Unixtopia
main/ artigos/
Estilo de programação SMR ou formatação de código
Na maioria dos casos, uma linguagem de programação permite que o programador escolha o estilo estético no qual escrever o código, assim como um escritor pode formatar seu texto de maneiras visualmente diferentes sem alterar o significado dele, tem-se a opção de nomear variáveis, recuar e alinhar comandos, inserir comentários e assim por diante. Isso dá origem a vários estilos, um programador terá seu próprio estilo preferido, como uma caligrafia, mas uma vez que ele trabalha em uma equipe, algum compromisso tem que ser encontrado ao qual todos devem se conformar para manter o código agradável, consistente e legível por todos. Alguns projetos, como Linux, desenvolveram estilos bons, testados e de fato padronizados, em vez de inventar um estilo personalizado, o que pode não ser tão fácil quanto parece, pode-se escolher adotar alguns dos estilos existentes. Embora isso seja mais uma parte superficial da programação, ainda é muito importante e pensar sobre isso pode ser muito profundo, não deve ser subestimado. Existem formatadores automáticos de código, eles são frequentemente chamados de embelezadores de código. Mas nem tudo pode ser automatizado, um programa dificilmente comentará seu código, ou inserir espaços vazios para separar partes logicamente relacionadas de um código sequencial também é algo para o qual é necessária inteligência humana.
Estilo de programação e formatação SMR C recomendado
Propomos um estilo de programação e formatação de código C que pode usar em seus programas. É um estilo que eu pessoalmente adotei e ajustei ao longo de muitos anos de minha programação. Lembre-se de que nada é definitivo, exceto que você não deve usar tabulações, o mais importante geralmente é ser consistente em um único projeto e realmente pensar sobre o porquê de você estar fazendo as coisas do jeito que está fazendo. Manter o padrão definido aqui lhe dará vantagens como maior legibilidade para outros já familiarizados com o mesmo estilo e evitar cair em armadilhas definidas por decisões míopes em relação a identificadores. Tente pensar do ponto de vista de um programador que obtém apenas seu source-code sem nenhuma maneira de se comunicar com você, torne a vida dele o mais fácil possível. Suponha também que ele esteja lendo seu código em uma calculadora.
- Respeite princípios de design SMR, KISS, sem OOP, evite dependências como stdlib.
- Use dois espaços para recuo, nunca use tabulações. Por quê? Tabulações são feias, complicadas, caracteres de comportamento não padronizados, o comportamento depende do editor e das configurações, alguns processadores convertem tabulações e espaços silenciosamente, copiar e colar também pode fazer isso, elas não são transferidas para algumas plataformas, especialmente papel, algumas plataformas muito simples podem nem mesmo suportá-las, sua fonte conterá espaços de qualquer maneira, não há necessidade de inserir um caractere em branco adicional.
- Limite a largura a 80 Col. Se a linha for um único comando, como chamada de função ou expressão, isso seria muito longo, apenas quebre-a em algum lugar antes do limite e coloque o resto na próxima linha, possivelmente recuando as linhas abaixo um nível mais adiante. Tenha em mente que a fonte pode ser editada em computadores com telas pequenas, como thinkpads antigos, com uma tela dividida verticalmente em duas ou mais colunas.
- Escreva chaves de abertura e fechamento em suas próprias linhas, nas mesmas colunas.
if (a == b)
{
doSomething();
doSomething2();
}
else
{
doSomethingElse();
doSomethingElse2();
}
- Omita chaves se puder, como com um único comando no bloco. Escreva-as onde não fazê-lo provavelmente causará confusão ou erros de sintaxe.
- Use colchetes normais para tornar a precedência e a intenção mais claras, mesmo desnecessariamente, não flexione escrevendo uma expressão com precedência confusa que economize 4 caracteres de texto. Pode ser melhor escrever a && b) | c em vez de a && b | c.
Identificadores e nomes:
- Use camelCase para variáveis e funções: variáveis globais e de grande escopo devem ter um nome bastante descritivo e autodocumentado, mesmo que longo, como countryAreaKMSquared, identificadores ou locais de escopo curto podem ser mais curtos dentro de uma única função, até mesmo apenas uma letra, como i dentro de um único loop.
- Use CapitalCamelCase para tipos de dados.
- Use ALL_CAPS_SNAKE_CASE para macros e constantes.
- É aconselhável que para seu projeto você crie um prefixo de namespace de três letras que virá na frente de seus identificadores globais. Como small3dlib usa o prefixo S3L. Se você escolher um prefixo XYZ_, adicione-o a todos os identificadores globais, isso evitará conflitos de nomes e ajudará na legibilidade ao escrever um renderizador, você exportará identificadores como XYZ_init, XYZ_draw, XYZ_setPixel, XYZ_Model3D. Não use o prefixo em variáveis locais, como dentro de funções ou loops.
- Prefixe identificadores globais privados com _, como _tmpPointerBackup, com o prefixo de namespace mencionado acima, ficará assim: _XYZ_tmpPointerBackup.
- Use espaços para tornar o código mais legível, como int x = 10 em vez de int x=10, escreva um espaço entre if e sua condição.
- Use verbos para funções, substantivos para variáveis e mantenha a consistência, uma função deve ser chamada getTimeMS enquanto uma variável será chamada timeMS. As funções devem ser formatadas assim:
void doSomethingCool(int a, int b, int c)
{
// ...
}
- Nome geral para específico, como getCountryTimezone e getCountryCapital em vez de getTimeZoneOfCountry, getCapitalOfCountry. Isso ajuda com sistemas de conclusão de código. Você também pode decidir usar countryGetTimezone, apenas mantenha consistência.
Switch sempre deve ter o rótulo padrão. As instruções podem ser formatadas:
switch (myVariable)
{
case 0:
doSomething();
break;
case 1:
doSomethingElse();
break;
case 2:
{
int a = x + y;
doSomethingCool(a);
break;
}
default:
break;
}
// ou mesmo, dependendo do tamanho das seções:
switch (myVariable2)
{
case 0: doSomething1(); break;
case 1: doSomething2(); break;
case 2: doSomething3(); break;
case 3: doSomething4(); break;
default: break;
}
- Para nomes de arquivo, sempre use apenas letras minúsculas, use camel_case.ext ou nocase.ext.
Use linhas em branco para agrupar logicamente linhas relevantes de código:
int a = x;
char b = y;
double q;
doSomething(a);
c += 3 * a;
d -= b;
if (c < d)
a = b;
- Cada arquivo deve ter um comentário global no topo com ao menos uma breve descrição do propósito do arquivo, isso quase sempre está ausente no mainstream, uma breve documentação, licença, o(s) autor(es) e ano de criação.
- Use comentários para tornar seu código mais legível e pesquisável com coisas como grep, adicione palavras-chave a partes relevantes do código, como comment // player shoots para código implementandor de player shooting. Use comentários no estilo doxygen, não custa nada e permite documentação automática.
- TODOs e WIPs são bons.
- Não use enums, use #defines.
- Variáveis globais são ótimas, use-as. Funções longas são boas. Repetir-se também pode ser bom se for algo como 3 linhas de código e a alternativa for muito complexa, mas coisas como macros variádicas geralmente podem resolver até mesmo esses casos, sempre pense bem nesses casos.
- Siga o padrão C99 ou C89. É ideal se seu código for válido em ambos e talvez até mais padrões, e em C++ também.
- Tente não criar muitos arquivos de origem, muitas vezes seu projeto pode muito bem estar em um único arquivo, que é o caso ideal, isso fará com que ele seja compilado rápido, possivelmente seja ainda melhor otimizado, o compilador vê o código inteiro, e será fácil de compilar, é basicamente um cenário ganha-ganha-ganha-ganha-ganha-ganha. Crie bibliotecas somente de cabeçalho Se você tiver vários arquivos, mantenha-os no mesmo diretório e tente ter apenas uma única unidade de compilação, penas um arquivo .c com vários arquivos .h, tente fazer arquivos com no máximo 10 mil linhas.
- Use sistema de numeração de versão SMR.
- Use apenas caracteres ASCII.
- Não dependa de nenhuma extensão do compilador. Para máxima portabilidade, minimize dependências, não confie em coisas como extensões GNU C, extensões POSIX, como _XOPEN_SOURCE. Você pode usá-las, mas sempre faça isso de uma forma que facilite a eliminação delas, não use macros como PATH_MAX diretamente, sempre defina sua própria macro, como #define MYLIB_PATH_MAX PATH_MAX e use somente isso, dessa forma você pode facilmente alternar para um limite codificado se a macro não estiver disponível em algum sistema. Da mesma forma com qualquer outra coisa: se seu programa estiver usando um recurso específico para um compilador, sistema operacional, algum padrão extra de terceiros e assim por diante, sempre ofereça uma maneira fácil de desabilitá-lo ou substituí-lo, o pré-processador é muito bom para isso.