Table des matières

Fonctions

Exemple simple

#include <stdio.h>
#include <stdlib.h>

int plus(int a, int b){
    return a + b;
}

int main() {
    int y = 4;
    int x = plus(y, 18);
    printf("%d\n", x);
    return 0;
}
ligne 4, signature

En ligne 4, on a défini une fonction plus c'est la signature de la fonction.

ligne 5, retour

Puisque la fonction a un retour de type int, il est indispensable qu'elle renvoie un entier. Ici, elle renvoie la somme de a et b ce qui sera bien un entier.

ligne 10, appel de la fonction

La fonction plus est appelée avec les arguments :

Important : Pour permettre son exécution ligne 10, la fonction doit-être définie avant.

Il est possible de ne définir que la signature de la fonction et de ne donner le contenu que plus tard.

Les arguments ne sont pas modifiés

Prenons cet autre exemple :

#include <stdio.h>
#include <stdlib.h>

int add(int a, int b){
    a = a + b;
    return a;
}

int main() {
    int a = 5;
    int x = plus(a, 18);
    printf("%d\n", x);
    printf("%d\n", a);
    return 0;
}
Des variables différentes

Ligne 4 et ligne 10, on définit int a. Elles ont beau porter le même nom, ce sont deux variables différentes. L'affectaton ligne 13 a = a + b; n'a pas d'effet sur la variable a définie ligne 10.

Pour éviter les confusions, il est peut-être utile de changer de nom. On peut le faire ici dans le cadre de cette explication, mais c'est on ne peut pas toujours le faire : Dans un gros programme on a inévitablement des variables différentes portant le même nom. Le mécanisme dont on parle maintenant permet justement qu'elles vivent sans se perturber l'une l'autre.

#include <stdio.h>
#include <stdlib.h>

int add(int c, int b){
    c = c + b;
    return a;
}

int main() {
    int a = 5;
    int x = plus(a, 18);
    printf("%d\n", x);
    printf("%d\n", a);
    return 0;
}
Création d'une copie

Au moment de l'appel ligne 11 : int x = plus(a, 18);, on lance la fonction définie ligne 4 par int add(int c, int b){. Cela signifie qu'à son lancement, la fonction add initialise une nouvelle variable c dans laquelle il recopie la valeur qu'on lui fournit, ici le contenu de a.

Donc c est initialisé comme copie de a.

Quand on modifie c en ligne 5, cela n'a donc pas d'effet sur a.

Portée - scope

Quand on définit une variable, elle a une certaine portée. La portée est définie par les fonctions.

Dans le cas précédent, c n'existe que le temps de l'exécution de la fonction plus. Un appelle à la variable c en dehors de la fonction plus provoque une erreur.

Dès que la fonction se termine, l'espace mémoire alloué à c est libéré. La variable n'existe plus.

C'est vrai aussi des variables définies dans main : a et x sont définies dans main et sont inaccessibles depuis plus. Le seul moyen de les mettre en relation est d'utiliser les entrées - sorties de la fonction : En mettant a comme argument de plus, plus va travailler sur une copie de la valeur de a. À l'autre bout, x reçoit le résultat de l'exécution de plus. C'est la seule interaction possible.

On verra que l'on peut aller plus loin avec les pointeurs mais ce principe général reste valable.

Variable globale

Si une variable est définie en dehors des fonctions, elle peut être atteinte de façon globale. Voyons un exemple :

#include <stdio.h>
#include <stdlib.h>

int a = 25;

void change_a(){
    a = a + 1;
}

int main() {
    printf("%d\n",a);
    change_a();
    printf("%d\n",a);
    return 0;
}

La variable a définie ligne 4 a une portée globale. Lors de l'exécution de change_a, en ligne 7, c'est bien ce a global qui est modifié et dans les affichages lignes 11 et 13, c'est toujours le même a.

Modifier un argument

Supposons que l'on veuille modifier un argument (c'est souvent utile, par exemple : tri(tableau), il peut être utile que tri modifie le contenu de tableau.

Avec pointeurs

La méthode consiste à ne pas transmettre la variable elle-même comme argument mais l'adresse de la variable de façon à ce que la fonction agisse directement sur la case mémoire contenant la variable. Cela correspond aux pointeurs.

#include <stdio.h>
#include <stdlib.h>
 
void change(int *a){
    *a = *a + 1;
}
 
int main() {
    int x = 13;
    printf("%d\n",x);
    change(&x);
    printf("%d\n",x);
    return 0;
}
La version C++

En C++ on peut utiliser & qui est appelé dans ce cas ampersed (utile à savoir si vous devez faire une recherche !)

Cette méthode fonctionne sur C playground puisque le compilateur utilisé sur ce site est un compilateur C++.
#include <stdio.h>
#include <stdlib.h>

void change(int &a){
    a = a + 1;
}

int main() {
    int x = 13;
    printf("%d\n",x);
    change(x);
    printf("%d\n",x);
    return 0;
}

En ligne 4, dans la définition de change, l'argument a est précédé de &. Ce symbole indique que la variable est passée par référence. Je vais expliciter le mot ci-dessous.

Voyons l'exécution pour bien comprendre :