Formations à l'informatique et à l'électronique

Auteur : SD
Créé le : 24-09-2020

Langage C – Les fonctions

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.

Pour quoi faire ?

Comment créer une fonction ?

Première étape : déclaration de la fonction (prototype)

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 :

Deuxième étape : écriture du corps de la fonction

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 :

Dernière étape : utiliser la fonction

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".

Les paramètres

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.

Le prototype sera donc :

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".

Le code de la fonction sera :

void affichePrixTTC(float prixHT, float tva) {
printf("Le prix TTC est : %.2f", prixHT * (1 + tva / 100));
}

On peut voir ici que :

Utilisation de la fonction :

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".

Valeur de retour

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.

Le prototype sera donc :

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".

Le code de la fonction sera :

float calculPrixTTC(float prixHT, float tva) {
float prixTTC;

prixTTC = prixHT * (1 + tva / 100);
return prixTTC;
}

On peut voir ici que :

Utilisation de la fonction :

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);
}

Passage de paramètres par pointeur

Pourquoi passer des paramètres par pointeur ?

Nous avons 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.

C’est quoi un pointeur ?

Un pointeur est une variable qui contient l’adresse d’une autre variable :

c'est quoi un pointeur

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.

Le prototype sera donc :

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".

Le code de la fonction sera :

void echange(int* nb1, int* nb2) {
int temp;

temp = *nb1;
*nb1 = *nb2;
*nb2 = temp;
}

On peut voir ici que :

Utilisation de la fonction :

int main() {
int valeur1 = 120;
int valeur2 = 200;

echange(&valeur1, &valeur2); // Suite à l’exécution de la fonction, valeur1 = 200 et valeur2 = 120
}

Fonctions et tableaux

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.

Le prototype sera donc :

void fillTabWithZero(int tab[], int size);
ou
void echange(int* tab, int size);

Ceci indique que la fonction va recevoir un paramètre de type pointeur sur un tableau d’entiers dont le nom est "tab" et un second paramètre de type entier dont le nom est "size".

Le code de la fonction sera :

void fillTabWithZero(int tab[], int size) {
int i;

for(i = 0 ; i < size ; i++)
tab[i] = 0;
}

Utilisation de la fonction :

int main() {
int tabEntiers[200];

fillTabWithZero(tabEntiers, 200);
}

Articles connexes

Testez vos connaissances en langage C


Vous avez apprécié cet article ? Partagez le !

Article connexe : Les structures algorithmiques de base