Organisation du Projet

Portrait de marseillais

un bon projet, c'est quoi?

* Un projet qui marche (normal)
* Un projet qui est débuggué (ah ben oui, quand meme)
* Un projet qui est débuggable (ne vous faites pas d'illusion il reste toujours des bugs)
* Un projet dont le code peut être compris par quelqu'un d'autre que le concepteur (et c'est la que ca se corse...)

Mais que faire?

Alors comment faire pour qu'un projet satisfasse ces exigences?
* Réfléchir avant de coder, et tester ses résultats
* Ecrire des tests pour l'utilisation du projet, et pas pour le code du projet (la nuance est de taille...): par exemple, on peut écrire les tests avant d'écrire le code du projet afin d'être sur de ne pas être influencé par la façon dont le code a été fait.
* Utiliser des outils de monitoring pour vérifier les fuites de mémoires, etc
* Et bien sur, écrire du code propre, et le ranger correctement.

A titre d'exemple, les projets de plusieurs milliers de lignes de code de C sont légions. Imaginez un fichier de 10000 lignes de code: déjà c'est très lourd à utiliser et ensuite, pour comprendre le code, ca se corse: si le main est tout en bas, et la fonction qu'on veut voir tout en haut....

Il est donc très rapidement nécessaire de séparer son code en morceaux.

Séparer son code

''' Les Headers '''

Déjà il faut séparer les déclarations globales du reste du code: ces déclarations globales sont:
* Les macros
* Les constantes
* Les déclarations de fonctions
* Les déclaration de types (struct, enum, typedef ...)
* Les déclaration de variables globales (beurk!)

Il existe un type de fichier particulier pour accueillir ces déclarations: les fichiers "headers", dont l'extension est ".h" (ca doit vous rappeler des choses)

Donc pour chaque fichier .c, il faut un fichier .h qui contienne la déclaration des fonctions, des macros, des constantes, etc qui y sont utilisées.

Petit rappel...

Ca c'est une '''déclaration''':

 void fonction(int arg1, char arg2);

Ca c'est une '''définition''':

 void fonction(int arg1, char arg2) {
     int i;
     for(i=0; i<arg1; i++)
         printf("%c\n", arg2);
 }

On parle bien ici des déclarations, et pas des définitions. Ca ne compilera pas si vous avez vos définitions dans vos headers. En effet vos headers risquent d'être inclus par plusieurs fichiers c, et donc à chaque fois les fonctions redéfinies...

''' Utiliser plusieurs fichiers '''

Il est aussi bon de séparer son code en blocs logiques: par exemple, un fichier s'occupera des fonctions d'affichage, pendant qu'un autre s'occupera de l'interface avec le système, pendant qu'un autre contiendra les algorithmes de calcul.
Attention! il ne faut pas se tromper d'objectifs: on fait ca pour pouvoir facilement retrouver le bout de code qui nous intéresse: pas pour avoir des petits fichiers!! Ca ne sert à rien d'avoir "fichier1.c fichier2.c fichier3.c" et des contenus tous liés entre eux: au contraire, ca risque d'être encore moins clair qu'un seul gros fichier.
C'est quand on utilise plusieurs fichiers que les headers deviennent important: en effet, peut etre que les fonctions du fichier d'algorithmes se serviront de l'affichage ou de l'interface systeme: il faut donc qu'ils connaissent les déclarations de ces fonctions: il faudra donc include les headers des fichiers d'affichage et systeme dans le fichier C des algorithmes...

Votre projet commence à ressembler à quelque chose

''' Ecrire des tests '''

Tester le programme à la main, c'est bien, mais pas efficace quand le programme devient complexe: on ne peut pas imaginer tous les cas et les taper à la main. En conséquence de quoi il est utile d'écrire des scripts de tests, qui appeleront par exemple 1000 fois le binaire avec des arguments différents et qui renverront des erreurs si le programme bug ou renvoie des résultats incohérents.
Un script de test bien fait, c'est tout un tas de mauvaises surprises en moins lors de la correction ou de la démo du projet :)

On a parlé des headers, des définitions, déclarations, etc. Il y a des outils pour optimiser la compilation de toutes ces choses: c'est ce qu'on verra dans la troisième partie du cours, [[C Avancé]].