Programmation en C


Structure générale d'un programme en C


Un programme écrit en C respecte toujours la même structure. Il est composé d'un ou plusieurs fichiers d'en-tête et du corps du programme. Un fichier d'en-tête est une bibliothèque de fonction. Si, par exemple, nous voulons faire apparaître une phrase à l'écran, il faudra utiliser la fonction appropriée. Celle-ci se trouve dans un fichier d'en-tête que nous devons mentionner en début de programme. Les fichiers d'en-tête portent l'extension .h (headers). La structure générale d'un programme C est décrite ci-dessous.

#include <stdio.h>  -> Mention du fichier d'en-tête standard main()                    -> Déclaration de la fonction principale
{                             -> Ouverture de la fonction principal .
.
.                         -> Instructions
.
}                           -> Fermeture de la fonction

Tout programme C doit respecter cette structure. Le fichier d'en-tête et la fonction principale sont obligatoires. La fonction principale est déclarée par la ligne "main()". Les instructions sont comprises dans cette même fonction.
Le fichier d'en-tête "stdio.h" contient toutes les fonctions d'entrées/sorties standards. Il doit toujours être mentionné dans un programme C.


Exemple de programme C

L'exemple ci-dessous illustre un programme C simple qui affiche une ligne de texte à l'écran. La fonction "printf" sert à afficher la phrase à l'écran. Celle-ci doit se trouver entre les parenthèses et les guillements. A la fin de cette chaîne de caractères, nous apercevons le caractère "\n". Celui-ci est sert à faire une nouvelle ligne (saut de ligne). Nous y reviendrons ultérieurement. La ligne servant à afficher la chaîne de caractère est terminée par un point-virgule. Si celui-ci est absent, le compilateur retourne un message d'erreur. Toutes les lignes doivent être terminées par un point-vigules, à l'exceptions de l'instruction #include, des déclarations de fonctions, des accolades, des boucles et des instructions conditionnelles. Enfin, la ligne "return 0;" indique que le programme ne revoie pas de valeur entière. Cette ligne est exigée par de nombreux compilateurs. Observez que cette ligne est terminée par un point-virgule.

#include <stdio.h> 
main()                   
{                            
printf("Ceci est un programme C.\n");
return 0;
}                           

Le résultat que vous apercevrez à l'écran lorsque vous exécuterez ce programme est illustré ci-dessous.
Ceci est un programme C.


Les commentaires

Les commentaires sont des annotations que le programmeur peut insérer dans le code pour que celui-ci soit plus compréhensible. Les commentaires n'ont aucune influence sur un programme, et ils peuvent être insérés à n'importe quel endroit dans le programme. Pour faire un commentaire, nous plaçons un texte entre les symboles /* et */. Une autre façon de procéder est faire précéder un texte du symbole //.
 
#include <stdio.h> 
/* Ceci est un commentaire */
main()                   
{                            

// Ceci est un autre commentaire

printf("Ceci est un programme C.\n");

return 0;
}


Constantes

Une constante représente une valeur fixe, ne pouvant pas être modifiée directement par l'utilisateur durant l'exécution du programme. En revanche, il est possible de modifier son contenu si nous écrivons le code C approprié. Cependant, une constante se trouvant dans un programme ne doit normalement pas être modifiée. A présent, voyons comment déclarer une constante.

Int const=10;
Char ch=F;

Le type de la constante est "Int" (integer). Cela signifie que la constante contient une valeur numérique entière décimale. Le nom de le constante est "const". C'est le programmeur qui donne le nom aux constante. Nous pouvons donc lui donner n'importe quel nom. Enfin, le 10 est la valeur que nous rangeons dans la constante. Dans le deuxième exemple, nous rangeons le charactère F dans la constante "ch". Il s'agit ici d'une constante caractère (type Char).


Variables

Au contraire d'un constante, une variable est expressement faite pour être modifiée à tout moment dans le programme. Comme une constante, il existe diférents types de variables, selon les données qu'elles contiennent. Une variable doit être déclarée et initialisée avant de pouvoir être utilisée. Pour déclarer une variable de type entier décimal (int), nous écrivons la ligne suivante.
Int variable;
Maintenant que la variable est déclarée, nous devons l'initialiser. Cela signifie que, avant de l'utiliser nous devons lui affecter la valeur 0. Dans le cas contraire, la variable contiendra une valeur aléatoire. Cette valeur aléatoire est inacceptable dans un programme, car elle pourrait affecter le résultat d'une opération mathématique, par exemple. Observez la ligne ci-dessous. Elle range la valeur 0 dans la variable.

Variable=0;


Types de données

Comme déjà dit, une variable ou constante doit avoir un type. Il existe bien entendu plusieurs types de données. Ces types doivent être adaptés au données qu'ils contiennent. Observez le tableau ci-dessous, il contient tout les types de données qu'il est possible de trouver dans un programme en C. Remarquez les valeurs fortement différentes que chaque type est capable de contenir.
 

Type de données

Désignation

Taille [octets]

Plage de valeurs

Commentaires

Char

Caractère

1

-128 à 127

Permet de stocker un caractère

Unsigned char

Caractère non signé

1

0 à 255

Permet de stocker un caractère à valeur non signée

Short int

Entier court

2

-32768 à 32767

Permet de stocker un entier décimal court signé

Unsigned short int

Entier court non signé

2

0 à 65535

Permet de stocker un entier décimal court non signé

Int

Entier

Microprocesseur 16 bits: Microprocesseur 32 bits: 4

-32768 à 32767

-2147483647 à 2147483647

Entier décimal

Unsigned int

Entier non signé

Microprocesseur 16 bits: Microprocesseur 32 bits: 4

0 à 65535

0 à 4294967295

Entier décimal non signé

Long int

Entier long

4

-2147483648 à 2147483647

Permet de stocker un entier long

Unsigned long int

Entier long non signé

2

0 à 429496795

Permet de stocker un entier long non signé

Float

Flottant . nombre réel

4

3.4*10-38 à 3.4*1038

Flottant (nombre à virgule

Double

Flottant double

8

1.7*10-308 à 1.7*10308

Flottant double

Long double

Flottant double long

10

3.4*10-4932 à 3.4*104932

Flottant double long


 

Opérations arthmétiques sur des constantes et variables

Les opération arithmétiques de base sont particulièrement simples. Les signes utilisés sont illustrés ci-dessous.
 
Signe

Signification

+

Addition

-

Soustraction

*

Multiplication

/

Division

%

Modulo (reste de la division entière)


 
Supposons que nous désirons écrire un programme qui effectue l'opération 5*5=25. Pour cela, nous allons déclarer deux variables, et une variable de résultat. L'instruction "printf" sera utilisée pour afficher le résultat à l'écran.
 
#include <stdio.h> 
// Ce programme effectue une opération arithmétique
main()                    
{

          initis// Corps du programme
          int var1;
          int var2;
          int resultat;

          // Initialisation des variable, rangements de la valeur 5
          var 1=5;
          var2=5;
          resultat=var1*var2;

          // Annonce du résultat
          printf("Le resultat de 5*5 est:%d\n", resultat);
          return 0;           
}
 
Dans cet exemple, certains éléments nous sont encore inconnus. Les variables Var1 et Var2 sont initialisées avec la valeur 5. Elles sont ensuite multipliées entre elles, et le résultat est rangé dans la variable résultat. Il s'agit de la ligne " resultat=var1*var2; ". Examinez l'instruction "printf". Vous remarquerez sans doute un élément nouveau. Il s'agit du caractère "%d". Celui-ci est chargé d'afficher un nombre entier décimal. Il est suivi du retour au chariot "\n". La variable "resultat" est mentionnée hors de guillemets. Elle indique quel nombre doit être affiché par le caractère "%d".


Saisie formatée

Pour saisir un caractère ou un autre élément, nous disposons de l'instruction scanf. Celle-ci range dans une variable un caractère saisi au clavier. L'exemple ci-dessus montre l'utilisation de la fonction scanf.
 
#include <stdio.h>
main()
{
           char prenom [40];            
           printf("Entrez votre prénom: \n");
           scanf("%s", &prenom); printf("Votre prénom est: %s\n");
           return 0;
}

Ce programme définit d'abord une variable de type char, où devra être rangée la chaîne de caractère du prénom. Le type définit dans la fonction scanf est "%s", qui signifie que la valeur contenue dans la variable prénom sera une chaîne de caractères. Autrement dit, lorsque l'instruction "scanf" sera exécutés, elle rangera la chaîne de caractère tapée dans la variable "prenom". Cette chaîne peut contenir 40 caractère, c'est pour cela que la variable char contient le chiffre 40 entre crochets. Le résultat de ce programme est illustré ci-dessous.
 
Entrez votre prénom: Alphonse
Votre prénom est: Alphonse

De la même façon, l'instruction scanf peut être utilisée avec n'importe quel type de donnée, par exemple numérique (int).


Saisie de caractère

Si nous voulons saisir un seul caractère, plusieurs instructions sont disponibles. L'une d'elle, getchar est spécifiquement utilisée pour saisir des caractères. Son utilisation est simple, comme le montre l'exemple ci-dessous.

#include <stdio.h>
main()
{
           char caractere;
           printf("Entrez un caractère: \n");
           caractere=getchar;
           printf("Le caractere tapé est: %c\n");

            return 0;

}

L'instruction getchar saisi le caractère après la validation de celui-ci par la touche [enter]. Le résultat affiché est donc:

Entrez un caractère: a
Le caractère tapé est: a

Une autre façon de saisir des caractères est d'utiliser l'instruction getche. Celle-ci ne nécessite pas de validation par la touche [enter], mais passe directement à la suite du programme, dès que le caractère est tapé. Cette instruction nécessite l'ajout du fichier d'en-tête "conio.h". Attention, celui-ci n'est pas disponible dans Linux. Le programme ci-dessous est presque similaire au programme précédent, mais nous utilisons l'instruction "getche".

#include <stdio.h>
#include <conio.h>

main()
{
           char caractere;
           printf("Entrez un caractère: \n");
           caractere=getche;
           printf("Le caractere tapé est: %c\n");

            return 0;

}

Le résultat demeure identique, mais la validation par [enter] n'est pas demandée.

Entrez un caractère: a
Le caractère tapé est: a


Boucles

Lorsque nous devons effectuer une ou pusieurs opérations répetitives, nous devons avoir recours aux boucles. Une boucle est chargée de répéter des instructions tant qu'une condition n'est pas remplie. Il existe trois types de boucles en C: for, while et do while.


Boucle for

L'exemple ci-dessous illustre l'utilisation de la boucle for.

#include <stdio.h>
main()
{
int i;

for (i=0; i<10; i++)
            {
                        printf("Répetition no.%d\n", i);
            }          
return 0;
}

Examinons l'exemple donné ci-dessus. Il s'agit d'un exemple typique d'utilisation de la boucle for. Nous trouvons comme première instruction de la fonction principale la ligne "int i;". Comme la boucle à besoin d'un compteur, il s'agit là de la variable qui remplira ce rôle. La ligne suivante est plus complexe. La boucle for est déclarée par cette ligne. La variable de boucle est initialisé à 0 par la l'instruction "i=0". C'est la valeur de départ de la boucle. L'instruction "i<10" indique la valeur à atteindre avant de sortir de la boucle. L'instruction "i++" indique que la variable i est incrementée. En résumé, la boucle part de la valeur 0, et à chaque exécution de cette boucle, la variable i est incrémentée. Lorsqu'elle atteint 10, la boucle est terminée. Entre les accolades de la boucle se trouvent les instructions que celle-ci doit effectuer de façon répetitive.
Remarquez qu'il est également possible de décrémenter une boucle for. Pour cela, la variable doit être initialisée à une valeur non nulle, et en dernière partie, nous mettrons le caractère "i--", chargé de décrémenter la variable i. Dans notre exemple le résultat affiché sera le suivant.

Répetition no. 1
Répetition no. 2
Répetition no. 3
Répetition no. 4
Répetition no. 5
Répetition no. 6
Répetition no. 7
Répetition no. 8
Répetition no. 9
Répetition no. 10

L'instruction printf est répétée à 10 reprises.


Boucle While

L'emploi de la boucle While est une autre façon d'effectuer des opérations répétitives. "While" est un mot anglais qui signifie "tant que". Nous utilisons ici une variable et une condition.

Var1=14;
while (var1>=10)
                       {
                       var1=var1-1;
                       printf("%d",var1);
                       }

Pour commencer, nous rangeons la valeur 14 à l'intérieur de la variable Var 1. La ligne "while (var1>=10)" signifie "tant que var 1 est plus grand ou égal à 10". Le symbole ">=" signifie "plus grand ou égal". Il s'agit de l'unique condition de la boucle. Le chiffre 14 étant plus grand et inegal à 10, les instruction entre les accolades sont exécutées. La ligne " var1=var1-1;" est équivalent à l'instruction "var1--". La variable var1 est donc décrementée. La valeur de cette variable est donc 13. La ligne suivante affiche la valeur de Var1. La boucle recommence et teste à nouveau la condition. Comme la variable est plus grande et inegale à 10, elle est à nouveau décrementée. Le procédé continu jusqu'à ce que la variable soit décrémentée jusqu'à la valeur 9. Lorsque la valeur est à nouveau testée elle n'est pas supérieure ou égale à 10. Le contenu des accolades ne s'exécute donc pas. Le résultat du programme contenant cette boucle est décrit ci-dessous.

13
12
11
10

Boucle do while

La boucle do while est une troisième façon d'effectuer des opérations répétitives. Elle ressemble à la boucle while, mais la condition est placée à la fin de la boucle. La syntaxe est donc quelque peu différente. Pour constitiuer une boucle do while, nous plaçon le mot clé "do" et ouvrons les accolades qui contiennent les instructions à exécuter. La dernière ligne de la boucle est l'instruction "while", qui contient la condition. Un exemple de boucle do while est illustré ci-dessous.

Var1=10;
do
                                          

{
                        var1=var-1    
                      printf("%d\n", var1);

}
while (valeur>3)

Lorsque la ligne " while (valeur>3) " est atteinte, le pointeur d'instruction est renvoyé à l'instruction "do" si la condition est remplie. La variable Var1 est décrementée, et son contenu est alors affiché à l'écran. Lorsque la variable atteint la valeur 3, le pointeur d'instruction sort de la boucle do while.


Boucles imbriquées

Il est naturellement possible d'intégrer une boucle à l'intérieur d'une autre boucle. Nous obtenons des boucles imbriquées. Il est possible de constituer des boucles imbriquées avec n'importe quel type de boucle que nous venons de voir. Revenons aux boucles for. L'exemple suivant montre des boucles imbriquées.

#include <stdio.h>
main()
{
       int i;
       int y;
       for (i=0; i<5; i++)
            {
              for (y=0; y<3; y++)
                     {
                                   printf("Répetition no.%d\n", y);
                      }
            printf("i=%d\n",i);

}          
return 0;
}

Comme nous avons ici deux boucles, ce programme nécessite deux variables distinctes. L'une (i) est utilisée dans la boucle extérieure. L'autre (y) est utilisée dans la boucle intérieure. Celle-ci s'exécute en premier, et l'instruction "printf" est utilisée à trois reprises. Lorsque la boucle intérieure à terminé son exécution, le pointeur d'instruction reviens à la première boucle extérieure et la variable i est incrémentée. La boucle intérieure est exécuté 5 fois, car la première boucle extérieure est programmée pour s'exécuter 5 fois. L'affichage obtenu est le suivant.

Répetition no. 1
Répetition no. 2
Répetition no. 3
Répetition no. 1
Répetition no. 2
Répetition no. 3
Répetition no. 1
Répetition no. 2
Répetition no. 3
Répetition no. 1
Répetition no. 2
Répetition no. 3
Répetition no. 1
Répetition no. 2
Répetition no. 3

Tout les types de boucles permettent des imbrications.


Instructions conditionnelles

Les instructions conditionnelles permettent d'exécuter des opérations différentes selon les variables renvoyées.


Instruction if

L'instruction if est la plus simple des instructions conditionnelles. Elle permet d'exécuter des opérations uniquement lorsqu'une variable à une valeur définie. Un exemple est illustré ci-dessous.

if(var1<10)
                {
                printf("Var1 est inférieure à 10");
                }

La condition est placée entre parenthèse, après le mot clé if. Lorsque la variable var1 est inférieure à 10, l'instruction entre accolades est exécutée. Dans le fragment de programme ci-dessus, le texte "Var 1 est inférieure à 10" est affiché.


Instructions if imbriquées

if(var1<10)
                {
                printf("Var1 est inférieure à 10\n");               
               if(var1==0)
                        {
                        printf("Var1 est une valeur nulle\n");
                       }
             }

Les instructions if imbriquées sont assez simples. Dans l'exemple ci-dessus, l'instruction if effectue vérifie d'abord si la variable Var1 est inférieurs à 10. Si tel est le cas, la condition est valide, et l'instruction printf est exécutée. Le pointeur d'instruction passe par le deuxième mot clé IF. La condition de celui-ci est que la variable Var1 soit égale à 0. Si tel est le cas, le message "Var1 est une valeur nulle" est affiché. Si au contraire ce n'est pas le cas, le pointeur d'instrutction ignore le mot clé "if" ainsi que le contenu compris entre les accolades.


Instruction if else

Dans l'exemple précédent, si la condition n'est pas rempli, le pointeur d'instruction ignore le mot clé if et ses instructions entre accolades et passe aux lignes suivantes. Dans l'exemple qui suit, si la condition n'est pas remplie, le pointeur d'instruction passe à l'instruction else, et exécute ce qui se trouve entre les accolades de celle-ci, comme le montre clairement l'exemple ci-dessous.

if(var1<10)
            {
            printf("Var1 est inférieure à 10");

 }
            else
            {
            printf("Var 1 est supérieure ou égale à 10");
            }


Instruction switch / case

L'instruction if est utilisée dans des cas peu complexes. Pour des cas complexes, nous disposons des instructions Switch / case, qui peuvent s'averer extrêmement pratiques à l'intérieur d'un programme en C. Bien entendu, cette solution est plus complexe que le IF simple, mais permet d'être plus efficace dans certains cas. Observez l'exemple de programme illustré ci-dessous.

#include <stdio.h>
main()
{
int choix;             
             printf("Tapez un chiffre de votre choix: ");
             scanf("%d", &choix);
             switch (choix)

             case 1:
             {
            printf("Vous avez tapé 1\n");
             }

             case 2:
             {
            printf("Vous avez tapé 2\n");
            }
      
case 3:
            {  
            printf("Vous avez tapé 3\n");
           }

default:
            {
            printf("Vous avez tapé un chiffre différent\n");
            }
}
return 0;
}

Un chiffre est d'abord demandé à l'utilisateur, puis rangé dans la variable Choix. L'instruction Switch analyse le chiffre entré puis exécute les instruction "case" selon la valeur du chiffre entré. L'instruction printf sera exécuté, ainsi que les instructions suivantes. Par exemple, supposons que l'utilisateur entre le chiffre 2. Le résultat affiché sera le suivant.

Vous avez tapé 2.
Vous avez tapé 3.

En effet, le pointeur d'instruction ne s'est pas arrêté à l'instruction "case 2". Il a également exécuté les instruction qui ont suivi. Si nous vous exécuter uniquement l'instruction Case correspondante au chiffre entré, nous devons utiliser le mot clé break. Vous trouverez ci-dessous le même programme d'exemple avec le mot clé break, et constaterez la différence.

#include <stdio.h>
main()
{
int choix;             
           printf("Tapez un chiffre de votre choix: ");
           scanf("%d", &choix);
           switch (choix)

case 1:
           {
            printf("Vous avez tapé 1\n");
           }
           break;               

case 2:
            {
            printf("Vous avez tapé 2\n");
            }
            break;      
 
case 3:
            {  
            printf("Vous avez tapé 3\n");
           }
           break;
 
default:
            {
            printf("Vous avez tapé un chiffre différent\n");
            }            break
 
}
return 0;
}

Les instructions break sont insérées dans le programme ci-dessus. Attention, les instructions break ne sont pas comprises dans les accolades délimitant les CASE. Avec les Break, le résultat est affiché ci-dessous lorsque vous tapez le chiffre 2.

Vous avez tapé 2.

Une fois que l'instruction printf est exécutée, le pointeur d'instruction ne pointe plus vers aucune instruction comprise entre les accolades de l'instruction switch. Le cas Default est utilisé lorsque la valeur entrée est différente des valeurs proposées. Dans notre cas, le "default" est utilisé lorsque l'utilisateur entre un autre chiffre que 1, 2 ou 3.


Fonctions

Une fonction est en quelque sorte un sous-programme situé hors de la fonction principale (main). Il peut être appelé par une instruction situé dans la fonction main pour effectuer une tâche particulière. On pourrait se passer de fonctions, car elle servent à simplifier le code et à le rendre facilement lisible. Cependant elles sont particulièrement pratiques lorsqu'il est nécessaire d'exécuter plusieurs fois les mêmes opérations en écrivant une seule fois ces mêmes opérations.
Une fonction est composée d'un type, d'un nom et d'une accolade ouvrante et d'une accolades fermante. Le fragment de programme ci-dessous montre une fonction. Nous définissons pour commencer le type de la fonction (ici int). Nous donnons ensuite son nom (ici "multiplication). Entre parenthèse, nous entrons les arguments. Il s'agit des variables que la fonction devra traiter. Notez qu'une fonction ne nécessite pas forcément d'arguments. La fonction main, que nous avons vu jusqu'ici ne possède pas d'argument dans nos exemple. Nous continuons par une accolade ouvrante. Comme pour la fonction principale, nous délimitons le corps de la fonction par des accolades. Dans le corps de la fonction se trouvent les instructions qui multiplie les variables x et y. La fonction retourne la valeur obtenue (return resultat;). Dans la partie principale du programme (main), nous définissons la variable entière "produit", pour y ranger le résultat de l'opération arithmétique. A la ligne suivante, nous appelons la fonction "multiplication" en entrant les valeurs que nous désirons (ici 7 et 8). Ces deux valeurs seront traitées par la fonction, dans les variables x et y. Autrement dit, c'est la fonction qui est chargée de multiplier ces valeurs. Le resultat de la multiplication est rangée dans la variable produit. Celle-ci est affichée à l'écran à l'aide de l'instruction "printf". Le programme prend fin après cette instruction.

Int multiplication(int x, int y)
{
            int resultat;
            resultat=x*y;
            return resultat;
}
 
int main()
{
            int produit;
           
            produit=multiplication(7,8);    // Appel de fonction
            printf("7 * 8 donne %d\n", produit);
            return 0;
}



Variables locales et variables globales

Maintenant que nous savons ce qu'est une fonction en C, il est nécessaire de faire clairement la différence entre une variable locale et une variable globale. Une variable globale peut-être utilisée dans tout le programme. Elle doit être déclarée avant la fonction principale. Une fonction locale, est au contraire, utilisable uniquement à l'intérieur de la fonction dans laquelle elle est déclarée.


Tableau unidimensionnel 

Dans les variables que nous avons vu jusqu'ici, il était possible de renger un seul élément, par exemple un entier.
Il est fréquent de devoir ranger un très grand nombre de variables en une seule fois. Pour cela, nous avons besoin de tableaux. En quelque sorte, un tableau est une variable pouvant contenir un nombre illimité d'autres variables. Il existe deux sortes de tableaux: les tableaux unidimensionnels et multidimensionnels.
Un tableau unidimensionnel se déclare de la manière suivante:

Type nomtableau [nombre_d_elements];

Supposons que nous voulons créer un tableau unidimensionnel contenant 10 variables entières. Nous entrerons alors la ligne suivante:

Int tableau [10];

Le tableau contiendra 10 variable de type int. Il aura donc l'allure représentée ci-dessous.

donnée

donnée

donnée

donnée

donnée

donnée

donnée

donnée

donnée

donnée




Initialisation d'un tableau unidimensionnel de type entier

Il est parfois nécessaire d'initialiser un tableau unidimensionnel, c'est-à-dire de ranger des valeurs nulles dans chacun de ses emplacement. Cela se fait d'une manière assez simple à l'aide d'une boucle, comme illustré. Cet exemple est valable pour un tableau de type entier.
 
for (i=0; i<10; i++)
        {
        valeur[i]=0;
        }

Une fois qu'un tel tableau est déclaré, il est possible de ranger un variable dans l'emplacement qui nous convient. De même qu'il est possible d'accéder à n'importe quel emplacement pour récupérer une variable.
Le programme ci-dessous donne un exemple d'utilisation de tableau. Un tableau contenant 15 variables entière est d'abord déclaré. A l'intérieur de la boucle, les valeurs de la variable de boucle i sont rangées les unes après les autres à l'intérieur du tableau. Ces valeurs sont rangées individuellement dans les emplacements du tableau à l'aide de la ligne " tableau_int[i]=i+1;". A chaque fois qu'une valeur est rangée dans un emplacement, le contenu de l'emplacement occupé est affiché à l'aide de la ligne "printf(tableaut_int[%d] contient %d. \n", i, tableau_int[i]);". Losque la boucle est terminée, le programme prend fin.

#include <stdio.h>
main()
{
        int i;
        int tableau_int[15];
        for (i=0; i<15; i++)
        {
                tableau_int[i]=i+1;
                printf("tableau_int[%d] contient %d. \n", i, tableau_int[i]);
        }
        return 0;
}


A la fin du programme, le tableau contient les éléments suivants:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15



Tableau unidimensionnel de caractères

Dans l'exemple précédent, nous avons travaillé avec un tableau contenant des entiers. Il est bien entendu possible de travailler avec des tableaux contenant uniquement des caractères. Nous y rangeons 7 caractères ainsi que le symbole "\0". Celui-ci doit obligatoirement être inséré à la fin du tableau pour annoncer la fin de la chaîne de caractère rangée dans le tableau. Les caractères sont rangés les uns après les autres à l'intérieur du tableau. Une boucle est chargée de lire les 8 emplacements du tableau et d'afficher les caractères que ceux-ci contiennent.

#include <stdio.h>
main()
{
        int i;
        char array_ch[8]={'B','o','n','j','o','u','r','\0'};
        for (i=0; i<8; i++)
                {
                printf("%c", array_ch[i]);
                }
        return 0;
}

Il est important de comprendre qu'une chaîne de caractère en C est en réalité un tableau contenant un caractère dans chacun de ses emplacements.


Initialisation d'un tableau unidimensionnel de type caractère

Pour initialiser un tableau de caractère, il est nécessaire de procéder de la même façon que pour l'initialisation du tableau d'entier que nous connaissons déjà. L'exemple ci-dessous montre comment initialiser un tableau de caractères pour 10 emplacement. A la fin de la boucle, la tableau ne contient que des caractères nuls, comme désiré.

for (i=0; i<10; i++)
        {
        valeur[i]=' ';
        }


Tableaux multidimensionnels

Les tableaux que nous avons utilisés jusqu'ici ne comportait qu'une dimension. Il est possible de créer des tableaux comprenant plusieurs dimensions. De tels tableaux sont dits "multidimensionnels". Nous utiliseront ici des tableaux à 2 dimensions, car ils sont fréquement utilisés. Il est évident que nous pouvons créer des tableaux plus complexes utilisant davantage de dimensions.
La tableau multidimensionnel se déclare de la manière suivante:


type nomtableau[longuer1][longueur2];

Comme le tableau est multidimensionnel, il est nécessaire de s'imaginer clairement l'allure qu'il présente. Par exemple, déclarons la ligne suivante.

int tableau [4][3];

Le tableau que nous avons déclaré présentera l'allure suivante.

Emplacement[0][0]

Emplacement[0][1]

Emplacement[0][2]

Emplacement[0][3]

Emplacement[1][0]

Emplacement[1][1]

Emplacement[1][2]

Emplacement[1][3]

Emplacement[2][0]

Emplacement[2][1]

Emplacement[2][2]

Emplacement[2][3]


 
En changeant les longueurs comprises entre cochet, nous pouvons accéder à n'importe quel emplacement du tableau. De cette façon nous pouvons y ranger des variables, ou lire les variables déjà rangées à l'intérieur du tableau.
Prenons à présent un exemple concret de l'utilisation d'un tableau multidimensionnel. Un tableau est d'abord déclaré, et des valeurs sont rangées à l'intérieur de tous les emplacements qu'il contient. Ce programme contient 2 boucles imbiquées. La boucle extérieure incrémente la variable i, et affiche la première dimension du tableau. La boucle intérieure incrément la variable j et la seconde dimension du tableau peut ensuite être affichée.

#include <stdio.h>
main()
{
        int tableau[3][5]={1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 100, 200, 300, 400, 500};
        int i;
        int j;
        for (i=0; i<3; i++)
                {
                printf("\n");
                for(j=0; j<5; j++)
                        {
                        printf("%6d", tableau[i][j]);
                        }
                }
        return 0;
}

Le caractère "%6d" sert à effectuer 6 espaces, puis à afficher la variable entière. Le résultat que retourne le programme est affiché ci-dessous.

1          2          3          4          5
10       20       30       40       50
100     200     300     400     500


Structures et unions

Les tableaux que nous venons de voir ne sont capable de stocker qu'un type de variable, par exemple int. Si nous désirons regrouper différents types de variable, nous disposons des structures. Une structure est un groupe de variable qui peuvent être de type différent.
La syntaxe générale d'une structure est illustrée ci-dessous.
Struct nom
{
           type var1;
           type var2;
           type var3;
.
.
};
 
Observez le programme ci-dessous. Il montre une structure contenant 4 variables de types différents.

#include <stdio.h>
main(void)
{
        struct personne
                {
                // Déclaration des champs de la structure
                char nom[15];
                char prenom[15];
                int age;
                float moyenne;
                } model;
        printf("Nom:\n");
        gets(model.nom);
        printf("Prenom:\n");
        scanf("%s", &model.prenom);
        printf("Age:\n");
        scanf("%d", &model.age);
        printf("Moyenne:\n");
        scanf("%f", &model.moyenne);

        // Lecture des données contenus dans les champs
        printf("Resultats saisis:\n");
        printf("Nom: %s\n", model.nom);
        printf("Prenom: %s\n", model.prenom);
        printf("Age: %d\n", model.age);
        printf("Moyenne: %f\n", model.moyenne);
 
        return 0;
}

La structure est d'abord déclarée à l'aide du mot clé "struct". A l'intérieur des accolades de la structure, les variable sont déclaré. La structure "model" est déclarée avec le type de structure personne. Ainsi, lorsque les variables sont utilisées, il est possible de reconnaître à quelle  structure elles appartiennent.
Le résultat de ce programme d'exemple est décrit ci-dessous.

Nom:
Dupont
Prénom:
Alphonse
Age: 24
Moyenne:5,73
 
Résultats saisis:
Nom: Dupont
Prénom: Alphonse
Age: 24
Moyenne: 5,73

Les structures servent à rendre un programme plus clair et compréhensible, notamment quand le nombre des variables est important.
Les unions sont semblables aux structure, excepté dans la gestion de la mémoire. En effet, une union est capable de stocker tous ses membres dans le même emplacement en mémoire. Une union se déclare de la même façon qu'une structure, à l'exception du mot clé de déclaration, comme illustré.

Union exemple;
{
            type var1;
            type var2;
            type var3;
};



Pointeurs

Les pointeurs en C sont assez complexes. Un pointeur est une variable contenant l'adresse mémoire d'une autre variable. En d'autres termes il s'agit d'une variable pointant vers une autre variable, d'où le nom "pointeur". Un pointeur possède en réalité deux valeur. L'une est dite valeur de gauche. Il s'agit de l'adresse mémoire. L'autre est dite valeur de droite. Il s'agit du contenu de la variable pointée. Celle-ci est alors accessible par son son nom son adresse mémoire. L'emplacement en mémoire où la variable sera stocké dépend du système d'exploitation.
Prenons à présent un exemple concret des pointeurs. L'exemple ci-dessous donne l'adresse et le contenu d'une vairable pointeur.

#include <stdio.h>
main()
{
        int x, *ptr_x;
        x=10;
        printf("x: adresse=0x%p, contenu=%d\n", &x, x);
        ptr_x=&x;
        printf("ptr_x => %d\n", *ptr_x);
        return 0;
}
 
Nous déclarons d'abord une variable entière et une variable pointeur. La variable pointeur est déclarée par le symbole * suivi du nom de la variable et d'un point-virgule de terminaison. Nous rangeons ensuite la valeur 10 à l'intérieur de la variable entière. La première instruction "printf" affiche l'adresse de la variable X (en hexadécimal) ainsi que son contenu. Remarquez que l'adresse doit être affichée à l'aide de l'instruction "%p". Pour afficher la valeur de gauche, l'instruction printf doit contenir "&x" hors des guillemets. La valeur gauche de la variable X est affecté au pointeur &x. Cette valeur est ensuite affichée à l'aide de l'instruction "printf". Ci-dessous, observez le résultat affiché.

X: adresse=0x0012FF88, contenu=10


L'adresse mémoire affichée varie d'un ordinateur à l'autre.


Mise à jour d'une variable pointeur

L'exemple ci-dessous montre comment mettre à jour le contenu d'une variable pointée. Dans cet exemple nous n'utiliserons plus de variable entière, mais une variable de caractère. Cet exemple montre clairement le fonctionnement des pointeurs.
Nous commençons par déclarer une variable caractère et une variable pointeur. Nous rangeons la valeur 'A' dans la variable caractère. L'adresse et le contenu de la variable X sont ensuite affichés à l'aide de l'instruction "printf". La valeur gauche de la variable X est affecté au pointeur &x. Par la ligne suivante, nous pouvons afficher l'adresse de la variable X ainsi que son contenu:

printf("ptr_x: adresse=0x%p, contenu=0x%p\n", &ptr_x, ptr_x);

La ligne suivante affiche la valeur de droite de la variable pointeur:

printf("*ptr_x => %c\n", ptr_x);

A la ligne suivante, nous mettons cette valeur à jour en lui affectant le caractère B. La variable pointeur ainsi que la variable caractère sont à nouveau affichés. Nous remarquons alors que nous avons mis à jour la variable, sans changer son adresse mémoire. Nous remarquons que l'adresse de la variable caractère et de la variable pointeur sont différentes, et que la valeur de gauche de la variable pointeur contient l'adresse mémoire de la variable caractère.

#include <stdio.h>
main()
{
        char x, *ptr_x;   // Déclaration de la variable pointeur
        x='A';
        printf("x: adresse=0x%p, contenu=%c\n", &x, x);
        ptr_x=&x;
        printf("ptr_x: adresse=0x%p, contenu=0x%p\n", &ptr_x, ptr_x);
        printf("*ptr_x => %c\n", *ptr_x);
        *ptr_x='B';
        printf("ptr_x: adresse=0x%p, contenu=0x%p\n", &ptr_x, ptr_x);
        printf("x: adresse=0x%p, contenu=%c\n", &x, x);
        printf("*ptr_c => %c\n", *ptr_x);
        return 0;
}
Le résultat de ce programme est illustré ci-dessous.

X: adresse=0x0012FF8B, contenu=A
Ptr_x: adresse=0x0012FF84, contenu=0x0012FF8B
*ptr_x=>A
Ptr_x: adresse=0x0012FF84, contenu=0x0012FF8B
X: adresse=0x0012FF8B, contenu=B
*ptr_x=>B

RETOUR