Notions de bases en C

Programmation multi fichiers et classes d’allocations des variables :

En général, les projets informatiques de grande taille comportent plusieurs fichiers sources (extension .c en langage C) ayant chacun une ou plusieurs fonctions. Cela entraîne une gestion des variables entre les différents fichiers et au sein d’un fichier.

Classes d’allocations des variables :

La portée d’une variable détermine la zone du programme dans laquelle elle est valable ;  sa durée de vie est la durée pendant laquelle elle conservera la valeur qu’elle stocke.

Ces deux notions, portée et durée de validité dépendent de la classe d’allocation de la variable. On distingue :

  • des variables automatiques ;
  • des variables statiques ;
  • des variables externes ;
  • des variables de registres.

Variables locales et classe d’allocation automatique : auto

Les variables locales sont déclarées à l’intérieur d’une fonction; les emplacements mémoire correspondants sont alloués chaque fois que la fonction est appelée, et détruits lorsqu’on en sort.

Les variables locales sont pour ainsi dire de classe « automatiques » (automatic).

Exemple :

int baar(int x, int y)
{
      int a, b ;
      …
}

Les variables x, y , a et b sont automatiques.

Le mot clé « auto », utilisé pour déclarer une variable automatique, est très rarement utilisé pour une bonne partie des compilateurs ; (il faudra se référer à la documentation du compilateur utilisé).

Variables globales – variables locales et classe d’allocation statique : static

La classe d’allocation statique alloue les emplacements mémoire de façon permanente, pendant toute la durée de vie du programme ; ces emplacements sont crées lorsque le programme démarre son exécution, puis ils sont détruits lorsque l’exécution du programme se termine.

Les variables globales sont implicitement statiques.

Exemple :

int a ;

int main(void)
{
    …
}

La variable globale a est de classe statique.

Pour déclarer une variable statique il faut ajouter le mot clé « static » au début de sa déclaration.

Exemple :

static int a ;

Dans une fonction, une variable locale déclarée comme statique, conserve la valeur qu'elle aurait prise au dernier appel de cette fonction.

Exemple :

int baar(int x)
{
    static int a = 0 ;
    …
    a *= x ;
    return a ;
}

La variable a va conserver la valeur qu’elle avait lors du précédent appel de la fonction baar().  Même si la variable a avait une valeur initiale, celle-ci n’existera qu'au moment de sa création.

Variable de classe externe : extern

Dans des environnements de développement informatique, la notion de projet permet de gérer plusieurs programmes sources qui interviennent dans la création d’un exécutable.

Nous allons supposer que chaque programme figure dans fichier.

Si les variables globales sont créées dans certains fichiers, leur portée est limitée au fichier dans lequel elles sont définies. En cas de besoins ces variables peuvent être déclarées au-delà de leur champ de validité dans un autre programme, à l’aide du mot clé extern.

Syntaxe :

extern type identificateur ;

Exemple :

fichier 1 fichier 2
int x ;
int fexple1(int a)
{
    …
}

int main(void)
{
     …
}

int fexple2()
{
    …
}

int fexple3()
{
    …
}

 

A l’état actuel, il n’est pas possible de faire référence à la variable globale x dans les fonctions fexple2() et fexple3() du fichier 2.

Le mot clé extern permet de spécifier qu’une variable a déjà été déclarée dans un autre fichier source. Ainsi le fichier 2 devrait avoir l’allure suivante pour que les fonctions fexple2() et fexple3() puissent utiliser la variable globale x :

extern int x ;
int fexple2()
{
    …
}

int fexple3()
{
    …
}

L’espace mémoire de la variable est alloué uniquement au moment de sa définition et non par le mot clé extern.

Variable de classe registre : register

La classe register met à contribution les registres du microprocesseur pour la réservation d’espace dans le but d’améliorer la vitesse d’exécution des instructions ;  au lieu d’effectuer les mêmes actions dans les mémoires RAM externes.

Mais cette classe d’allocation n’a aucun sens dans un système embarqué où un microcontrôleur est utilisé ; la mémoire RAM étant interne pour ce type de composants.

Portée d’une fonction :

La portée d’une fonction dépend de sa classe d’allocation. On distingue:

  • des fonctions de portée statique (static)
  • des fonctions de portée externe (extern)

Une fonction dont la déclaration est « static » a une portée locale, c’est-à-dire valable uniquement pour le fichier dans lequel elle est déclarée. Une déclaration « extern » a une portée globale, dans ce cas la fonction est valable pour tous les fichiers du projet.

Dans l'exemple illustré par la figure ci-dessous, le fichier expleLib.c représente n'importe quel fichier source (.c) qui se trouve dans une librairie, comme les librairies du compilateur ou des librairies personnelles. Un fichier en-tête (.h) contient les déclarations de variables externes et des prototypes de fonctions qui peuvent être nécessaires pour n'importe quel programme ayant besoin d'accéder aux variables et aux fonctions contenues dans le fichier librairie (expleLib.c). Donc il suffit d'inclure le fichier expleLib.h dans main.c, puis d'ajouter la librairie expleLib.c au projet, pour que le programme main.c puisse accéder aux variables déclarées dans expleLib.h et aux fonctions de expleLib.c.

exple files interactions 2 

Une librairie de fichiers permet de réutiliser des programmes autant de fois qu'on le souhaite. Un projet multi fichiers amène plus de souplesse dans la programmation en C.