if(0==x)
et non if(x==0)
?{
' et '}
' autour des boucles ?goto
?#endif
?La chose la plus importante est de commenter un programme. Il ne s'agit pas de décrire en français tout ce que fait chaque ligne de code, mais de préciser le fonctionnement des opérations complexes, d'expliquer le rôle des variables, de dire à quoi servent les fonctions. Choisir des noms de variables et de fonctions explicites est une bonne façon de commenter un programme.
Tout morceau de code qui n'est pas standard doit être abondamment commenté afin de rendre le portage vers d'autres cibles le moins fastidieux possible, l'idéal étant d'utiliser des macros.
Il est également important de bien structurer son programme en modules, puis en fonctions. Certains vont jusqu'à dire qu'une fonction ne doit pas dépasser la taille d'un écran.
Les déclarations et prototypes doivent être regroupés dans des fichiers d'en-têtes, avec les macros.
Enfin, il est très important de bien présenter le code, avec une indentation judicieuse et des sauts de ligne. (cf. 15.2) Il est généralement admis que les lignes ne doivent pas dépasser 80 caractères.
Pour le reste, c'est une histoire de goût.
L'indentation du code est une chose essentielle pour la lisibilité. Certaines personnes utilisent des tabulations, ce qui est une mauvaise habitude. La largeur de ces tabulations varie d'un éditeur à un autre. Des éditeurs remplacent les tabulation par un nombre d'espaces fixe et d'autres encore utilisent des tabulations de taille variable. Ne parlons pas des imprimantes ou des lecteurs de news... Tout ceci rend l'utilisation des tabulations difficile.
Pour éviter tout problème, et améliorer la lisibilité du code,
il faut utiliser uniquement des espaces.
Un éditeur correct doit pouvoir générer un nombre d'espaces fixe
(voire une indentation automatique) lorsqu'on appuye sur la touche
<TAB>
(ou autre raccourci).
Personnellement, je règle à 4 espaces par tabulation.
Comme vous vous en doutez, il n'y en a pas. Le plus important est d'en avoir un, et de le suivre. Quand on utilise un type d'indentation ou un style de nommage, il faut l'utiliser dans tout le programme (voire dans tout ses programmes). C'est la régularité qui donne la lisibilité.
Il existe des styles de programmations fréquemment utilisés en C, comme les styles K&R ou GNU. Le style K&R est le style « historique », et c'est pourquoi il est très utilisé. Le style GNU est utilisé pour tous les projets de la Free Software Fundation.
Sur le site FTP caramba.cs.tu-berlin.de, le repertoire /pub/doc/style contient quelques documents intéressants sur la question.
C'est une convention de nommage des objets, inventée par Charles
Simonyi. Le principe est de faire précéder le nom des
variables par un identificateur de type.
Par exemple, une chaîne de caractère représentant un nom sera
nommée szname
, sz
signifiant « string
zero », ou chaîne terminée par un '\0'
.
Personnellement, je ne trouve pas cette convention toujours pratique. Le nom de la variable doit avant tout refléter son rôle.
if(0==x)
et non if(x==0)
?Il arrive souvent que l'on écrive =
au lieu de
==
. Comme 0
n'est pas une lvalue
(cf. 10.10), cette étourderie
provoquera une erreur, simple à détecter.
Dans le même genre, on peut écrire while (0 == x)
.
Certains compilateurs préviennent lorsque l'on fait une affectation là ou est attendu un test. C'est le cas de GNU CC, avec l'option -Wall.
Lorsque l'on écrit while ( c = fct() )
, certains
compilateurs râlent en croyant que l'on s'est trompé entre le
=
et le ==
. Pour éviter cela, il suffit de
rajouter un paire de parenthèses.
while ((c = fct())) { /* ... */ }
{
' et '}
' autour des boucles ?C'est une précaution contre les erreurs du genre :
for (i = 0; i < N; i++); tab[i] = i;
De plus, cela permet une plus grande simplicité dans l'évolution du code. En effet, les programmes ont tendance à s'épaissir avec le temps.
goto
?Le goto
est une instruction qui permet de casser l'aspect
structuré d'un programme. Des goto
mal utilisés
permettent de rendre un code totalement illisible (code
spaghetti), d'autant plus qu'avec les structures de
boucles traditionnelles, on peut souvent s'en passer.
Toutefois, il arrive parfois que l'utilisation d'un goto
rende le code plus propre. C'est le cas, par exemple, des sorties
de boucles imbriquées en cas d'erreur.
Cela rejoint le cas plus général des gestions d'exceptions
internes.
Poser comme règle de ne jamais utiliser les
goto
est une absurdité.
Par contre, avertir le programmeur de l'utiliser avec parcimonie,
et avec beaucoup de précautions me semble une bonne chose.
#endif
?#endif
ne peut être suivi par autre chose qu'un
commentaire. On commente donc
pour savoir à quelle directive il correspond :
#if FOO /* du code ou des directives */ #ifdef BAR /* encore du code ou des directives */ #endif /* BAR */ /* encore du code ou des directives */ #endif /* FOO */
Le document suivant contient des règles de base à suivre pour programmer proprement : ftp.laas.fr/pub/ii/matthieu/c-superflu/c-superflu.pdf
Sachez également qu'il existe un programme indent
issu de BSD qui réindente automatiquement du code,
suivant un style donné. Les options classiques de la version
GNU de cet utilitaire sont -kr
(pour le
style décrit dans K&R), -gnu
(pour le
style utilisé dans les projets GNU) ou encore
-orig
(pour le style BSD).
Sous Unix, on trouve également la commande
cb avec l'option -sj
pour avoir le style
K&R.
Il n'y a pas de réponse définitive, mais voici une piste :
Evidement, tout ça est peu théorique. De plus, il existes des techniques avancées (ADT, callback) qui permettent les appels croisés propres. (c à d sans dépendances croisées). L'avantage est que chaque module est testable individuellement (et le plus souvent réutilisable).
La phase suivante du développement est l'intégration. Elle consiste à mettre la colle qui va bien pour faire tenir tout les modules ensembles et à tester le fonctionnement de l'ensemble.
Nous ne traitons pas ici des différentes méthodes d'analyse et de conception. Rappelons toutefois les 5 phases (en 'V') de développement d'un projet :
1 - Spécification 5 - Validation \ / 2 - Conception 4 - Integration \ / 3 - Codage et test unitaire
Voir à ce sujet les questions 9.3 et 13.5.
Merci à Emmanuel Delahaye pour cette réponse.