les fonctions en C

25 Aug 2019 25 Aug 2019 9750 vues ESSADDOUKI Mostafa 8 min de lecture

Les fonctions en langage C

Une fonction est un ensemble d'instructions qui réalise une tâche précise. Elle peut recevoir des entrées (appelées paramètres), effectuer des calculs et produire une valeur de sortie. L'idée principale consiste à regrouper des instructions utilisées fréquemment dans un même bloc afin d'éviter de répéter plusieurs fois le même code.

Définition — Fonction Une fonction est un bloc de code identifié par un nom, qui peut recevoir des paramètres et éventuellement retourner une valeur. Elle constitue l'unité de base de la modularité en C.
AvantageDescription
Réduction de la redondanceUne opération répétée est codée une seule fois et appelée autant que nécessaire
Maintenance simplifiéeUne modification ne s'effectue qu'à un seul endroit dans le code
Organisation modulaireUn programme complexe est découpé en modules simples et indépendants
RéutilisabilitéUne fonction bien écrite peut être réutilisée dans d'autres projets
À retenir Un programme bien structuré utilise plusieurs fonctions afin d'améliorer la lisibilité et la maintenance du code. La fonction main() est le point d'entrée obligatoire de tout programme C.

1. Déclaration et définition

En C, une fonction possède deux étapes distinctes : la déclaration (prototype) qui informe le compilateur de la signature, et la définition qui fournit le corps de la fonction.


Syntaxe — Déclaration et définition C
/* Déclaration (prototype) — avant main() */
type_retour nom_fonction(type1 param1, type2 param2);

/* Définition — corps complet */
type_retour nom_fonction(type1 param1, type2 param2)
{
    /* instructions */
    return valeur;   // si type_retour != void
}
ÉlémentRôleExemple
Type de retourType de la valeur retournée (void si aucune)int, float, void
NomIdentifiant appelé dans le codesomme, Max, afficher
Paramètres formelsVariables locales reçues lors de l'appelint a, int b
CorpsInstructions exécutées lors de l'appelEntre { et }
returnRetourne une valeur et quitte la fonctionreturn a + b;

Exemple n°1 — Fonction somme à deux entiers

#include <stdio.h>

/* Déclaration */
int somme(int a, int b);

int main()
{
    int a = 5, b = 3;
    int s = somme(a, b);
    printf("La somme est : %d\n", s);
    return 0;
}

/* Définition */
int somme(int a, int b)
{
    int c = a + b;
    return c;
}
Sortie
La somme est : 8

Exemple n°2 — Prototypes courants

float  somme(float, float);      // retourne un flottant
int    max(int, int);            // retourne le maximum
int   *echange(int *, int);      // retourne un pointeur
void   afficher(void);           // ne retourne rien, pas de paramètres

Exemple n°3 — Déclaration avant main(), définition après

#include <stdio.h>

int Min(int, int);   /* prototype — déclaration */

int main(void)
{
    int a = 2, b = 3;
    int i = Min(a, b);
    printf("Minimum = %d\n", i);
    return 0;
}

int Min(int i, int j)   /* définition */
{
    if (i < j)
        return i;
    else
        return j;
}
Sortie
Minimum = 2
Astuce — Déclaration vs définition Déclarer la fonction avant main() et la définir après est la pratique recommandée. Dans les projets réels, les prototypes sont placés dans un fichier d'en-tête (.h) et les définitions dans un fichier source (.c) :
// math_utils.h — prototypes
int somme(int, int);
int Min(int, int);

// math_utils.c — définitions
#include "math_utils.h"
int somme(int a, int b) { return a + b; }
int Min(int i, int j)   { return (i < j) ? i : j; }

2. Passage des paramètres

Lors d'un appel de fonction, les valeurs envoyées sont appelées paramètres réels (ou arguments) et les variables utilisées dans la fonction sont appelées paramètres formels. Il existe deux mécanismes principaux.

MécanismeCe qui est transmisVariable originale modifiée ?Syntaxe côté appel
Par valeurUne copie de la valeur❌ Nonf(x)
Par référence (pointeur)L'adresse de la variable✅ Ouif(&x)

a. Passage par valeur

Une copie de la variable est transmise à la fonction. Les modifications effectuées dans la fonction n'affectent pas la variable originale.

Exemple n°4 — Passage par valeur

#include <stdio.h>

void incremente(int i)
{
    i++;   // modifie la COPIE locale, pas j
    printf("i dans la fonction = %d\n", i);  // 13
}

int main()
{
    int j = 12;
    incremente(j);
    printf("j dans main = %d\n", j);  // j reste 12
    return 0;
}
Sortie
i dans la fonction = 13
j dans main = 12
Attention — Copie locale La variable j n'est pas modifiée car seule sa copie est passée à la fonction. Le paramètre formel i est une variable locale indépendante qui disparaît à la fin de la fonction.

b. Passage par référence (via pointeur)

En C, tous les paramètres sont techniquement passés par valeur. Pour simuler un passage par référence — et permettre à une fonction de modifier la variable originale — on passe l'adresse de la variable à l'aide de l'opérateur &, et on accède à sa valeur via l'opérateur de déréférencement *.


Syntaxe — Passage par pointeur C
/* Déclaration — paramètre pointeur */
void maFonction(int *p);

/* Appel — on passe l'adresse */
maFonction(&variable);

/* Dans la fonction — on déréférence */
(*p)++;      // modifie la variable originale
*p = 42;     // idem

Exemple n°5 — Passage par référence

#include <stdio.h>

void incremente(int *i)
{
    (*i)++;   // modifie la valeur à l'adresse reçue
}

int main()
{
    int j = 12;
    incremente(&j);   // on passe l'adresse de j
    printf("j = %d\n", j);   // j a été modifié
    return 0;
}
Sortie
j = 13
Explication — Opérateurs & et *
  • &j — retourne l'adresse mémoire de j
  • int *i — déclare un pointeur vers un entier
  • *idéréférence le pointeur : accède à la valeur stockée à cette adresse
  • (*i)++ — incrémente la valeur pointée (les parenthèses sont nécessaires car * et ++ ont la même priorité)

Exemple n°6 — Échange de deux variables via pointeurs

#include <stdio.h>

void echanger(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main()
{
    int x = 10, y = 20;
    printf("Avant : x = %d, y = %d\n", x, y);
    echanger(&x, &y);
    printf("Après : x = %d, y = %d\n", x, y);
    return 0;
}
Sortie
Avant : x = 10, y = 20
Après : x = 20, y = 10
Danger — Oublier les parenthèses sur (*p)++ Sans parenthèses, *p++ incrémente le pointeur(il pointe vers la case mémoire suivante) et non la valeur pointée — résultat indéfini et source de bugs difficiles à détecter :
(*p)++   // ✅ incrémente la VALEUR à l'adresse pointée
*p++     // ❌ incrémente le POINTEUR (comportement non voulu)

3. Points importants à retenir

RègleDétailExemple
Fonction principaleTout programme C possède une fonction main()int main(void) { ... }
Type voidAucune valeur retournée / aucun paramètrevoid afficher(void);
Pas de tableau en retourUne fonction ne peut pas retourner un tableau directementRetourner un int * (pointeur)
Déclarer avant usageSans déclaration, le compilateur suppose int f()Toujours écrire le prototype
Fichiers séparésPrototypes dans .h, définitions dans .c#include "utils.h"
Conseil pratique — Organisation des fichiers Dans les programmes réels, les fonctions sont déclarées dans des fichiers d'en-tête (.h) et définies dans des fichiers source (.c). Cette séparation facilite la compilation modulaire et la réutilisation :
// utils.h
#ifndef UTILS_H
#define UTILS_H
int somme(int, int);
int Min(int, int);
void echanger(int *, int *);
#endif

// utils.c
#include "utils.h"
int somme(int a, int b) { return a + b; }

// main.c
#include <stdio.h>
#include "utils.h"
int main() { ... }

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.