Le langage C pas à pas livre de formation complet pour apprendre à programmer
…
Exemple pratique 1
Lecture au clavier et affichage à l’écran
Vous trouverez, dans ce livre, plusieurs sections de ce type présentant un programme un peu plus long que les exemples fournis dans les chapitres. Il pourra contenir des éléments qui n’auront pas encore été abordés, mais vous aurez ainsi la possibilité de saisir un programme complet puis de l’exécuter.
Les programmes présentés constitueront des applications pratiques ou amusantes. Le programme perroquet de cette section, par exemple, lit une ligne au clavier et l’affiche. Ce programme contient d’ailleurs une fonction qui sera utilisée tout au long de cet ouvrage : lire_clavier(). Vous devrez la recopier telle quelle dans chaque programme qui y fait appel.
Prenez le temps de tester ces programmes. Modifiez-les, recompilez, puis exécutez-les de nouveau. Observez les résultats ainsi obtenus. Nous n’expliquerons pas les détails de fonctionnement au niveau du code, seulement les opérations effectuées. Vous en comprendrez toutes les subtilités lorsque vous aurez parcouru tous les chapitres. Vous avez ainsi la possibilité d’aborder rapidement des programmes intéressants.
Le premier exemple pratique
Saisissez et compilez le programme suivant, en prenant soin de ne pas introduire de fautes de frappe (vous les retrouverez sous la forme d’erreurs au moment de la compilation).
Pour exécuter ce programme, tapez perroquet. Ne soyez pas impressionné par sa longueur, vous n’êtes pas censé comprendre chaque ligne de code pour l’instant.
Listing Exemple pratique 1 : perroquet.c
1: /* perroquet.c : ce programme répète ce qu’il vient de lire au clavier */
2: #include
3: #include
5: int lire_clavier(char *str, int taille)
6: {
7: int i;
8: fgets(str, taille, stdin);
9: str[taille-1] = ’\0’;
10: for(i=0; str[i]; i++) /* supprime le retour chariot */
11: {
12: if(str[i] == ’\n’)
13: {
14: str[i] = ’\0’;
15: break;
16: }
17: }
18: return(i); /* Renvoie 0 si la chaîne est vide */
19: }
21: int main()
22: {
23: char buffer[80];
25: printf("Entrez une ligne et validez avec Entrée\n");
26: lire_clavier(buffer, sizeof(buffer));
27: printf("Vous avez écrit : ’fis’\n", buffer)
29: exit(EXIT_SUCCESS);
30: }
Le Chapitre 5 sur les fonctions, ainsi que le Chapitre 14, qui traite des entrées/sorties, vous aideront à comprendre le fonctionnement de ce programme.
2 Structure d’un programme C
Un programme C est constitué de plusieurs modules de programmation ou blocs. Une grande partie de ce livre traite de ces divers éléments de programme et de leur utilisation. Avant de détailler chacun d’eux, nous allons étudier un programme C complet.
Aujourd’hui, vous allez apprendre à :
Exemple de programme
Le Listing 2.2 représente le code source du programme de test. Ce programme est très simple : il donne le produit de deux nombres saisis au clavier. N’essayez pas d’en comprendre les détails, ce chapitre est destiné à vous familiariser avec les composants d’un programme C.
Avant d’étudier votre programme de test, vous devez savoir ce que représente une fonc¬tion. C’est une partie indépendante du code du programme qui effectue une certaine tâche, et qui est référencée par un nom. En introduisant ce nom dans le programme, celui-ci peut exécuter le code qui lui est associé. Le programme peut transmettre des informations, appelées arguments, à cette fonction qui pourra à son tour lui renvoyer une valeur. Les deux types de fonctions C sont les fonctions de bibliothèque, qui sont four¬nies avec le compilateur C, et les fonctions utilisateur, que le programmeur peut lui-même créer.
Nous vous rappelons que les numéros de ligne inclus dans cet exemple, comme dans tous les exemples de ce livre, ne font pas partie du programme. Ne les tapez pas.
Listing 2.1 : multiplier.c
1: /* Calcul du produit de deux nombres. */
2: #include
4: int produit(int x, int y);
6: int main()
7: {
8: int a,b,c;
10: /* Lecture du premier nombre */
11: printf("Entrez un nombre entre 1 et 100 : ");
12: scanf("%d", &a);
14: /* Lecture du deuxième nombre */
15: printf("Entrez un autre nombre entre 1 et 100 : ");
16: scanf("%d", &b);
18: /* Calcul du produit et affichage du résultat */
19: c = produit(a, b);
20: printf ("\n%d fois %d = %d", a, b, c);
22: return 0;
23: }
24:
25: /* La fonction renvoie le produit de ses deux arguments */
26: int produit(int x, int y)
27: {
28: return (x * y);
29: }
Entrez un nombre entre 1 et 100 : 35
Entrez un autre nombre entre 1 et 100 : 23
35 fois 23 = 805
Structure du programme
Nous allons examiner le programme précédent ligne par ligne pour en isoler les différents composants.
La fonction main()
La fonction main() est le seul bloc obligatoire d’un programme C. Sa forme la plus simple consiste à saisir son nom, main, suivi de parenthèses () vides et d’une paire d’accolades{}. Celles-ci renferment la partie principale du programme. L’exécution du programme débute à la première instruction de main() et se termine avec la dernière instruction de cette fonction.
Appel d’un fichier #include
L’instruction d’appel #include, indique au compilateur C qu’il doit inclure le contenu d’un fichier dans le programme pendant la compilation. Ce fichier inclus (aussi appelé fichier en-tête) contient des informations destinées à votre programme ou au compilateur. Plusieurs de ces fichiers été livrés avec votre compilateur, vous ne devez pas en modifier les informations. Ils ont tous une extension .h (par exemple, stdio.h).
Dans notre exemple, l’instruction d’appel #include signifie "ajouter le contenu du fichier stdio.h". Le Chapitre 21 vous donnera de plus amples informations sur ces fichiers.
La définition de variable
Une variable est un nom donné à une zone mémoire. En effet, votre programme a besoin de mémoire pour stocker ses données en cours d’exécution. En C, une variable doit être définie avant d’être utilisée. La définition de variable indique son nom au compilateur et le type de données que l’on pourra y stocker. La définition de la ligne 8 de notre exemple, int a, b, c;, définit trois variables appelées a, b, et c qui contiendront chacune une valeur entière. Les variables et constantes numériques sont traitées au Chapitre 3.
La déclaration de fonction
La déclaration de fonction indique au compilateur C le nom et les arguments d’une fonc¬tion qui sont utilisés dans le programme. Cette déclaration doit apparaître avant l’utilisa¬tion de la fonction et ne doit pas être confondue avec la définition de fonction qui contient les instructions propres à cette fonction. Cette déclaration est facultative si la fonction peut être définie avant tout appel à elle.
Les instructions
Les instructions constituent le travail réalisé par le programme. Elles affichent les infor¬mations sur l’écran, lisent les données saisies au clavier, effectuent les opérations mathé¬matiques, appellent les fonctions, lisent les fichiers et accomplissent tous types d’opérations nécessaires à un programme. Chaque instruction occupe généralement une ligne et se termine par un point-virgule. Ce livre est consacré en grande partie à l’ensei¬gnement de ces différentes instructions.
printf ()
printf() (lignes 11, 15, et 20) est une fonction de bibliothèque qui envoie des informa¬tions à l’écran. Elle peut afficher un message texte simple (comme en ligne 11 ou 15) ou un message accompagné de variables issues du programme (comme en ligne 20).
scanf ()
scanf() (lignes 12 et 16) est une autre fonction de bibliothèque. Elle lit les données entrées au clavier et les attribue à des variables du programme.
L’instruction de la ligne 19 appelle la fonction produit() et lui transmet les arguments a et b. Le programme exécute alors les instructions appartenant à la fonction produit() qui lui renvoie une valeur. Cette valeur est sauvegardée dans la variable c.
return
L’instruction return de la ligne 28 fait partie de la fonction produit(). Elle calcule le produit des variables x et y, puis renvoie le résultat au programme appelant.
La définition de fonction
Une fonction est une portion de code indépendante qui a été écrite pour effectuer une certaine tâche. On appelle cette fonction dans un programme en introduisant son nom dans une instruction.
La fonction produit(), jusqu’à la ligne 29, est une fonction utilisateur . Comme son nom l’indique, une fonction utilisateur est écrite par le programmeur pendant le développement de son programme. Celle-ci est simple, elle multiplie deux valeurs et renvoie la réponse au programme qui l’a appelée. Vous apprendrez au Chapitre 5 qu’une bonne programmation C est basée sur une utilisation correcte de ces fonctions.
En réalité, vous n’avez pas besoin de créer une fonction pour une tâche aussi simple que la multiplication de deux nombres. Nous l’avons fait pour vous donner un exemple.
Le langage C possède de multiples fonctions de bibliothèques qui sont fournies avec le compilateur. Ces fonctions réalisent la plupart des tâches de base (comme les entrées/ sorties de l’écran, du clavier, et du disque) dont votre programme a besoin. Dans notre exemple, printf() et scanf() sont des fonctions de bibliothèque.
Les commentaires du programme
La partie de code du programme qui commence par /* et qui se termine par */ est un commentaire. Le compilateur l’ignore. Vous pouvez le placer n’importe où, il n’a aucune influence sur le déroulement du programme. Un commentaire peut s’étendre sur une ou plusieurs lignes, ou sur une partie de ligne seulement. En voici trois exemples :
/* un commentaire d’une ligne */
int a, b, c; /* sur une partie de ligne */
/* un commentaire qui s’étend sur plusieurs lignes */
Vous ne devez pas imbriquer des commentaires, cela provoque une erreur avec beaucoup de compilateurs :
/*
/* mauvais exemple à ne pas suivre */ */
Même si certains compilateurs les acceptent, évitez-les si vous voulez conserver une bonne portabilité de votre code C. De tels commentaires peuvent aussi conduire à des problèmes difficiles à résoudre.
Beaucoup d’apprentis programmeurs considèrent les commentaires comme une perte de temps inutile. C’est une erreur ! Votre code peut vous sembler tout à fait clair pendant que vous le développez, surtout s’il s’agit d’un programme simple. Mais s’il évolue dans le temps pour devenir plus complexe, vous apprécierez ces commentaires quand vous aurez à le modifier. Prenez l’habitude de bien documenter ce qui le nécessite, en faisant également attention à ne pas trop en mettre.
Certains programmeurs utilisent un type de commentaire plus récent qui est disponible avec le langage C++ ou Java : le double slash (// ). En voici deux exemples :
// cette ligne est un commentaire
int x;// les commentaires débutent après les deux slash
Les deux slashs signifient que la fin de la ligne est un commentaire. Même si beaucoup de compilateurs les acceptent, vous devriez les éviter pour conserver une bonne portabilité de votre code.
À faire
Commenter votre code source, surtout s’il contient des algorithmes qui pour¬raient être difficiles à comprendre. Vous gagnerez un temps précieux quand vous aurez à les modifier.
À ne pas faire
Formuler des commentaires inutiles. Par exemple,
/* Le programme suivant affiche "Hello, world !" sur votre écran */ printf("Hello, World ! ");
Ce commentaire est inutile si vous connaissez le fonctionnement de printf(). À faire
Apprendre à doser les commentaires dans vos programmes. S’ils sont peu nom¬breux ou en style télégraphique, ils ne seront pas d’un grand secours. S’ils sont trop longs, vous passerez plus de temps à commenter qu’à programmer.
Les accolades
Les accolades (il) permettent d’encapsuler les lignes de programmes qui constituent chaque fonction C. On appelle bloc l’ensemble des instructions qui se trouvent entre ces accolades.
Comment exécuter le programme
Prenez le temps de saisir, compiler, et exécuter multiplier.c. C’est une bonne occasion d’utiliser votre éditeur et votre compilateur. Rappelez-vous les étapes du Chapitre 1 :
Remarque
Un ordinateur est précis et rapide, mais il ne fait qu’exécuter des ordres. Il est parfaitement incapable de corriger la moindre erreur .
Cela est valable pour votre code source C. Le compilateur échouera à la moindre faute de frappe. Heureusement, même s’il ne peut pas corriger vos erreurs, il sait les reconnaître pour vous les indiquer. (Les messages du compilateur et leur interprétation sont traités dans le chapitre précédent.)
Étude de la structure d’un programme
Vous connaissez maintenant la structure d’un programme. Étudiez le Listing 2.2 et essayez d’en reconnaître les différentes parties.
Listing 2.2 : list_it.c
1: /*list_it.c Ce programme affiche du code source avec les numéros de lignes. */
2: #include
3: #include
5: void display_usage(void);
6: int line;
8: int main(int argc, char *argv[])
9: {
10: char buffer[256];
11: FILE *fp;
13: if(argc < 2)
14: {
15: display_usage();
16: exit(EXIT_FAILURE);
17: }
19: if ((fp = fopen(argv[1], "r")) == NULL)
20: {
21: fprintf(stderr, "erreur fichier, %s!", argv[1]);
22: exit(EXIT_FAILURE);
23: }
25: line = 1;
27: while(lire_clavier(buffer, sizeof(buffer)))
28: fprintf(stdout, "%4d:\t%s", line++, buffer);
30: fclose(fp);
31: exit(EXIT_SUCCESS);
32: }
34: void display_usage(void)
35: {
36: fprintf(stderr, "La syntaxe est la suivante :\n\n");
37: fprintf(stderr, "list_it filename.ext\n");
38: }
C:\>list_it list_it.c
1: /*list_it.c Ce programme affiche du code source avec les numéros de lignes. */
2: #include
3: #include
5: void display_usage(void);
6: int line;
8: int main(int argc, char *argv[])
9: {
10: char buffer[256];
11: FILE *fp;
13: if(argc < 2)
14: {
15: display_usage();
16: exit(EXIT_FAILURE);
17: }
19: if ((fp = fopen(argv[1], "r")) == NULL)
20: {
21: fprintf(stderr, "erreur fichier, %s!", argv[1]);
22: exit(EXIT_FAILURE);
23: }
25: line = 1;
27: while(lire_clavier(buffer, sizeof(buffer)))
28: fprintf(stdout, "%4d:\t%s", line++, buffer);
30: fclose(fp);
31: exit(EXIT_SUCCESS);
32: }
34: void display_usage(void)
35: {
36: fprintf(stderr, "\nLa syntaxe est la suivante : ");
37: fprintf(stderr, "\n\nLIST_IT filename.ext\n");
38: }
Analyse
list_it.c ressemble à print_it.c du Chapitre 1. Il permet d’afficher le source du programme numéroté à l’écran, au lieu de l’envoyer vers l’imprimante.
Nous pouvons identifier les différentes parties de ce programme. La fonction main() est développée de la ligne 8 à 32. Les lignes 2 et 3 contiennent les appels du fichier en-tête #include et les définitions de variables sont en lignes 6, 10 et 11. Nous trouvons la décla¬ration de fonction, void display usage(void), en ligne 5. Ce programme possède de nombreuses instructions (lignes 13, 15, 16, 19, 21, 22, 25, 27, 28, 30, 31, 36, et 37). Les lignes 34 à 38 représentent la définition de fonction display usage. La ligne 1 est une ligne de commentaires et des accolades séparent les différents blocs du programme.
list_it.c appelle plusieurs fonctions. Les fonctions de bibliothèque utilisées sont exit() en lignes 16, 22 et 31, fopen() en ligne 19, fprintf() en lignes 21, 28, 36, et 37, lire clavier() en ligne 27 (notre fonction définie dans l’exemple pratique 1), enfin fclose() en ligne 30. display usage() est une fonction utilisateur. Toutes ces fonctions sont traitées plus loin dans ce livre.
Résumé
Ce chapitre court a abordé un sujet important : les principaux composants d’un programme C. Vous avez appris que la fonction main() est obligatoire et que les instructions du programme permettent de transmettre vos ordres à l’ordinateur. Ce chapitre a aussi introduit les variables, leurs définitions, et vous a expliqué comment et pourquoi introduire des commentaires dans le code source.
Un programme C peut utiliser deux types de fonctions : les fonctions de bibliothèque qui sont fournies avec le compilateur, et les fonctions utilisateur qui sont créées par le programmeur.
Q & R
Q Les commentaires ont-ils une influence sur le déroulement du programme ?
R Les commentaires sont destinés aux programmeurs. Lorsque le compilateur converti le code source en code objet, il supprime tous les blancs et commentaires. Ils n’ont donc aucune influence sur l’exécution du programme. Les blancs et commentaires permet¬tent simplement de clarifier le code source pour faciliter la lecture et la maintenance du programme.
Q Quelle est la différence entre une instruction et un bloc ?
R Un bloc est constitué d’un groupe d’instructions entre accolades ({}).
5 Les fonctions
Les fonctions sont au centre de la programmation du langage C et de la philosophie du développement dans ce langage. Nous avons vu les fonctions de bibliothèque qui sont fournies avec le compilateur. Ce chapitre traite des fonctions utilisateur qui sont créées par le programmeur.
Aujourd’hui, vous allez apprendre :
Qu’est-ce qu’une fonction ?
Ce chapitre aborde les fonctions sous deux angles, en les définissant et en montrant à quoi elles servent.
Définition
Une fonction est un bloc de code C indépendant, référencé par un nom, qui réalise une tâche précise et qui peut renvoyer une valeur au programme qui l’a appelée. Examinons cette définition :
Exemple de fonction
Listing 5.1 : Ce programme emploie une fonction utilisateur pour calculer le cube d’un nombre
1: /* Exemple d’une fonction simple */
2: #include
3: #include
4: long cube(long x);
6: long input, reponse;
8: int main()
9: {
10: printf("Entrez une valeur entière : ");
11: scanf("%d", &input);
12: reponse = cube(input);
13: /* Note: %ld est la spécification de conversion d’un entier long */
14: printf("\n\nLe cube de %ld est %ld\n.", input, reponse);
15: exit(EXIT_SUCCESS);
16: }
18: long cube(long x)
19: {
20: long x_cube;
22: x_cube = x * x * x;
23: return x_cube;
24: }
Entrez un nombre entier : 100 Le cube de 100 est 1000000 Entrez un nombre entier : 9 Le cube de 9 est 729
Entrez un nombre entier : 3 Le cube de 3 est 27
L’analyse suivante ne porte pas sur la totalité du programme, mais se concentre sur les éléments du programme directement en relation avec la fonction.
Analyse
La ligne 4 contient le prototype (déclaration) de la fonction qui représente un modèle pour une fonction qui apparaîtra plus loin dans le programme. Ce prototype contient le nom de la fonction, la liste des variables qui lui seront transmises, et éventuellement le type de variable que la fonction renverra. La ligne 4 nous indique que la fonction s’appelle cube, qu’elle utilise une variable de type long, et qu’elle renverra une variable de type long. Les variables qui sont transmises à la fonction sont des arguments et apparaissent entre paren¬thèses derrière le nom de la fonction. Dans notre exemple, l’argument de la fonction est long x. Le mot clé situé avant le nom indique le type de variable renvoyé par la fonction. Dans notre cas, c’est un type long.
La ligne 12 appelle la fonction cube et lui transmet en argument la variable input. La valeur renvoyée par la fonction est stockée dans la variable reponse. Ces deux variables sont déclarées en ligne 6 avec le type long ce qui correspond bien au prototype de la ligne 4.
Les lignes 18 à 24, qui constituent la fonction cube elle-même, sont appelées définition de la fonction. La fonction commence par un en-tête en ligne 18 qui indique son nom (dans notre exemple cube). Cet en-tête décrit aussi le type de donnée qui sera renvoyée et les arguments. Vous pouvez remarquer que l’en-tête de fonction est identique au prototype (le point-virgule en moins).
Les lignes 20 à 23 représentent le corps de la fonction ; il est encadré par des accolades. Il contient des instructions, comme celle de la ligne 22, qui sont exécutées chaque fois que la fonction est appelée. La ligne 20 est une déclaration de variable comme nous en avons déjà vu, à une exception près : c’est une variable locale. Les variables locales, qui sont traitées au Chapitre 12, sont déclarées à l’intérieur d’une fonction. La ligne 23 indique la fin de la fonction et renvoie une valeur au programme appelant. Dans notre cas, c’est la valeur de x cube qui est transmise.
Si vous comparez la structure de la fonction avec celle de la fonction main(), vous ne trouverez pas de différence. Comme printf() ou scanf() qui sont des fonctions de bibliothèque, toutes les fonctions peuvent recevoir des arguments et renvoyer une valeur au programme qui les a appelées.
Fonctionnement
Les instructions d’une fonction dans un programme ne sont exécutées que lorsqu’elles sont appelées par une autre partie de ce programme. Quand la fonction est appelée, le programme lui transmet des informations sous la forme d’arguments. Un argument est une donnée de programme dont la fonction a besoin pour exécuter sa tâche. La fonction s’exécute puis le programme reprend à partir de la ligne qui contient l’appel en récupérant éventuellement une valeur de retour.
La Figure 5.1 représente un programme qui appelle trois fonctions. Les fonctions peuvent être appelées autant de fois que nécessaire et dans n’importe quel ordre.
Figure 5.1
Quand un programme appelle une fonction, les instructions de la fonc-tion s’exécutent puis le programme reprend la main pour la suite de son exécution.
Fonctions
Prototype de la fonction
type_retour nom_fonction (type_arg nom–1, ..., type_arg nom–n); Définition de la fonction
type_retour nom_fonction (type_arg nom–1, ..., type_arg nom–n) ;
{
/* instructions; */
}
Le prototype de la fonction fournit au compilateur la description d’une fonction qui est définie plus loin dans le programme. Cette description comprend le nom de la fonction, le type de valeur (type retour) qui sera renvoyée à la fin de l’exécution de la fonction et les types d’arguments (type arg) qui lui seront transmis. Il peut éventuellement contenir le nom des variables qui seront transmises et il se termine toujours par un point-virgule.
La définition de la fonction est la fonction, c’est-à-dire le code qui sera exécuté. La première ligne, l ’en-tête de la fonction, est identique au prototype, à l’exception du point-virgule. Cet en-tête doit obligatoirement contenir le nom des variables arguments qui était en option dans le prototype. Il est suivi du corps de la fonction, les instructions entre acco¬lades. Si le type retour n’est pas void, il faut une instruction return qui renvoie une valeur correspondant au type retour.
Exemples de prototypes
double carré (double nombre);
void impression_rapport (int nombre_rapport); int choix_menu (void);
Exemples de définitions
double carré (double nombre) /* en-tête de fonction */
{ /* accolade de début */
return (nombre * nombre); /* corps de la fonction */
} /* accolade de fin */
impression_rapport (int nombre_rapport)
{
if (nombre_rapport == 1)
puts ("Impression rapport 1");
else
puts("pas d’impression du rapport 1");
}
Les fonctions et la programmation structurée
En utilisant des fonctions dans votre programme vous pratiquez la programmation structurée. Cela signifie que les différentes tâches du programme sont réalisées par des portions de code indépendantes : les fonctions.
Avantages de la programmation structurée
La programmation structurée a deux avantages :
Ce type de programmation peut vous faire gagner du temps. En effet, une fonction que vous aurez écrite dans un programme pour réaliser une certaine tâche, pourra facilement être utilisée dans un autre programme pour réaliser la même tâche. Si celle-ci est légèrement différente, il sera plus facile de la modifier que d’en créer une nouvelle.
Étude d’un programme structuré
Pour écrire un programme structuré, vous devez faire une étude préalable avant de créer la première ligne de code. Cette étude doit être composée de la liste des tâches à réaliser par le programme. Par exemple, pour écrire un programme de gestion de vos adresses, voici les tâches que devrait pouvoir faire ce programme :
Cette liste permet de partager le programme en quatre fonctions principales. Vous pouvez maintenant décomposer ces tâches en sous-tâches plus simples. "Saisir les nouveaux noms et adresses" peut ainsi devenir :
De la même façon, vous pouvez décomposer "Modifier un enregistrement" :
Ces deux listes ont deux sous-tâches en commun : celle qui lit et celle qui sauvegarde. Vous pouvez écrire une fonction pour "lire les adresses existantes sur disque" et cette fonc¬tion sera appelée par chacune des fonctions "Saisir les nouveaux noms et adresses" et "Modifier un enregistrement". Le raisonnement est le même pour "Sauvegarder la nouvelle liste sur disque".
En identifiant ainsi des parties du programme qui réalisent la même tâche, vous pouvez écrire des fonctions qui seront appelées plusieurs fois par le programme. Vous gagnez du temps et votre programme est plus efficace.
Comme le montre la figure suivante, cette méthode de programmation conduit à une struc¬ture de programme hiérarchique.
Impression
L’approche top-down
Avec la programmation structurée, les programmeurs adoptent une approche top-down (de haut en bas). Cela est illustré par la Figure 5.2 ou la structure du programme ressemble à un arbre inversé. En général, les tâches importantes sont réalisées au bout des "branches", les autres fonctions sont là pour orienter l’exécution du programme vers ces fonctions.
Par ce fait, beaucoup de programmes C ont très peu de code dans la partie principale main(), et une partie de code importante pour les fonctions. Vous trouverez dans la partie main quelques lignes d’instructions dont le rôle se limitera à aiguiller l’exécution du programme vers les fonctions. Ces lignes représentent souvent un menu dans lequel l’utili¬sateur choisit la tâche qu’il veut réaliser. Chaque partie de ce menu utilise une fonction différente.
Le Chapitre 13, avec l’instruction switch, vous apprendra à créer un bon système à base de menus.
À faire
Établir le plan du programme avant de commencer à coder. En déterminant à l’avance la structure de votre programme, vous gagnerez du temps au dévelop¬pement et à la correction.
À ne pas faire
Essayer de tout faire avec une seule fonction. Une fonction doit exécuter une seule tâche, comme lire un fichier ou sauvegarder des données.
Écriture d’une fonction
La première étape de l’écriture d’une fonction consiste à savoir ce que doit faire cette fonction. La suite ne représente pas de difficultés particulières.
En-tête
La première ligne d’une fonction est l’en-tête de la fonction. Il est constitué de trois éléments qui ont chacun un rôle particulier.
type nom_fonction(parm1,.
Nom de la fonction
Type de la valeur renvoyée
Le type de la valeur renvoyée indique le type de donnée que la fonction retournera au programme appelant. Ce type peut être : char, int, long, float, ou double. Vous pouvez aussi créer une fonction qui ne retourne pas de valeur en utilisant le type de valeur renvoyée void. Voici quelques exemples :
int fonc1(...) /* renvoie une donnée de type int. */
float fonc2(...) /* renvoie une donnée de type float. */
void fonc3(...) /* ne renvoie aucune donnée. */
Nom
Le nom d’une fonction doit suivre les mêmes règles que les noms de variables C (voir Chapitre 3) et il doit être unique (vous ne pouvez pas appeler une variable ou une autre fonction par le même nom).
Liste des paramètres
Beaucoup de fonctions utilisent des arguments, et elles ont besoin de connaître le type de donnée qu’elles vont recevoir. Vous pouvez transmettre à une fonction n’importe quel type de donnée C en l’indiquant dans l’en-tête de cette fonction avec la liste de paramètres.
À chaque argument transmis vers la fonction doit correspondre une entrée dans la liste de paramètres. Voici, par exemple, l’en-tête de la fonction du Listing 5.1 :
long cube (long x)
La liste de paramètres contient long x ce qui indique à la fonction qu’elle recevra un para¬mètre de type long représenté par la variable x. Si la liste contient plusieurs paramètres, ils sont séparés par une virgule. Examinons l’en-tête suivant :
void fonction1 (int x, float y, char z)
La fonction va recevoir trois arguments : x de type int, y de type float, et z de type char. Une fonction qui ne doit pas recevoir de paramètre a une liste d’arguments qui contient void :
void fonction2 (void)
Il ne faut pas mettre de point-virgule à la fin de votre en-tête de fonction, sinon le compilateur générera un message d’erreur.
Il ne faut pas confondre paramètre et argument. Un paramètre est une entrée de l’en-tête de la fonction, il "annonce" l’argument. Les paramètres ne peuvent changer pendant l’exécution du programme.
Un argument est une donnée transmise à la fonction par le programme appe¬lant. Chaque fois que la fonction sera appelée, le programme pourra lui trans¬mettre des valeurs d’arguments différents. Par contre, le nombre et le type des arguments transmis ne doivent pas changer. L’argument est référencé par le nom correspondant dans la liste de paramètres.
Listing 5.2 : Différence entre argument et paramètre
1: /* Ce programme montre la différence entre paramètre et argument */
2: #include
3: #include
5: float x = 3.5, y = 65.11, z;
7: float moitie_de(float k);
9: int main()
10: {
11: /* Dans cet appel, x est l’argument de moitie_de(). */
12: z = moitie_de(x);
13: printf("La valeur de z = %f\n", z);
15: /* Dans cet appel,y est l’argument de moitie_de(). */
16: z = moitie_de(y);
17: printf("La valeur de z = %f\n", z);
18: exit(EXIT_SUCCESS);
19: }
21: float moitie_de(float k)
22: {
23: /* k est le paramètre. Chaque fois que moitie_de est */
24: /* appelée, k prend la valeur qui a été passée en argument */
26: return (k/2);
27: }
La valeur de z = 1.750000 La valeur de z = 32.555000
Premier appel de la fonction z=moitié_de(x); 3,5
float moitié_de(float k)
Second appel de la fonction z=moitié_de(y); 65,11
float moitié_de(float k)
Analyse
Examinons le programme du Listing 5.2. Le prototype de la fonction moitie de() se trouve en ligne 7. Les lignes 12 et 16 appellent cette fonction dont les instructions sont en lignes 21 à 27. La ligne 12 envoie l’argument x, qui contient la valeur 3,5 ; la ligne 16 envoie l’argument y, qui contient la valeur 65,11. Les résultats donnés par le programme donnent bien la moitié de ces deux valeurs. Les valeurs contenues dans x et y sont transmises par l’intermédiaire de l’argument k de moitie de(). On a fait, en fait, une copie de x en k puis une copie de y en k. La fonction a ensu