Les conseils suivants rendent les logiciels plus maintenables.
Leur respect a pour but de :
Cartouche d'entête (c_lis_1).
Chaque fichier source (.c, .h) et chaque fonction C doivent être précédés d’un cartouche qui pourra contenir : 
Justification.
Le cartouche de l’unité permet de faciliter sa compréhension d'un point de vue général. Les cartouches de fonctions permettent de comprendre leur rôle et conditions d'appel sans se plonger dans le code source . Ces entêtes sont indispensables à la gestion de la configuration et à la maintenance.
Exemple.
/*******************************************************
Nom ... : limites.c
Role ... : Affiche les caractéristiques numériques
 pour les types du langage C
Auteur ... : Thierry46
Version ... : V1.1 du 10/3/2008
Licence ... : GPL
Compilation :
gcc -Wall -pedantic -std=c99 -o limites.exe limites.c
Pour exécuter, tapez : ./limites.exe
Indentation des instructions (c_lis_2).
Les instructions imbriquées sont indentées à l’aide de tabulations ou d'espaces de façon homogène dans tous les fichiers sources du projet.
Justification.
La maintenance et la relecture des sources sont facilités par une présentation homogène.
Exemple (extrait).
 // Teste si les valeurs lues sont les valeurs attendues.
 for (i=0; i<(int)nbInt; i++)
 (void)printf("%d, ", valIntLu[i]);
 if ( valIntLu[i] != valInt[i] )
 (void)printf("Au lieu de %d\n", valInt[i]);
 exit(EXIT_FAILURE);
Indentation des commentaires (c_lis_3).
Les commentaires suivent l’indentation des instructions de code. 
Justification.
Augmente la lisibilité.
Une instruction par ligne (c_lis_4).
Ne pas écrire plus d'une instruction par ligne.
Justification.
Augmente la lisibilité.
Décomposer les instructions longues (c_lis_5).
Coder des lignes simples.
Justification.
Il est quelquefois tentant de coder des lignes longues :
Le code parait, à première vue, plus compact, plus efficace. Il faut cependant décomposer les lignes longues en plusieurs, en utilisant des variables intermédiaires. Les compilateurs récents se chargeront d'optimiser efficacement le code pour vous. Le résultat sera plus facile à comprendre par d'autres. Les problèmes de priorité pourraient être atténués.
Constantes symboliques et macros en majuscule (c_lis_6).
Les noms des constantes symboliques et des macros instructions doivent être écrits en majuscule.
Justification.
Dans un fichier source, permet des distinguer rapidement les constantes des variables.
Pas de lignes trop longues (c_lis_7).
Les instructions ne doivent pas dépasser la colonne 80. Les instructions longues doivent être placées sur plusieurs lignes.
Justification.
Les lignes courtes seront plus faciles à comprendre par une personnes chargée de maintenir le logiciel.
Exemples.
Mauvais :
 (void)printf("\nProgramme %s, fichier source "__FILE__"\nCompile le "__DATE__" a "__TIME__"\n", argv[0]);
Meilleur :
 int n; \
 for (n=N; n>0; n--) fputc(0x7, stderr); \
//...
 (void)printf("\nProgramme %s, fichier source "__FILE__
 "\nCompile le "__DATE__" a "__TIME__"\n",
 argv[0]);
Nommage des identificateurs (c_lis_8).
Vous devez donner des noms significatifs aux identificateurs.
Justification.
Facilite la lisibilité et la maintenabilité.
Cohérence des identificateurs (c_lis_9).
Dès lors qu’un identificateur de variable est défini pour une entité significative, il faut utiliser ce même identificateur quelle que soit l’unité de code considérée.
Justification.
Facilite l'analyse du programme.
Arguments du programme principal (c_lis_10).
Les arguments du programme principal sont standards : codice_1
Justification.
Améliore la lisibilité du code. argv[0] représente le nom de lancement du programme et peut être utilisé pour les messages d'erreur. La récupération des arguments du programme pourra se faire avec les fonctions getopt(), getsubopt().
Limiter l'utilisation des opérateurs ++ et -- (c_lis_11).
Les opérateurs ++ et -- ne sont autorisés que pour les indices de boucles et les pointeurs, à condition qu’aucun autre opérateur n’apparaisse et que seule l’utilisation post-fixée soit utilisée.
Justification.
Facilite l’analyse et la maintenance par des programmeurs habitués à d’autres langages.
Limiter l'utilisation de l'opérateur de test ternaire (c_lis_12).
L’utilisation de l’expression conditionnelle ? : est interdite en dehors des macros.
Justification.
Facilite l’analyse et la maintenance par des programmeurs habitués à d’autres langages.
Ne pas économiser les accolades (c_lis_13).
Utilisez des accolades {} autour d'une ou des instructions d'un bloc. Ce bloc peut faire partie d’une structure de contrôle comme if - else - for - do - while.
Justification.
Rend le code plus lisible et évite les erreurs lors de l'ajout d'une instruction dans un bloc qui n'en contient qu'une seule.
Exemple.
Mauvais :
for (i=0; i<n; i++)
 table[i] = 1;
Meilleur :
for (i=0; i<n; i++)
 table[i] = 1;
Exemple d'erreur provoquée par la violation de ce conseil :
if (test == 2)
 for (i=0; i<n; i++)
 table[i] = 1;
 table2[i] = 2;
/* Suite... */
L'instruction codice_4 donne faussement l'impression de faire partie de la boucle for, ce qui est renforcé par l'indentation et l'accolade fermante du if.
Si table2 était dimensionné à n, les indices acceptables iraient de 0 à n-1 inclus. Lors de l'exécution de l'instruction codice_4, i vaudrait la valeur n, ce qui provoquerait l'écriture d'une valeur hors de l'espace mémoire réservé pour le tableau table2.
Il s'en suivra :
Bien aligner les accolades (c_lis_14).
Une accolade fermante se trouve toujours à la verticale de l’accolade ouvrante correspondante.
Justification.
Permet de mieux repérer les blocs d'instructions conditionnelles, les corps de boucles surtout en cas de structures imbriquées.
Exemple.
// Compilation : gcc -Wall -pedantic -std=c99 -o essai.exe essai.c
int main(void)
 const int nbLigne = 3;
 const int nbCol = 4;
 int table[nbLigne][nbCol];
 for(int ligne = 0; ligne < nbLigne; ligne++)
 for(int col = 0; col < nbCol; col++)
 table[ligne][col] = ligne + col;
 // Impression
 for(int ligne = 0; ligne < nbLigne; ligne++)
 for(int col = 0; col < nbCol; col++)
 (void)printf("table[%d][%d] = %d,",
 ligne, col, table[ligne][col]);
 (void)puts("");
 return EXIT_SUCCESS;
Éviter d'utiliser les opérateurs d'affectation spécifique au C (c_lis_15).
L’utilisation de l’assignation composée codice_6 et de l’affectation multiple codice_7 est déconseillée.
Justification.
Facilite l’analyse et la maintenance par des programmeurs habitués à d’autres langages.
Ne pas déclarer plusieurs variables dans la même instruction (c_lis_16).
Il faut déclarer chaque variable séparément et non les unes à la suite des autres, séparées par des virgules.
Justification.
La déclaration de plusieurs variables dans une même instruction peut provoquer des erreurs de type pour les variables.
Une déclaration séparée permet aussi de décrire dans un commentaire en bout de ligne le rôle de chaque variable.
Exemple.
// Declaration incorrecte :
// nomFicSortie est de type char au lieu de char * et ne peut donc être initialisé à NULL
char *nomFicEntree = NULL, nomFicSortie = NULL;
// Declaration correcte mais pas lisible
char *nomFicEntree = NULL, *nomFicSortie = NULL;
// Meilleur
char *nomFicEntree = NULL; // Fichier de parametres du calcul
char *nomFicSortie = NULL; // Fichier pour les points calculés
Seuils pour les métriques déterminant la facilité d'analyse (c_lis_17).
Les métriques suivantes influent sur la facilité d'analyse d'un programme (ISO/IEC 9126) :
Seuils pour les métriques :

Conseils de codage en C/Robustesse des programmes