précédent  index  suivant

15. Styles


15.1 Comment bien programmer en C ?

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.

15.2 Comment indenter proprement du code ?

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.

15.3 Quel est le meilleur style de programmation ?

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.

15.4 Qu'est-ce que la notation hongroise ?

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.

15.5 Pourquoi certains écrivent-ils 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())) {
		/* ... */
	}
		

15.6 Pourquoi faut-il mettre les '{' 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.

15.7 Pourquoi certains disent-ils de ne jamais utiliser les 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.

15.8 Pourquoi commenter un #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 */
		

15.9 Où trouver de la doc sur les différents styles ?

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.

15.10 Comment bien structurer son programme ?

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.


précédent  index  suivant