Glossaire langage C

Glossaire langage C


Dernière mise à jour : 2 janvier 2011

Affectation

Blocs (ou instructions composées)

    --> cat bloc.c
    #include <stdio.h>
    #include <stdlib.h>
    int main( )
    { // début du bloc 1
       int a = 1;
       { // début du bloc 1.1
          printf("%d\n", a);
          int a = 10;
          printf("%d\n", a);
          { // début du bloc 1.1.1
             printf("%d\n", a);
             int a = 100;
             printf("%d\n", a);
             a ++;
             printf("%d\n", a);
          } // fin du bloc 1.1.1
          a ++;
          printf("%d\n", a);
       } // fin du bloc 1.1
       { // début du bloc 1.2
          printf("%d\n", a);
          int a = 1000;
          printf("%d\n", a);
          a ++;
          printf("%d\n", a);
       } // fin du bloc 1.2
       printf("%d\n", a);
       return EXIT_SUCCESS; // return 0
    } // fin du bloc 1

L'exécution de ce programme fournit les résultats suivants :


    --> ./bloc
    1
    10
    10
    100
    101
    11
    1
    1000
    1001
    1

break

Comparaison (opérateurs relationnels)

Ces opérateurs permettent de comparer des valeurs numériques ou des pointeurs :

const


    const int a = 1;
    int const b = 2;

De telles définitions de m et n entrainent une erreur lors de la compilation pour des tentatives de modification des valeurs de ces variables :

    a ++; // error: increment of read-only variable 'a'
    b = 2; // error: assignment of read-only variable 'b'

Si les deux écritures sont équivalentes dans le cas de variables de type classique (types de base, structures ou unions), les choses sont un peu différentes dans le cas de la définition de variables de type pointeur :

int a, b;
int * const ptr = &a;
Le fait que ptr soit constant, interdit dans la suite du programme toute instruction modifiant le pointeur :
ptr = &b; // erreur de compilation: assignment of read-only variable 'ptr'

    int a, b;
    int const * ptr = &a;

Le fait que l'espace pointé par ptr soit déclaré constant, interdit dans la suite du programme l'instruction

*ptr = 12; // erreur de compilation: assignment of read-only location
Il est intéressant d'observer ce qui se passe dans la séquence suivante : un simple avertissement (warning) signale que le pointeur référence une variable qualifiée const, ce que la définition du pointeur ne spécifie pas :
int const a;
int *ptr=&a; // warning:initialization discards qualifiers from pointer target type
Un exécutable est donc produit. L'exécution de l'instruction suivante, qui modifie indirectement la variable supposée constante n'a donné lieu à aucune erreur (mais un tel comportement non souhaitable n'est pas garanti sur tout système et risque de conduire sur certains à un arrêt brutal de l'exécution pour violation mémoire) :
*ptr = 1000;
printf("%d\n", a);

continue

Cela signifie que:

Décrémentations (autodécrémentations)

L'opérateur -- est un opérateur unaire (un argument) applicable à un argument adressable (Lvalue).
C'est un opérateur à effet de bord (modifiant la valeur de l'espace mémoire correspondant à son argument) qui est utilisable sous deux formes :

do ... while

do
  {
     suite_instructions
    }
while (expression)

Effet de bord

On parle d'effet de bord dans le cas d'un opérateur (par exemple =, ++ ou -=) modifiant l'un de ses opérandes ou d'une fonction qui modifie la valeur d'une variable globale ou d'une zone pointée par un de ses paramètres.

Expressions composées

L'opérateur « , » permet de composer deux expressions.

Ainsi, une expression de la forme

         exp1,exp2

est une expression dont l'évaluation entraîne successivement :

Ainsi l'évaluation de l'expression

         x = (y = 4, z = 2 * y)

entraîne l'évaluation successive des expressions

Expressions conditionnelles

         exp1?exp2:exp3

dont l'évaluation est la suivante :


        (a > 5) ? ((b <= 150) ? 3.25 : 9) : -13.0

a pour valeur 3.25.

Fonctions

Définition de fonction

La définition d'une fonction est constituée de

Une seule définition peut être attachée à un nom de fonction. Il n'y a pas la possibilité, comme en C++ ou Java, de donner plusieurs définitions de fonctions sous le même nom mais différant par leur signature (nombre ou type des paramètres).

Appel de fonction

L'évaluation et la transmission des paramètres depuis le module appelant vers le module appelé possèdent les propriét&eacutes importantes suivantes :

Cela signifie qu'il faut bannir les effets de bord dans les expressions utilisées dans les paramètres d'appel des fonctions.
 

Cela signifie que pour chacun des paramètres, une variable locale (portant le nom du paramètre formel) est créée sur la pile. Cette variable est initialisée avec la valeur du paramètre d'appel correspondant.

Prototype d'une fonction (déclaration d'une fonction)

Le prototype d'une fonction doit normalement être décrit avant sa première utilisation (voir cependant la remarque).

Un tel prototype permet au compilateur de « vérifier » que l'utilisation de la fonction est conforme à sa définition.


Il est suivi d'un point virgule et non du corps de la fonction (contenant les instructions à exécuter), et ne nomme pas a priori les paramètres (s'il en contient nous parlerons de prototype étendu).

Ce petit exemple illustre ce que nous venons de dire :
    --> cat prototype.c
    #include <stdio.h>
    #include <stdlib.h>
    void g(void){
       printf("Bonjour\n"); 
    }
    int main( ) {
       float x = f(3, 5);
       g(3);
       printf("%f\n", x);
       return EXIT_SUCCESS;
    }
    int f(int x, int y, int z){
       return x + y + z;
    }
    --> gcc prototype.c
    prototype.c: In function 'main':
    prototype.c:6: warning: implicit declaration of function 'f'
    prototype.c:7: error: too many arguments to function 'g'
    -->

    /* deux paramètres de type int et retour d'un int */
    int somme(int, int);
    /* un paramètre de type size_t et retour d'un pointeur sur char */
    void *malloc (size_t);
   

for

for(exp_initialisation; exp_condition; exp_modification)
    instruction

dans laquelle :

? Une telle boucle est équivalente à la boucle while suivante :

exp_initialisation;
while(exp_condition)
   {
        instruction
        exp_modification;
   }

Identificateur

if

Il s'agit d'une structure de contrôle permettant de réaliser des tests et d'exécuter des instructions ou blocs différents selon la valeur de ces tests.
Dans ce qui suit instruction désigne soit une instruction simple, soit un bloc (délimité par des accolades) et expression désigne une expression quelconque dont on considérera la valeur logique déduite de sa valeur..

if (expression)
    instruction

L'instruction n'est exécutée que si la valeur logique de l'expression est vraie

if (expression)
    instruction1
else
    instruction2

L'expression est évaluée : si sa valeur logique est vraie, l'instruction1 est exécutée et sinon c'est l'instruction2 qui est exécutée.

Dans la séquence suivante, les if et else de même couleur sont associés :

if(a)
     if(b)
         x = 3;
     else if(c)
            x = 4;
          else {
              if(d)
                  x = 5;
               }
else
     x = 6;

Incrémentations (autoincrémentations)

L'opérateur ++ est un opérateur unaire (un argument) applicable à un argument adressable (Lvalue).
C'est un opérateur à effet de bord (modifiant la valeur de l'espace mémoire correspondant à son argument) qui est utilisable sous deux formes :

Instructions élémentaires (ou simples)

Toute instruction élémentaire se déduit d'une expression en lui ajoutant le caractère « ; »


Le caractère « ; » fait donc partie de l'instruction et en marque la terminaison.
Ce n'est pas, comme c'est le cas dans d'autres langages (Pascal par exemple), un opérateur de composition ou un séparateur d'instructions.

Remarque : une instruction telle que « i + 1; » est correcte mais ne fait rien puisqu'elle ne modifie rien en mémoire (pas d'effet de bord).

Instruction vide

L'instruction « ; » réduite à un point virgule est l'instruction vide. Elle est utilisable par exemple comme corps de boucle ou dans une instruction conditionnelle en partie if ou else.

main

La fonction main constitue le « point d'entrée » dans un binaire exécutable, c'est-à-dire qu'au lancement du programme, c'est cette fonction qui est automatiquement appelée.

Ainsi :

Arguments/paramètres de la fonction main : la fonction est normalement appelée sous deux formes (c'est ce qu'attend par exemple le compilatuer gcc) :

Consultation d'un programme parcourant les paramètres.

Opérateurs logiques (booléens)

Ils permettent de composer de composer les valeurs logiques d'expression et par là de réaliser des tests généraux.

Quatre opérateurs sont disponibles :

Priorité des opérateurs

Il existe 15 niveaux de priorité.

Pour chaque niveau, l'associativité est réalisée de gauche à droite ou de droite à gauche comme indiqué.
A titre d'exemple, l'associativité des opérateurs arithmétiques additifs est réalisée de gauche à droite et ces opérateurs sont moins prioritaires que les opérateurs arithmétiques mutiplicatifs.
Cela signifie que l'expression
        3-4+5*6-7-8+1
est évaluée comme
       (((((3-4)+(5*6))-7)-8)+1)
et a donc 16 comme valeur.

L'associativité des opérateurs d'affectation étant de droite à gauche et l'addition étant prioritaire par rapport aux affectations, l'expression
        a=b+=b*=c=2+b
est évaluée comme
        a=(b+=(b*=(c=(2+b))))
Si b vaut initialement 3, après évaluation de cette expression, les nouvelles valeurs des variables a, b et c sont respectivement (par effet de bord) 30, 30 et 5.

Premier niveau : indexation, fonction, structure

Opérateur

Notation

Exemples

Associativité

indexation

[ ]

t[i][j]

de gauche à droite

accès aux champs

.  ->  

c.champ    pointeur->champ

de gauche à droite

appel de fonction

( )

f(a, b, 3)

de gauche à droite

Deuxième niveau : opérateurs unaires

Opérateur

Notation

Exemples

Associativité

négation logique

!

!(x == 4)    !x

de droite à gauche

négation bit à bit

˜

˜ent    !x

de droite à gauche

incrémentation

++

++x    x++

de droite à gauche

décrémentation

--

--x    x--

de droite à gauche

moins unaire

-

-(x + 1)

de droite à gauche

coercition (cast)

(type)

(char *)    (float)

de droite à gauche

taille

sizeof

sizeof(int)    sizeof(n)

de droite à gauche

référencement (adresse de)

&

&n

de droite à gauche

déréférencement (valeur pointée)

*

*ptr

de droite à gauche

Troisième niveau : opérateurs arithmétiques multiplicatifs

Opérateur

Notation

Exemples

Associativité

mutiplication

*

5 * x

de gauche à droite

division

/

x / y

de gauche à droite

modulo

%

x % 5

de gauche à droite

Quatrème niveau : opérateurs arithmétiques additifs

Opérateur

Notation

Exemples

Associativité

addition

+

x + 8

de gauche à droite

soustraction

-

a - b

de gauche à droite

Cinquième niveau : opérateurs de décalage

Opérateur

Notation

Exemples

Associativité

décalage à gauche

<<

a << 4

de gauche à droite

décalage à droite

>>

x >> n

de gauche à droite

Sixième niveau : opérateurs relationnels (plus grand et plus petit)

Opérateur

Notation

Exemples

Associativité

plus grand

>

a > b

de gauche à droite

plus grand ou égal

>=

a >= 5

de gauche à droite

plus petit

<

y < a

de gauche à droite

plus petit ou égal

<=

a <= b

de gauche à droite

Septième niveau : opérateurs relationnels (égal, différent)

Opérateur

Notation

Exemples

Associativité

égalité

==

(x + 1) == (y + 2)

de gauche à droite

négalité

!=

z != 5

de gauche à droite

Huitième niveau : ET bit à bit

Opérateur

Notation

Exemples

Associativité

ET bit à bit

&

x & 0x3456AF01

de gauche à droite

Neuvième niveau : XOR bit à bit (OU exclusif)

Opérateur

Notation

Exemples

Associativité

XOR bit à bit

^

x ^ y

de gauche à droite

Dixième niveau : OU bit à bit (OU exclusif)

Opérateur

Notation

Exemples

Associativité

OU bit à bit

|

x | 0234

de gauche à droite

Onzième niveau : ET logique

Opérateur

Notation

Exemples

Associativité

conjonction logique (ET)

&&

a > b) && (z < 5)

de gauche à droite

Douzième niveau : OU logique

Opérateur

Notation

Exemples

Associativité

disjonction logique (OU)

||

(a != 0) || (b / a > 5)

de gauche à droite

Treizième niveau : expression conditionnelle

Opérateur

Notation

Exemples

Associativité

expression conditionnelle

?  :

(x>0)?x:-x

de droite à gauche

Quatorzième niveau : affectations

Opérateur

Notation

Exemples

Associativité

affectation simple

=

a = 5

de droite à gauche

affectations étendues (arithmétiques)

+=  -=  *=  /=  %=

a+=5  a*=(b+1)

de droite à gauche

affectations étendues (opérations bit à bit)

&=  ^=  |=

a&=b  a^=0x789A

de droite à gauche

affectations étendues (décalages)

<<=  >>=

a<<=5

de droite à gauche

Quinzième niveau : composition d'instructions

Opérateur

Notation

Exemples

Associativité

composition d'instructions

,

a=2,b=a+3,z+=5

de gauche à droite

switch

Souvent appelée aiguillage, cette structure permet, après évaluation d'une expression, de « se brancher » (et donc d'y poursuivre l'exécution) en un point (une étiquette) correspondant à la valeur de l'expression.

La syntaxe de la structure switch est la suivante (chaque suite_instructions peut éventuellement être vide et consiste sinon en la concaténation d'instructions, dont l'instruction « break; ») :

    switch ( expression_entière )
       {
         case constante1 : suite_instructions1
         case constante2 : suite_instructions2
              ........
         case constanteN : suite_instructionsN
         default : suite_instructions
       }
    // point de reprise d'exécution en cas de break dans le switch

La dernière alternative, notée default correspond au cas par défaut (si la valeur de l'expression ne correspond à aucun des cas prévus).
Elle est facultative. Cependant, pour des raisons de lisibilité des programmes, son usage est conseillé, quitte à lui associer une liste d'instructions vide;

Les étiquettes de chacun des cas sont des expressions constantes (que le compilateur doit donc pouvoir calculer).

la sémantique de cette structure de contrôle est la suivante :

un exemple utilisant un switch pour imprimer un message différent selon la nature du caractère contrôlant l'instruction :

    switch(c) {
        case 'A': case 'E': case 'I': case 'O': case 'U': case 'Y':
           printf("Le caractere lu est une voyelle\n");
           break;
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
           printf("Le caractere lu est un chiffre\n");
           break;
        case 'B': case 'C': case 'D': case 'F': case 'G':
        case 'H': case 'J': case 'K': case 'L': case 'M':
        case 'N': case 'P': case 'Q': case 'R': case 'S':
        case 'T': case 'V': case 'W': case 'X': case 'Z':
           printf("Le caractere lu est une consonne\n");
           break;
        default :
           printf("Le caractere lu n'est ni une lettre, ni un chiffre\n");
           // break;
    }

Le type void

Il a été introduit avec la norme ANSI du langage pour :


Le type void est un type incomplet (de taille non définie) : il correspondant à une absence de type et par suite :

    --> cat essai.c
    int main(){void a; }
    --> gcc a.c
    essai.c: Dans la fonction « main »:
    essai.c:2: error: variable or field `a' declared void
    -->

while

La forme générale de la boucle est :

while (expression)
   instruction

instruction est une instruction simple ou un bloc.

Il s'agit d'une structure de contrôle permettant d'itérer une instruction (élémentaire ou bloc) tant qu'une certaine condition est vraie.

L'expression contrôlant la boucle est évaluée à l'entrée de la boucle et donc l'instruction n'est éventuellement pas exécutée.


Copyright © <2011>, <Lycée de Taaone/Escot>

Created with the Freeware Edition of HelpNDoc: Easily create CHM Help documents