Les classes de stockage en langage C

20 Sep 2019 20 Sep 2019 6911 vues ESSADDOUKI Mostafa 7 min de lecture

Classes de stockage en C

Classe de stockage Une classe de stockage est un attribut d'une variable qui précise, au-delà de son type et de sa valeur : sa portée (qui peut y accéder), son emplacement mémoire (pile, segment de données, registre CPU), sa valeur initiale et sa durée de vie (quand elle est créée et détruite).

Tableau des 4 classes de stockage en C : auto, extern, static, register

ClasseMot-cléPortéeEmplacement mémoireDurée de vieValeur initiale
AutomatiqueautoBloc localPile (stack)Durée du blocIndéfinie (garbage)
ExterneexternTout le programme (multi-fichiers)Segment de donnéesDurée du programme0 / NULL
StatiquestaticBloc local ou fichierSegment de donnéesDurée du programme0 (une seule fois)
RegistreregisterBloc localRegistre CPU (si disponible)Durée du blocIndéfinie (garbage)

1. Classe automatique — auto

auto La classe auto est la classe par défaut de toute variable déclarée dans un bloc ou une fonction. Le mot-clé auto est optionnel (presque jamais écrit explicitement). La variable est créée à l'entrée du bloc et détruite à sa sortie.

Syntaxe C
auto int age;        /* explicite — rarement écrit */
int  age;            /* équivalent — classe auto implicite */

Exemple n°1 — Portée de blocs imbriqués avec auto

#include <stdio.h>

int main(void)
{
    auto int j = 1;           /* bloc 1 */
    {
        auto int j = 2;       /* bloc 2 — nouvelle variable j, masque le j du bloc 1 */
        {
            auto int j = 3;   /* bloc 3 — nouvelle variable j, masque les deux précédentes */
            printf("bloc 3 — j = %d\n", j);
        }                     /* j de bloc 3 détruite ici */
        printf("bloc 2 — j = %d\n", j);
    }                         /* j de bloc 2 détruite ici */
    printf("bloc 1 — j = %d\n", j);
    return 0;
}                             /* j de bloc 1 détruite ici */
Sortie
bloc 3 — j = 3
bloc 2 — j = 2
bloc 1 — j = 1

Chaque bloc possède sa propre variable j indépendante. À la sortie d'un bloc, la variable locale est détruite et la variable du bloc parent redevient visible.

auto est implicite En pratique, le mot-clé auto n'est jamais écrit en C moderne — toute variable locale est automatique par défaut. En C++11, auto a été réutilisé pour la déduction de type, ce qui est une signification complètement différente.

2. Classe externe — extern

extern Le mot-clé extern déclare qu'une variable ou une fonction est définie dans un autre fichier. Il permet de partager des données globales entre plusieurs fichiers source d'un même projet sans redéfinir la variable.

Syntaxe C
/* Fichier A — définition (une seule fois dans tout le projet) */
int compteur = 3;

/* Fichier B — déclaration (autant de fichiers que nécessaire) */
extern int compteur;   /* pas d'initialisation — la variable existe déjà dans A */

Exemple n°2 — Variable partagée entre deux fichiers

/* ───── main.c ───── */
#include <stdio.h>

int compteur;                   /* définition — mémoire allouée ici */
extern void methode_globale(void);

int main(void)
{
    compteur = 3;
    methode_globale();
    return 0;
}
/* ───── utilitaire.c ───── */
#include <stdio.h>

extern int compteur;            /* déclaration — pas de nouvelle allocation */

void methode_globale(void)
{
    printf("compteur est : %d\n", compteur);
}

Compilation multi-fichiers C
gcc main.c utilitaire.c -o main
./main
Sortie
compteur est : 3
Attention — Définition vs déclaration extern est une déclaration (annonce qu'une variable existe ailleurs) — pas une définition (pas d'allocation mémoire). Il ne faut jamais initialiser une variable extern:
extern int x = 5;   /* incorrect — extern + initialisation = redéfinition */
extern int x;       /* correct   — simple déclaration */

3. Classe statique — static

static Le mot-clé static a deux effets selon le contexte. Appliqué à une variable locale, il prolonge sa durée de vie à toute l'exécution du programme tout en conservant sa portée locale — la variable persiste entre les appels. Appliqué à une variable ou fonction globale, il restreint sa visibilité au fichier source courant.

Syntaxe C
static int compteur = 10;   /* variable statique — initialisée une seule fois */

Exemple n°3 — Variable locale statique qui persiste entre les appels

#include <stdio.h>

void func(void);

static int compteur = 3;   /* globale statique — visible dans ce fichier uniquement */

int main(void)
{
    while (compteur--) {
        func();
    }
    return 0;
}

void func(void)
{
    static int i = 5;   /* initialisée à 5 une seule fois — conserve sa valeur */
    i++;
    printf("i = %d  |  compteur = %d\n", i, compteur);
}
Sortie
i = 6  |  compteur = 2
i = 7  |  compteur = 1
i = 8  |  compteur = 0

La variable locale i conserve sa valeur (6, puis 7, puis 8) d'un appel à l'autre. Sans static, elle serait réinitialisée à 5 à chaque appel.

Exemple n°4 — Compteur d'appels avec variable statique

#include <stdio.h>

void compter_appels(void)
{
    static int nb = 0;   /* initialisée à 0 une seule fois */
    nb++;
    printf("Appel n°%d\n", nb);
}

int main(void)
{
    compter_appels();
    compter_appels();
    compter_appels();
    return 0;
}
Sortie
Appel n°1
Appel n°2
Appel n°3
Contexte de staticEffet sur la portéeEffet sur la durée de vie
Variable localeInchangée (bloc local)Prolongée à toute l'exécution
Variable globaleRestreinte au fichier courantToute l'exécution (déjà le cas)
FonctionRestreinte au fichier courant

4. Classe registre — register

register Le mot-clé register est un indice au compilateur pour stocker la variable dans un registre du processeur (plutôt que dans la RAM), ce qui accélère l'accès. C'est une suggestion — le compilateur peut l'ignorer si aucun registre n'est disponible.

Syntaxe C
register int compteur;   /* suggestion : stocker dans un registre CPU */

Exemple n°5 — Usage typique : compteur de boucle

#include <stdio.h>

int main(void)
{
    register int i;
    long somme = 0;

    for (i = 0; i < 1000000; i++) {
        somme += i;
    }

    printf("Somme = %ld\n", somme);
    return 0;
}
Danger — Impossible de prendre l'adresse d'une variable register Une variable register n'a pas d'emplacement en RAM — il est donc impossible d'obtenir son adresse avec l'opérateur &:
register int poids;
int *ptr = &poids;   /* ERREUR — address of register variable requested */
Attention — register est obsolète en C11 Depuis C11, le mot-clé register est déprécié. Les compilateurs modernes (GCC, Clang) optimisent l'usage des registres bien mieux que le programmeur ne peut le faire manuellement. En pratique, register n'est plus utilisé dans le code moderne.

Récapitulatif

Critèreautoexternstaticregister
PortéeBloc localMulti-fichiersBloc local ou fichierBloc local
EmplacementPileSegment de donnéesSegment de donnéesRegistre CPU
Durée de vieDurée du blocDurée du programmeDurée du programmeDurée du bloc
Valeur initialeGarbage0 / NULL0 (une seule fois)Garbage
Opérateur &PermisPermisPermisNon permis
Usage typiqueVariables locales (défaut)Partage multi-fichiersPersistance entre appelsCompteurs (obsolète)

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.