Convenções de nomenclatura usadas para variáveis e funções em C [fechado]

Fechado. Esta questão está fora do tópico . Atualmente não está aceitando respostas.

Comentários

  • Cite alguns exemplos de idiomas com convenções de nomenclatura sugeridas. E onde podemos encontrar essas convenções de nomenclatura.
  • @Philip Exemplos adicionados
  • Não deve haver ' um problema com variáveis que você não ' para usar globais. E para nomes de função: se o nome do módulo ' s for order.c, você poderia nomear as funções order_add(), order_del() e outros semelhantes. Pode haver sistemas antigos que informam que o nome deve ser exclusivo nos primeiros 8 caracteres. Quando você mudar para c ++ mais tarde por acidente, você ' adorará escrever order::add() e order::del() então.

Resposta

Se eu continuar escrevendo mais código, então chegará um momento em que será difícil para mim organizá-lo.

Este é o seu problema: faça a organização certa, e o estilo deve fluir mais facilmente.

Não espere para organizar seu código: mantenha seu código organizado enquanto avança. Embora a linguagem não faça isso por você, o código ainda deve ser organizado em módulos com baixo acoplamento e alta coesão.

Esses módulos fornecem naturalmente um namespace. Abrevie o nome do módulo (se for longo) e prefixe os nomes das funções com seus módulos para evitar colisões.

No nível dos identificadores individuais, eles estão aproximadamente em ordem crescente de subjetividade:

  1. escolha uma convenção e mantenha-a
    • por exemplo, function_like_this(struct TypeLikeThis variable) é comum
  2. definitivamente evite a notação húngara (desculpe JNL)

    • a menos que você esteja disposto a usá-la conforme pretendido originalmente, o que significa a notação apps de Simonyi em vez de a terrível versão do sistema

      Por quê? Eu poderia escrever um ensaio sobre isso, mas, em vez disso, sugiro que você leia este artigo de Joel Spolsky, e então procure mais alguns se estiver interessado. Há um link para o artigo original de Simonyi na parte inferior.

  3. evite typedefs de ponteiro, a menos que sejam tipos de cookies genuinamente opacos – eles apenas confundir as coisas

    struct Type *ok; typedef struct Type *TypePtr; TypePtr yuck; 

    O que quero dizer com um tipo de cookie opaco ? Quero dizer algo usado dentro de um módulo (ou biblioteca, ou qualquer) que deve ser passado para o código do cliente, mas esse código do cliente não pode ser usado diretamente. Ele apenas o passa de volta para a biblioteca.

    Por exemplo, uma biblioteca de banco de dados pode expor uma interface como

    /* Lots of buffering, IPC and metadata magic held in here. No, you don"t get to look inside. */ struct DBContextT; /* In fact, you only ever get a pointer, so let"s give it a nice name */ typedef struct DBContexT *DBContext; DBContext db_allocate_context(/*maybe some optional flags?*/); void db_release_context(DBContext); int db_connect(DBContext, const char *connect); int db_disconnect(DBContext); int db_execute(DBContext, const char *sql); 

    Agora, o contexto é opaco para o código do cliente, porque você não pode olhar dentro. Basta passá-lo de volta para a biblioteca. Algo como FILE também é opaco e um descritor de arquivo inteiro também é um cookie , mas não é opaco.


Uma observação sobre design

Usei a frase baixo acoplamento e alta coesão acima sem explicação, e me sinto um pouco mal por isso. Você pode pesquisar e provavelmente encontrar alguns bons resultados, mas tentarei abordá-lo brevemente (novamente, eu poderia escrever um ensaio, mas tentarei não fazê-lo).

A biblioteca DB esboçada acima mostra baixo acoplamento porque expõe uma pequena interface para o mundo exterior. Ao ocultar seus detalhes de implementação (em parte com o truque do cookie opaco), evita que o código do cliente dependa desses detalhes.

Imagine em vez do cookie opaco, declaramos a estrutura de contexto para que seu conteúdo seja visível, e isso inclui um descritor de arquivo de soquete para uma conexão TCP com o banco de dados. Se posteriormente alterarmos a implementação para suportar o uso de um segmento de memória compartilhada quando o O banco de dados está sendo executado na mesma máquina, o cliente precisa ser recompilado em vez de apenas vinculado novamente. Pior ainda, o cliente poderia ter iniciado usando o descritor de arquivo, por exemplo, chamando setsockopt para alterar o tamanho do buffer padrão, e agora ele precisa de uma alteração de código também. ils deve ser escondido dentro de nosso módulo onde for prático, e isso dá baixo acoplamento entre módulos.

O exemplo também mostra alta coesão , em que todos os métodos no módulo estão preocupados com a mesma tarefa (acesso ao banco de dados). Isso significa que apenas o código que precisa de saber sobre os detalhes de implementação (ou seja, o conteúdo de nosso cookie) realmente tem acesso a eles, o que simplifica a depuração.

Você também pode ver que ter uma única preocupação facilitou a escolha de um prefixo para agrupar essas funções.

Agora, dizer que este exemplo é bom é fácil (especialmente porque não “nem mesmo completo), mas não o ajuda imediatamente. O truque é observar, enquanto você escreve e estende seu código, por funções que fazem coisas semelhantes ou operam nos mesmos tipos (que podem ser candidatas a seus próprios módulos), e também por funções que fazem muitas coisas separadas que não são ” são realmente relacionados e podem ser candidatos à divisão.

Comentários

  • Você pode me ajudar a entender por que o húngaro é evitado? Apenas curioso para saber mais sobre isso. 🙂
  • @JNL: Um comentário é muito curto para ser explicado corretamente. Sugiro que você o poste como uma nova pergunta.
  • with low coupling and high cohesion. O que isso significa? E explique sobre os tipos de cookies opacos. Não tenho ideia do que isso significa.
  • Tentei abordar ambos brevemente e, francamente, falhei na brevidade. Espero que você consiga entender começou.
  • Estou respondendo depois de alguns dias. Desculpe por isso. Li sua descrição de low coupling and high cohesion. Então, basicamente significa encapsular as coisas quando eu puder e deve ser feito de uma maneira que o funções que realmente precisam devem ter acesso. Algumas coisas passaram pela minha cabeça, mas ainda assim acho que entendi.

Resposta

Na minha opinião 90 % do problema de nomenclatura é resolvido se você tiver três coisas em mente: a) torne seus nomes de variáveis e funções tão descritivos quanto possível, b) seja consistente em todo o seu código (ou seja, se uma função é chamada addNumbers, uma segunda função deve ser chamada multiplyNumbers e não numbersMul) e c) tente tornar os nomes curtos, se possível, pois precisamos digitá-los.

Dito isso, se você quiser dar uma olhada em outros aspectos deste tópico, a página da Wikipedia em Convenções de nomenclatura tem uma boa lista de coisas que você deve tenha em mente. Ele também tem uma seção em C e C ++:

Em C e C ++, palavras-chave e identificadores de biblioteca padrão são em sua maioria minúsculos. Na biblioteca padrão C, os nomes abreviados são os mais comuns (por exemplo, isalnum para uma função que testa se um caractere é alfanumérico), enquanto a biblioteca padrão C ++ geralmente usa um sublinhado como separador de palavras (por exemplo, out_of_range). Os identificadores que representam macros são, por convenção, escritos usando apenas letras maiúsculas e sublinhados (isso está relacionado à convenção em muitas linguagens de programação de usar todos os identificadores em maiúsculas para constantes). Nomes contendo sublinhado duplo ou começando com um sublinhado e uma letra maiúscula são reservados para implementação (compilador, biblioteca padrão) e não devem ser usados (por exemplo, reservados__ ou _Reservados). [5] [6] Isso é superficialmente semelhante a stropping, mas a semântica difere: os sublinhados são parte do valor do identificador, em vez de serem caracteres de citação (como está stropping): o valor de __foo é __foo (que é reservado), não foo (mas em um namespace diferente).

Comentários

  • " tente tornar os nomes curtos, se possível " Use um IDE com preenchimento automático, então seus nomes de função podem ser tão longos e descritivos quanto precisam ser, conforme você só precisa para digitar uma vez.
  • @Joel conselho terrível. Nem todo mundo usará o mesmo IDE que você.
  • @James Eles não ' precisam, eles podem usar qualquer IDE decente. Então você não ' não precisa sacrificar a clareza pela produtividade.
  • O termo IDE é um pouco esticado hoje em dia. Tecnicamente, o Notepad ++ é um IDE porque você pode configurá-lo para compilar e executar seu projeto, mas ' é principalmente um editor de texto. E ele se completa automaticamente.

Resposta

A única restrição rígida em C é que não há namespaces. Portanto, você deve encontrar uma maneira de tornar a função rename() de sua biblioteca do sistema de arquivos distinta da rename() função de sua biblioteca de mídia . A solução usual é um prefixo, como: filesystem_rename() e media_rename().

O outro conselho geral é: fique consistente dentro de um projeto ou equipe. A legibilidade será aprimorada.

Comentários

  • +1: Isso é especialmente verdadeiro para símbolos exportados em uma biblioteca. " Lamento, mas essa biblioteca do sistema de arquivos não acompanha essa biblioteca de mídia, porque ambas têm uma função de renomeação exportada.

Resposta

SE VOCÊ ESTÁ PROCURANDO UM GLOBALMENTE FORMATO ACEITO

MISRA / JSF / AUTOSAR cobre quase 100% de todo e qualquer padrão da indústria para nomear e organizar código C / C ++. O problema é que eles não serão de graça, ou seja, cada um dos guias custa algum dinheiro. Eu sei que o livro padrão de codificação MISRA 2008 C / C ++ provavelmente custa cerca de 50 dólares.

Você pode pensar nisso como a Harvard Referencing para bibliografia e leitura adicional quando você escreve um diário. Eu usei MISRA e é uma boa maneira de nomear suas funções e variáveis e organizá-las para uso adequado.

SE VOCÊ ESTÁ PROCURANDO ALGO TEMPORÁRIO

As referências que você forneceu para Python e Java estão ok, eu acho. Já vi pessoas adotando o estilo javadoc de comentar, nomear e organizar código. Na verdade, em meu último projeto, tive que escrever código C ++ em nomes de funções / variáveis semelhantes a Java. Duas razões por trás disso:

1) Era aparentemente mais fácil de seguir.

2) Os requisitos do código de produção não tocavam no terreno dos padrões de sistema de software de segurança crítica.

3) O código legado estava (de alguma forma) nesse formato.

4) O Doxygen permitia comentários no sistema Javadoc. Naquele momento, estávamos usando doxygen para gerar documentação para os caras de produção.

Muitos programadores serão oponentes disso, mas eu pessoalmente acho que não há nada de errado em adotar a nomenclatura de função / variável do estilo javadoc em C / C ++. SIM, CLARO, as práticas de organização de seu controle de fluxo, segurança de thread etc. No entanto, não sou um candidato aqui. Eu também não sei quão rigorosos são os seus requisitos de formato de código de produção. Sem desviá-lo para uma área fora do tópico, sugiro que você reveja seus requisitos, descubra como você depende de uma convenção de nomenclatura específica e vá com uma solução mencionada nas minhas e em outras “respostas

Espero que tenha ajudado !?

Comentários

  • Na verdade, eu estava pedindo códigos C pessoais . Mas eu ' lembrarei sua sugestão.
  • @AseemBansal Pessoal ou profissional, são bons para aprender e também para colocar no currículo 🙂 … . Depende de você.

Resposta

Poucas coisas importantes a serem consideradas ao nomear seriam;

  1. Observe o tipo actionObject ou ObjectAction. (Objeto não para C. Mas, em geral, quando você vai para outras linguagens orientadas a objetos) Isso deve ajudar

  2. O descanso seria SER CONSISTENTE, curto e descritivo, com certeza.

  3. Além disso, um único propósito de cada variável e função definida, Ex: se for para armazenar um valor temporariamente, nomeie-o como nTempVal para int
  4. Variáveis devem ser substantivos e Métodos devem ser verbo.

Comentários

  • notação húngara (prefixar uma variável com letras que denotam o tipo) leva a uma dor infinita. Felizmente, quase saiu de moda.
  • @StevenBurnap Estava apenas curioso para saber por que o formato húngaro é evitado? Eu acredito que ' é o que eles nos ensinaram na escola e eu vi esse código em alguns locais de trabalho também. Qual você recomendaria se não fosse o húngaro. Obrigado
  • A melhor convenção de nomenclatura é apenas aquela usada consistentemente, com nomes claros e descritivos, idealmente mantidos relativamente curtos, sem abreviações excessivas e evitando prefixos redundantes. A notação húngara tem pouca utilidade real, torna o código mais difícil de ler e torna mais difícil alterar os tipos.
  • Aqui está uma descrição da intenção original e a abominação em que a notação húngara se tornou: joelonsoftware.com/articles/Wrong.html
  • @Residuum Esse era um bom link. Ajudou muito. Agradeço.

Resposta

A maioria das respostas são boas, mas quero dizer algumas coisas sobre nomenclatura convenções para bibliotecas e arquivos incluídos, semelhantes ao uso de namespaces em outras linguagens como C ++ ou Java:

Se você construir uma biblioteca, encontre um prefixo comum para seus símbolos exportados, ou seja, funções globais, typedefs e variáveis. Isso evitará conflitos com outras bibliotecas e identificará as funções como provenientes das suas. Este é um pouco de aplicativos de notações húngaras.

Talvez vá ainda mais longe e agrupe seus símbolos exportados: libcurl usa curl_ * para símbolos globais, curl_easy_ *, curl_multi_ * e curl_share_ * para as diferentes interfaces.Portanto, além de usar curl_ * para todas as funções, eles adicionaram outro nível de “namespaces” para as diferentes interfaces: chamar uma função curl_easy_ * em um identificador curl_multi_ * agora parece errado, consulte os nomes das funções em http://curl.haxx.se/libcurl/c/

Mantendo as regras para símbolos exportados, você deve usá-las para funções estáticas em #include arquivos ed: tente encontrar um prefixo comum para essas funções. Talvez você tenha funções de utilitário de string estática em um arquivo chamado “my_string”? Prefixe todas essas funções com my_string_ *.

Comentários

  • Por símbolos exportados você quer dizer variáveis globais, funções, typedefs etc. se eu estiver correto. Você pode explicar um pouco sobre o agrupamento dos símbolos exportados? Achei que você já tivesse explicado isso no parágrafo anterior. O que você adicionou no terceiro parágrafo?

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *