Les fonctions
Description du chapitre et des ses objectifs :
Autre point primordial du C et de tous les langages actuels, les fonctions. Elles permettent de diviser le code, de le
factoriser (d'éviter qu'il se répète). Un bon programmeur sait faire des fonctions qui s'adaptent au plus de cas possibles.
Que vont faire nos fonctions? Et bien elles vont traiter les variables que nous lui envoyons, comme des fonctions mathématiques, mais l'
algorithmie en plus.
Accéder directement à une des parties du cours :
Pourquoi des fonctions?
Ha les fonctions... tout ce qui définit un langage. Qu'est-ce qu'à proprement parler une fonction?
Peut-être avez-vous vu en mathématique des fonctions de base comme:
Citation Professeur de mathématique :
F(x)= x + 3
Et bien en C, les fonctions s'en rapproche énormément. Ce sont des environnements pour opérer sur nos variables. Chacun de ces environnements sont hermétiques, cela signifie que les variables déclarées dans chaque fontion n'existent pas dans les autres fonctions. Le seul moyen d'envoyer des valeurs vers le traitement qu'effectue une fonction est de les passer en
argument.
Question : Oula, ça veut dire quoi ça?
Et bien comme dans la fonction de votre professeur de maths, F(x) prends un argument. Ici l'argument c'est x. Et pour chaque valeur de x que vous envoyez, le résultat en sortie va changer.
Par exemple, si vous remplacez x par 4: F(4)= 4 + 3 = 7. C'est un peu plus clair?
Notez bien qu'une fonction peut avoir plusieurs arguments. Par exemple votre professeur de mathématique aurait pu faire cette fonction:
Citation Professeur de mathématique : G(x,y)= x * y + 1
Donc si vous envoyez en argument x=4 et y=3, on aurait obtenu: G(4,3)= 4 * 3 + 1 = 13.
Voyons comment traduire ça en C...
Créer une fonction
Une fonction doit d'abord être déclarée, un peu comme une variable, cela se décompose en 3 morceaux:
<type de retour> <nom>( <arguments> );
On appelle cela le
prototype de la fonction. En voici un exemple:
int addition(int x, int y);
Voyons cela de plus près:
int est le type de retour, c'est le type du résultat que va renvoyer la fonction (si la fonction renvoie un nombre a virgule, on aurait mis un
float en type de retour par exemple).
addition est le nom de la fonction, toutes les fonctions doivent avoir un nom différent (et donc unique) comme les variables!
(int x, int y) sont les arguments. Notez bien qu'il faut mettre entre parenthèses tous les arguments de la fonction. Ces arguments doivent être déclarés, car on va travailler dessus. On indique donc le nom et le type des variables que la fonction attend. Tous les arguments sont séparés par une
virgule. N'oubliez pas de mettre un ";" à la fin de la ligne, c'est une déclaration pour le moment, il n'y a pas d'action a effectuer.
Déclarer une fonction signifie expressément qu'il est possible d'utiliser cette fonction, donc à partir du moment que le programme à lu qu'il existe cette fonction, vous pourrez l'utiliser, ce que l'on verra tout à l'heure.
Attention : On n'initialise pas les variables dans les arguments, il s'agit donc bien de dire quel type de valeur la fonction va attendre. Ces valeurs seront copiées dans les variables spécifique à la fonction.
<type de retour> <nom>( <arguments> );
Maintenant qu'elle a été déclarée il faut l'initialiser. Le prototype servant à donner le feu vert à toute utilisation de la fonction, il faut maintenant donner du contenu à exécuter dans notre fonction. On
initialise donc la fonction après sa déclaration. Voici la syntaxe de l'initialisation:
<type de retour> <nom>( <arguments> )
{
<instructions>
}
Pour savoir à quelle fonction la déclaration doit se reporter pour l'initialisation de la fonction, il faut impérativement mettre les mêmes type de retour, nom et arguments que dans la déclaration de la fonction. La différence fondamentale entre une déclaration et une initialisation viens de la présence ou non du ";" pour un prototype, remplacé par un couple d'accolades {} qui délimitent le
bloc d'instructions qui sera exécuté lors de l'
appel de la fonction (son utilisation). Voici un exemple:
int addition(int x, int y);
int addition(int x, int y)
{
int a = x + y;
return a;
}
Voila une fonction complète!
Etudions la attentivement:
Le prototype que je vous ai expliqué.
Suivit de l'initialisation qui est remarquée par l'
accolade ouvrante. Tout ce qui suit sera donc exécuté par la fonction.
On retrouve dedans une déclaration de variable:
a. Celle ci n'est là qu'en tant que exemple, vous pouvez bien entendu la nommer et la manipuler comme je vous ai expliqué dans le chapitre précédent.
Puis on trouve le mot clef
return suivit de la variable
a. Cela signifie que la fonction va
retourner la valeur de
a. Dès que la fonction exécute un
return elle va arrêter de s'exécuter. C'est donc la dernière ligne lue par la fonction.
Enfin on ferme le
bloc d'instruction avec une accolade fermante, cela signifie que tout le code contenu après ne fait plus partie de la fonction. Il faut
impérativement qu'il y ai une accolade fermante pour bien dire qu'il n'y a rien d'autre dans la fonction.
En résumé, pour faire une fonction il faut:
1° un prototype
2° le prototype sans point virgule ";"
3° une accolade ouvrante "{"
4° un return
5° une accolade fermante "}"
Information : On ne peut pas déclarer ni initialiser une fonction dans une autre fonction, elle doivent toujours être séparées
Revenons un peu sur le prototype de la fonction, et plus particulièrement le type de retour. Comme vous avez pu le remarquer, la fonction retourne une
valeur (non pas une variable attention), il faut donc savoir quelle taille elle fait. C'est une spécificité que vous comprendrez lorsque vous utiliserez vos premières fonctions.
La fonction précédente aurait pu être écrite d'autres façons:
int addition(int x, int y)
{
return x + y;
y *= x;
}
Que va faire cette fonction? Et bien elle va renvoyer la valeur de
x + y.
Question : Et?
Et c'est tout, on a dit que la fonction arrêtait de s'exécuter au moment du
return.
Petit exercice, que fait cette fonction
mystere:
float mystere(float a, float b, float c)
{
float tmp = a + b + c;
tmp /= 3.0;
return tmp;
}
On réfléchit...
Bravo! Elle renvoie la moyenne des 3 valeurs sous forme d'un float. (j'espère que vous aviez trouvé

)
Information : Il est préférable d'avoir des noms de fonction clairs, si vous appelez toutes vos fonctions aa,ab,ac,ad... vous ne vous en sortirez pas. Cela est surtout utile dans le cas où vous devriez faire relire le code par quelqu'un d'autre.
Attention : Dans les plus anciennes normes du C (le C à eu plusieurs versions), les variables doivent toutes être déclarées en début de fonction! Cependant, comme vous le verrez plus loin, c'est de nos jours un peu plus laxiste sur ce point. Mais si vous voulez respecter la norme d'origine que je vous enseigne (c89), il est impératif de respecter ces règles.
Utiliser une fonction
Je sens que vous avez très envie d'utiliser vos fonctions et d'expérimenter tout ce que vous avez appris, patience ceci est le dernier chapitre avant de créer votre premier programme! Il ne vous reste plus qu'à savoir utiliser les fonctions.
Question : Alors comment on utilise les fonctions?
Et bien on l'appelle par son nom avec les arguments que l'on veut! Bien sur, il faut que la fonction soit déclarée avant, sinon on ne peut l'appeler, comme pour les variables. De plus à partir de maintenant,
TOUTES les instructions que vous utiliserez devrons se trouver dans une fonction. De façon provisoire, j'appelle ma fonction principale
calculer, c'est à partir d'elle que j'appellerai les fonctions au fur et à mesure. Vous verrez dans le prochain chapitre son vrai nom.
Reprenons les exemples vus juste avant:
int addition(int x, int y);
float moyenne(float a, float b, float c);
int calculer(int argument);
int addition(int x, int y)
{
int a = x + y;
return a;
}
float moyenne(float a, float b, float c)
{
float tmp = a + b + c;
tmp /= 3.0;
return tmp;
}
int calculer(int argument)
{
float x, c = 3, b = 9;
float variableA = 10.5, resultat;
x = addition(c , b);
resultat = moyenne( 12, variableA, x);
return argument;
}
Vous comprenez maintenant à quoi sert le type de retour? Le but est de savoir ce qu'il faut stocker comme variable à l'appel de la fonction. La
fonction est donc considéré comme une valeur.
Remarquez que le nom des variables envoyés à une fonction importe peu, comme je vous l'ai dit, une fonction reçoit des valeurs et exécute un traitement de ces valeurs. Ces valeurs sont stockées dans les arguments qu'on a déclaré dans notre prototype. Comme vous avez pu le remarquer, l'initialisation ne doit pas forcément se faire juste après la déclaration.
Attention : Les fonctions sont hermétiques, la variable c déclarée en bas n'est pas la même que celle de la fonction moyenne par exemple. Les fonction sont des blocs indépendants, et les variables déclarées dans une fonction sont détruites à la fin de l'utilisation de celle ci. Seule est renvoyée la valeur associée au return.
Autre point, il est tout à fait possible
d'utiliser une fonction dans une autre, voici un nouveau code qui fait exactement la même chose que le précédent:
float addition(float x, float y)
{
return x + y;
}
float moyenne(float a, float b, float c)
{
float tmp = a + b + c;
tmp /= 3.0;
return tmp;
}
int calculer(int argument)
{
float variableA = 10.5, resultat;
resultat = moyenne( 12, variableA, addition(3 ,6));
return argument;
}
Les combinaisons sont infinies

. Puissant comme outil vous ne trouvez pas?
Question : Hey? Où sont passés les prototypes?
Grâce à la magie du C, si la fonction appelée est initialisée avant elle, il n'est pas nécessaire de la déclarer, la déclaration se fait automatiquement dans le sens de la lecture du code, on dit que la déclaration est
implicite. Donc si je souhaite utiliser une fonction écrite
après l'endroit où je suis en train de lire et qu'elle n'a pas été déclarer, il sera impossible de savoir ce que doit faire le code. Voici donc un exemple de code
impossible utilisant les exemples précédents:
Erreur :
float moyenne(float a, float b, float c)
{
float tmp = addition( addition(a , b), c));
tmp /= 3.0;
return tmp;
}
float addition(float x, float y)
{
return x + y;
}
Pour que ce code soit juste, il aurait donc suffit d'ajouter en haut du code les prototypes des fonctions.
Un dernier point concernant les prototypes. Comme ce ne sont en fait que des "alerteur" pour dire qu'une fonction de tel nom/argument/type de retour existe, il n'est pas nécessaire de mettre un nom de variable après le type d'un argument. En plus clair, ces 2 prototypes sont corrects et strictement identiques:
int addition(int a,int b);
int addition(int,int);
Vous voici arrivé à la fin de la partie théorique avant la pratique. Les fonctions sont l'outil majeur de tout bon programmeur qui évite de répéter son code, n'hésitez donc pas à en abuser. Vous allez maintenant découvrir les joies( et déceptions ) de la compilation!
Chapitre précédent - Sommaire - Chapitre suivant
Nos rédacteurs et membres sont pour la plupart ouverts à des remarques constructives et servir à alerter le rédacteur du cours, des fautes éventuelles ou de propositions et nouvelles perspectives de cours etc ...
Pour ce faire cliquez ici
Postez vous aussi un commentaire à cette partie via le lien que voici