Você está na página 1de 5

Programando em C: Boas Prticas

por Roberto Alcntara - ltima modificao 26/05/2008 17:51 Este artigo aborda algumas dicas que visam melhorar a legibilidade do cdigo fonte. Em 1972 o funcionrio da AT&T Dennis Ritchie iniciou o desenvolvimento de uma linguagem de programao que simplificasse a sua tarefa diria de programador nos laboratrios Bell. Chamou-a simplesmente de "C", em referncia clara uma linguagem anterior, escrita por Ken Thompson, conhecida como "B". Aps estar madura o suficiente para substituir o assembly no kernel do sistema Unix em 1973, a linguagem ganhou o mundo, evoluindo com o tempo e tornando-se referncia, mas sem perder as principais caractersticas que a fizeram ocupar uma posio de destaque. Este artigo pretende conversar diretamente com o programador, revelando algumas boas prticas que podem auxili-los no desenvolvimento e manuteno do cdigo. Apesar de genrico linguagem C, os tpicos abordados so frutos da experincia como desenvolvedor de sistemas embarcados, sendo estes o nosso foco principal.

Mantendo Bonito
A linguagem C, por definio, no exige que voc escreva o programa seguindo regras que o tornem esteticamente agradvel de ver (e ler). Nada impede voc de escrever algo como: /*#define ppp xp * /## define */#define x = #define zim void /*\**\*\***//*/ #denife $/*/ #define p () #define iu for( /*\**\*\***//*/ #defie $##def x^3printdf/*/ #define xyz < /*/* 8/ *******/ #define o ;} #define v "\na l o m u n d o " int s (zim) { char b x 1; iu b x 9;\ b xyz 21; b++){ printf( v ) o /*}}}*/} zim main( zim ) { s p o Exceto, claro, o bom senso. De uma maneira geral, o cdigo bonito e organizado sempre mais fcil de ler.

Identao & Espaos


Utilizar a identao no cdigo algo essencial para a legibilidade. O tamanho do espaamento pode variar, mas o importante sempre manter blocos aninhados

respeitando os nveis de identao das estruturas condicionais e laos de repetio. De uma forma geral, o nvel de identao muda sempre aps o incio de uma funo, estrutura condicional ou lao: void exemplo ( void ) { if ( a > 5 ) { b += 3; for ( i=0; i<5; i++ ) { z++; x--; } } } No exemplo acima foram utilizados quatro espaos entres os blocos. Voc pode configurar o seu editor de texto preferido para que a tecla TAB substitua o caracter invisvel de tabulao por estes espaos, bastante til. Evite espaamentos muito curtos, como apenas um espao, ou muito longos. Alm da identao, que voc j deve estar habituado, outro recurso que facilita a legibilidade a utilizao de espaos horizontais e verticais. Aumentar o nmero de linhas e espaos no vai, obviamente, aumentar o tamanho do binrio compilado. Ao invs de escrever uma sentena condicional como: if (a<20 &&(c==5||d==6)) { } prefira algo assim: if ( (a < 20) && ( (c==5) || (d==6) ) ) { } que visivelmente mais agradvel de avaliar. Separar as sentenas por parnteses tambm evita algum erro de precedncia que voc possa cometer ao digitar as expresses, reduzindo o tempo de depurao no futuro. Laos complexos tambm podem ser quebrados em vrias linhas, com o mesmo objetivo: for ( cont = 0, aux = 3; cont < 100; cont++, aux+=2 ) { a = c + b; d = e - f; } Quando falo em legibilidade do cdigo, lembro-me que existe um operador na linguagem C, o ternrio, que utilizado em excesso pode tornar as expresses pouco legveis aos olhos menos treinados. De uma forma geral eu evito utilizar o operador ternrio, mesmo em sentenas simples. A operao

aux = ( cont < aux ) ? cont : cont * -1; poderia ser escrita, sem nenhum prejuzo, como: if ( cont < aux ) aux = cont; else aux = cont * -1; Mas se voc gosta do operador ternrio, uma opo para melhorar a legibilidade separar as sentenas por linhas identadas. A mesma expresso poderia ser escrita assim: aux = ( cont < aux ) ? cont : cont * -1; Isto ser especialmente til caso voc utilize o operador ternrio de forma encadeada. Este cdigo: a=(b<z) ?x :(i>x) ?i : ++i; certamente mais legvel que este: a = ( b < z ) ? x : ( i > x ) ? i : ++i;

- ++ e -Evite agregar mais de um ++ ou -- na mesma sentena. Com o mesmo intuito, evite atribuir ao resultado da operao operadores que utilizaram o incremento ou decremento na expresso. Portando, expresses como: z = a++ + ++b; ou a[b] = b++; devem ser evitadas e substituidas por clusulas que inibam, ou pelo menos minimizem, interpretaes errneas.

Nmeros Mgicos

As constantes so suas amigas, e os "#define" uma das mais ricas formas de melhorar a legibilidade do cdigo. "Nmeros Mgicos" so valores, inteiros ou no, que aparecem no cdigo e que so constantes, mas no foram declarados como tais. Fazer isso prejudica a organizao e dificulta a manuteno. Ao invs de ter condies como: while ( tensao_bateria < 30 ) { if ( potencia_transmissor > 50 ) diminua_potencia(); else { desliga_radio(); while ( tensao_bateria < 30 ) { /* espera bateria carregar */ } liga_radio(); } } substitua os inteiros por constantes com nomes adequados, como LIMITE_BATERIA_CRITICA e POTENCIA_MINIMA_TRANSMISSOR. Alm de melhorar a organizao facilita a manuteno, em caso de alteraes nestas constantes.

Loops "Parados"
Utilizando o exemplo anterior, observe que escrevemos while ( tensao_bateria < 30 ) { /* espera bateria carregar */ } ao invs de simplesmente while ( tensao_bateria < 30 ); A primeira forma deixa explcita a nossa inteno, ao contrrio da segunda, que poderia ser confundida com um erro do programador ou causar problemas posteriormente, caso o ";" fosse erroneamente removido (possivelmente sem erro na compilao).

Convenes
No importa exatamente quais convenes voc utiliza, o importante que voc defina uma (prpria ou no) e siga-a da forma mais rigorosa possvel. Preferencialmente estas convenes devem ser descritas em um documento simples, que permita consultas rpidas sempre que necessrio. Exemplificarei algumas abaixo que so bastante populares, mas voc deve adapt-las s suas necessidades. - Constantes: para as constantes utilize sempre letras maisculas. Desta forma ser fcil distingui-la entre as variveis. Ex.: #define LIMITE_TEMPERATURA 40 #define BATERIA_BAIXA 30

- Variveis: mais importante que as convenes, uma regra bsica: utilize nomes claros para as variveis, abreviando apenas o que bastante conhecido ou bvio. Programadores so, em sua maioria, geis no teclado. Portanto, abreviar pressaoMotorEsquerdo para preMotE provavemente no vai economizar muito do seu tempo durante o desenvolvimento e certamente dificultar a leitura do cdigo. Existem algumas convenes mais antigas como a Notao Hngara ou mais modernas, como a Notao Camelo, muito utilizada na programao orientada a objetos. Usualmente, em C, bastante comum todas as variveis serem escritas com letras minsculas e/ou com o "_" como separador de palavras. Sendo assim, variveis como velocidademaxima ou velocidade_maxima so bastante comuns, sendo esta ltima forma mais freqente. - Tipos de Variveis: uma das grandes vantagens da linguagem C a portabilidade entre arquiteturas. No entanto, alguns tipos de variveis possuem comprimento varivel dependendo da arquitetura e compilador, o que pode ocasionar problemas no software, como overflow ou erros de converses. Por exemplo, o tipo inteiro (int) normalmente representa o tamanho da palavra do processador, nos processadores modernos de 32 e 64 bit e compiladores como o GCC. Mas isso no necessariamente uma regra; no compilador HITECH para microcontroladores PIC de 8 bit, por exemplo, o inteiro possui 16 bit. Sendo assim, defina tipos claros e utilize-os, como uint8 para inteiros no sinalizados de 8 bit ou int16 para inteiros sinalizados de 16 bit. Tambm seja atencioso ao declarar ponteiros. Uma declarao como: char* s, t, u; no est errada, mas provavelmente no o que voc deseja, j que t e u no sero declarados como ponteiros. Sendo assim, prefira esta forma para declarar os ponteiros sem margem para erros: char *s, *t, *u;

Concluso
Nossa inteno neste artigo foi abordar algumas tcnicas que podem ajud-lo a melhorar a legibilidade do seu cdigo. Apesar de existirem vrios outros pontos que podem ser abordados neste tpico, de uma forma geral, escrevendo um cdigo organizado, bonito e bem comentado existe uma grande probabilidade do seu cdigo tornar-se bastante legvel, quesito que traduz-se em agilidade e produtividade em todas as fases do ciclo de vida do software.