Une fonction est un petit bloc de programme (une sorte de sous-programme) qui va créer, faire ou modifier quelque chose. Un bloc de programme est mis sous la forme d’une fonction si celui-ci est utilisé plusieurs fois dans un programme, si on veut le réutiliser dans un autre programme (bibliothèque) ou simplement pour une question de clarté du code.
Le format de la déclaration est toujours le suivant :
<type de sortie> <nom de la fonction> (<paramètres d'appel>);
Cette déclaration est à placer avant le "main()" ou dans un fichier ".h" séparé.
Exemple : prototype d’une fonction dont le rôle sera d’afficher "Bonjour" :
void afficheBonjour();
On peut voir ici que :
Le corps de la fonction (ou la définition) se fait après la déclaration de la fonction ou dans un fichier ".c" séparé :
Le corps de la fonction est délimité par des accolades { } comme le main().
Exemple : corps de la fonction dont le rôle est d’afficher "Bonjour !" :
void afficheBonjour() {
printf("Bonjour !");
}
On peut voir ici que :
La fonction peut être utilisée dans le "main()" ou une autre fonction.
Exemple complet :
#include <stdio.h>
void afficheBonjour(); // Déclaration de la fonction
int main() {
afficheBonjour(); // Appel de la fonction
}
void afficheBonjour() { // Définition de la fonction (code)
printf("Bonjour !");
}
Remarque : "printf" et "scanf", que nous avons utilisé jusqu’à présent, sont des fonctions qui sont définies dans la bibliothèque "stdio.h".
On souhaite créer une fonction qui affiche le prix TTC d’un article en fonction de son prix HT (Hors Taxes) et de la TVA. Ces valeurs (prix HT et TVA) seront passées en paramètre à la fonction.
void affichePrixTTC(float prixHT, float tva);
Ceci indique que la fonction va recevoir un paramètre de type Réel dont le nom est "prixHT" et un second paramètre de type Réel dont le nom est "tva".
void affichePrixTTC(float prixHT, float tva) {
printf("Le prix TTC est : %.2f", prixHT * (1 + tva / 100));
}
On peut voir ici que :
int main() {
float tauxTva = 20.0;
affichePrixTTC(12.50, tauxTva); // Affiche le prix TTC d’un produit à 12,5 avec une TVA à 20%
}
Au moment de l’appel il faut respecter les types définis dans le prototype de la fonction : ici le prototype de la fonction indique qu’il faut lui passer deux "float" en paramètres. Les valeurs passées doivent donc bien être de type "float".
Remarque : Au moment de l’appel de la fonction la valeur de la variable "tauxTva" déclarée dans le main() va être copiée dans la variable "tva" (paramètre d’appel) de la fonction "affichePrixTTC". La fonction travaille donc sur une copie de la variable, on est donc certain que la fonction ne modifiera pas la variable "tauxTva".
Nous avons vu que le format de déclaration d’une fonction est :
<type de sortie> <nom de la fonction> (<paramètres d'appel>);
Pour le type de sortie, nous avons vu que "void" indique que la fonction ne renvoie pas de résultat.
Nous allons créer ici une fonction qui calcule et renvoie le prix TTC d’un produit en fonction de son prix HT et du taux de TVA.
float calculPrixTTC(float prixHT, float tva);
Le premier "float" indique que la fonction va renvoyer une valeur de type nombre Réel. Les deux autres (dans les parenthèses) indiquent que la fonction va recevoir un paramètre de type Réel dont le nom est "prixHT" et un second paramètre de type Réel dont le nom est "tva".
float calculPrixTTC(float prixHT, float tva) {
float prixTTC;
prixTTC = prixHT * (1 + tva / 100);
return prixTTC;
}
On peut voir ici que :
int main() {
float tauxTva = 20.0;
float pTTC_produit;
pTTC_produit = calculPrixTTC(12.50, tauxTva); // Ici, la valeur renvoyée par la fonction est copiée dans la variable pTTC_produit
printf("Prix TTC : %f", pTTC_produit);
}
Nous savons que les paramètres passés à une fonction sont dupliqués en mémoire. Ceci fait que la fonction ne peut pas modifier les valeurs originales puisqu’elle travaille sur des copies.
Dans certains cas, nous pouvons avoir besoin qu’une fonction puisse modifier les valeurs des paramètres.
Par exemple imaginons une fonction qui aurait pour rôle d’échanger 2 variables. On voit bien ici qu’il est absolument nécessaire que la fonction puisse accéder directement aux variables concernées et non à des copies.
Un pointeur est une variable qui contient l’adresse d’une autre variable :
Pour déclarer un pointeur, on met une "*" après sont type :
int* ptr1; // ptr1 est un pointeur sur un entier
float* ptr2; // ptr2 est un pointeur sur un réel
char* ptr3; // ptr3 est un pointeur sur un caractère
Pour obtenir l’adresse d’une variable, on met le symbole "&" devant la variable :
scanf("%d", &nb1);
Pour écrire dans une variable à partir de son pointeur, on met une "*" avant le nom du pointeur :
int* ptr1; // ptr1 est un pointeur sur un entier
*ptr1 = 3; // On écrit la valeur 3 à l’adresse pointée par ptr1
Exemple : On veut écrire une fonction qui a pour rôle d’échanger 2 variables de type nombres entiers.
void echange(int* nb1, int* nb2);
Ceci indique que la fonction va recevoir un paramètre de type pointeur sur un entier dont le nom est "nb1" et un second paramètre de type pointeur sur un entier dont le nom est "nb2".
void echange(int* nb1, int* nb2) {
int temp;
temp = *nb1;
*nb1 = *nb2;
*nb2 = temp;
}
On peut voir ici que :
int main() {
int valeur1 = 120;
int valeur2 = 200;
echange(&valeur1, &valeur2); // Suite à l’exécution de la fonction, valeur1 = 200 et valeur2 = 120
}
Il est possible de passer un tableau en paramètre à une fonction. Comme le nom d’un tableau est en réalité déjà un pointeur, pas besoin de mettre le "&" quand on passe un tableau en paramètre. De la même manière, à l’intérieur de la fonction on n’utilise pas "*" mais les crochets "[ ]" pour accéder aux valeurs du tableau.
Exemple : on veut créer une fonction qui initialise à 0 toutes les cases d’un tableau d’entiers. On passe en paramètre le nom du tableau ainsi que sa taille.
void fillTabWithZero(int tab[], int size);
ou
void fillTabWithZero(int* tab, int size);
void fillTabWithZero(int tab[], int size) {
int i;
for(i = 0 ; i < size ; i++)
tab[i] = 0;
}
int main() {
int tabEntiers[200];
fillTabWithZero(tabEntiers, 200);
}
Faire les exercices sur les fonctions en langage C.
Article connexe : Les structures algorithmiques de base