next up previous contents index
Next: La fonction main Up: No Title Previous: Types

Nom, expression, instruction / valeur, objet, adresse

    

Un programme est une suite de définitions. Une définition introduit un nouveau nom , qu'il sera possible d'utiliser par la suite, déclare son type, l'installe dans la mémoire et éventuellement l'initialise. Voici les définitions de deux noms de variable de type int, a et b, la seconde étant initialisée, d'un nom de tableau t, de type << tableau de 10 caractères >>, et d'un nom de fonction f :

int a;
int b = 4;
char t[10];
int f(int x) { return x*x; }

Ces noms vont servir à construire des  expressions , autre notion syntaxique : on trouvera en C des expressions arithmétiques (par exemple, a - 2*b), des expressions logiques (comme a<b/2 || a>=b), des affectations (comme a = b+1), des appels de fonction (comme f(a+b)), et bien d'autres, qui seront présentées ultérieurement (C est un langage très riche en expressions).

 

Ces expressions sont destinées à être évaluées, c'est-à-dire à produire une  valeur : 2+3 a pour valeur 5.

En particulier, un nom de variable est une expression dont la valeur doit être cherchée en mémoire, là où cette variable a été installée : pour évaluer b+1, il faut évaluer la variable b, donc savoir où b est rangée en mémoire, ce qui est déterminé par l'adresse   de b.

Quand la définition d'une variable ne comporte pas d'initialisation, elle ne devra pas être utilisée tant qu'une valeur ne lui aura pas été affectée. Faute d'une   initialisation, la mémoire attribuée à une variable peut contenir des valeurs qui proviennent d'une autre utilisation de cette partie de la mémoire. Cette erreur de programmation est assez fréquente : on ne doit pas faire de la cuisine avec des détritus !

Pour évaluer une affectation  , comme a = 2+3, la position de a à gauche de l'affectation fait que ce n'est pas la valeur de a qui doit être utilisée, mais son adresse. L'expression qui figure à droite du signe = est évaluée, puis la valeur obtenue, ici 5, est copiée << dans >> a. Ainsi un nom de variable a à la fois une valeur et une adresse, l'un ou l'autre étant utilisé selon la position du nom dans une expression.

D'autres expressions peuvent être placées à gauche d'une affectation, de façon analogue aux noms de variable ; on en verra des exemples avec des tableaux, des structures et des pointeurs. Plus généralement, certaines expressions ont une adresse : on dit que ces expressions désignent des objets . Soulignons que ce n'est pas le cas de toutes : 2+3 a une valeur, mais pas d'adresse (la valeur, 5, n'est pas non plus un objet). Il faut distinguer valeur et objet : quand on définit

  int b = 4;
  int c = b;

les expressions b et c ont la même valeur, qui est l'entier 4. Par contre b et c désignent des objets différents, au sens où ils occupent des zones différentes de la mémoire. C'est la valeur de b qui est copiée dans la zone mémoire attribuée à c.

Un objet   a une existence dans l'espace et dans le temps. Dans l'espace, c'est une zone mémoire qui a été attribuée par allocation  , dans le temps c'est la durée de vie, qui s'étend de l'allocation à la dés-allocation de cette zone mémoire. Il y a trois modes d'allocation d'un objet : statique, automatique, et dynamique. Pendant sa durée de vie, un objet a une adresse. Les objets ayant une allocation statique ou automatique sont désignés par un nom ; ceux ayant une allocation dynamique sont anonymes (mais peuvent être désignés par des expressions).

La mémoire  peut être vue comme un tableau, à une dimension, dont les éléments sont des octets   (c'est-à-dire des suites de 8 bits) ; chaque élément de ce tableau est indexé par une adresse . La figure 2 donne un aperçu d'une mémoire qui contiendrait trois objets de tailles différentes : le premier occupe un octet (probablement un objet de type char), le second occupe 8 octets (c'est peut-être un double, ou un tableau de deux float, etc), le troisième occupe 4 octets (peut-être un int, ou un tableau de quatre char, etc). Les octets entre ces objets ne sont pas alloués, mais contiennent des détritus provenant d'utilisations précédentes de la mémoire.


  
Figure 2: Un aperçu de la mémoire
\begin{figure}
 \begin{center}
 \leavevmode
 
\fbox {
 \epsfig{file=fig/memoire.eps}
 }
 \end{center} \end{figure}

   

Enfin, les expressions servent à construire des instructions (en anglais statement ), autre notion syntaxique importante dont le rôle est d'opérer sur la mémoire et de contrôler l'exécution du programme. Celles-ci ne peuvent figurer que dans le corps d'une fonction. Une  instruction est soit une instruction simple, soit une instruction composée.

Toute expression suivie d'un << ; >> est une instruction simple ; notamment, une affectation suivie d'un << ; >> est une instruction ; un << return >> suivi d'une expression et d'un << ; >> est aussi une instruction simple.

Les instructions conditionnelles (if, switch), par exemple

    if (v <= f(u)) {
      k = k+1;
    }

et les instructions d'itération (for, while), par exemple

  for (i=1; i<=N; i++) {
    somme = somme + i;
  }

sont des instructions composées. Un bloc  , formé d'une suite de déclarations, puis d'une suite d'instructions, et encadré par << { >> et << } >> est aussi une instruction composée ; le bloc suivant est formé des définitions de u et de v et d'une instruction conditionnelle :

  {
    double u = drand48();
    double v = drand48();

    if (v <= f(u)) {
      k = k+1;
    }
  }

Le corps d'une fonction est un bloc.


next up previous contents index
Next: La fonction main Up: No Title Previous: Types
Jean-Philippe Chancelier
9/29/1998