02 Programmation C
02 Programmation C
Programme :
V. Les pointeurs..................................................................................................... 42
1|Page
I. Présentation du Langage C
1. Définition
La programmation est l’ensemble des activités qui permettent de concevoir, écrire,
tester et maintenir des programmes informatiques.
Ces instructions sont assez basiques. On trouve ainsi des instructions d’addition, de
soustraction, de multiplication, ou d’autres opérations mathématiques de base, qui
font que notre ordinateur est techniquement une vraie machine à calculer. D’autres
instructions existent, comme des opérations permettant de comparer des valeurs ou
de se rendre à un point précis du programme.
Créer un programme, c’est tout simplement utiliser ces instructions basiques afin de
réaliser ce que l’on veut.
3. Ecrire un programme
Code minimal en langage C :
# include <stdio.h>
# include <stdlib.h>
2|Page
int main ()
{
Printf ("Hello word!\n");
Return 0;
}
a. Directives de préprocesseur
# include <stdio.h> et # include <stdlib.h> sont des lignes spéciales que l’on ne voit
qu’en haut des fichiers source. Ces lignes sont facilement reconnaissables car elles
commencent par un dièse. Elles sont appelées directives de préprocesseur, ce sont
des lignes qui seront lues par un programme appelé préprocesseur, un programme
qui se lance au début de la compilation.
Le mot include signifie inclure en français. Ces lignes demandent d’inclure des
fichiers au projet c’est-à-dire d’ajouter des fichiers pour la compilation ; il y a deux
lignes donc deux fichiers inclus. On appelle ces fichiers des bibliothèques ; sans ces
fichiers écrire du texte à l’écran aurait été impossible.
En résumé les deux premières lignes incluent des bibliothèques qui permettent
d’afficher du texte à l’écran assez facilement.
b. Fonction et instruction
Int main ()
{
Printf ("Hello word!\n");
Return 0;
}
Ce qui se trouve entre les accolades s’appelle une fonction. Ce programme n’en
contient qu’une seule. Un programme en langage C est constitué de fonctions ;
chaque fonction permet de rassembler plusieurs commandes à l’ordinateur qui
permettent de faire quelque chose de précis. Par exemple on peut créer une fonction
ouvrir_fichier qui contiendra une suite d’instructions pour l’ordinateur, lui expliquant
comment ouvrir un fichier. L’avantage c’est que une fois la fonction écrite il suffira de
dire ouvrir_fichier et l’ordinateur saura comment faire sans qu’on ait à tout répéter.
3|Page
La première ligne contient le nom de la fonction main « principale » C’est toujours par
la fonction main que le programme commence. Une fonction a un début et une fin
délimitée par les accolades. Toute fonction main se trouve donc entre ses accolades.
Notre fonction main contient deux lignes. Ces lignes à l’intérieur d’une fonction sont
appelées instructions. Chaque instruction est une commande qui demande à
l’ordinateur de faire quelque chose de précis. Le programmeur devra regrouper
intelligemment les instructions dans les fonctions pour créer des bouts de programmes
tout prêts. Toute instruction se termine obligatoirement par un point-virgule.
Return 0; Cette ligne indique qu’on arrive à la fin de notre fonction main et demande
de renvoyer la valeur 0. En pratique 0 signifie que tout s’est bien passé et toute autre
valeur signifie qu’il y a une erreur.
Printf est une instruction qui commande à l’ordinateur « affiche ce message à l’écran».
Pour faire appel à une fonction, il suffit d’écrire son nom suivi de () puis de ; Printf () ;
Il faut indiquer quoi écrire à l’écran en donnant à la fonction le texte à afficher :
Printf ("Bonjour") ;
4|Page
\r : retour au début de la ligne
\a : alerte sonore
Printf ("Bonjour\nAu revoir\n") ; Ceci affiche Bonjour sur la première ligne et Au revoir
sur la deuxième.
d. Les commentaires
Les commentaires sont utiles pour mieux expliquer chaque ligne de code afin de vous
retrouver plus tard dans votre programme. Il y a plusieurs manières d’insérer un
commentaire :
Un double slash // lorsque le commentaire est court et ne tient que sur une
seule ligne
Lorsque le commentaire est long et tient sur plusieurs ligne, slash suivi d’étoile
/* indique le début du commentaire et étoile suivi de slash */ indique la fin.
5|Page
II. Les bases du langage C
1. Les variables
a. Définition
Une variable est une petite information temporaire qu’on stocke dans la mémoire vive
(RAM). Sa valeur peut changer pendant le déroulement du programme. Une variable
est constituée de deux éléments : un type et un identificateur qui est en gros le « nom
» de la variable.
b. Types de variables
Le type d’une variable permet d’indiquer ce qui y sera stocké, par exemple : un
caractère, un nombre entier, un nombre réel (ou nombre à virgule flottante, parfois
tout simplement abrégé en « flottant »), etc. Pour préciser le type d’une variable, il est
nécessaire d’utiliser un mot-clé spécifique.
c. Identificateur
Un identificateur est un nom donné à une variable pour la différencier de toutes les
autres. Et ce nom, c’est au programmeur de le choisir. Cependant, il y a quelques
limitations à ce choix :
6|Page
À noter que le C fait la différence entre les majuscules et les minuscules (on dit qu’il
respecte la casse). Les variables largeur, LARGEUR, Largeur sont trois variables
différentes en langage C.
Exemple :
int x ; // déclaration d’une variable entière
x = 5 ; // affectation d’une valeur
float y = 3.14 ; // variable réelle
char z = ‘a’ ; // variable caractère
bool b = true ; // variable booléenne
int tab [5] = {1, 2, 3, 4, 5} ; // tableau entier
int* ptr = &x ; // pointeur entier
2. Les opérateurs
a. Opérateurs arithmétiques
Addition + ; Soustraction – ; Multiplication * ; Division / ; Modulo % ; Incrément ++ ;
Décrément - -
Exemple :
int x = 5 ;
int y = 3 ;
int z = x + y ; // z = 8
z = x – y ; // z = 2
z = x * y ; // z = 15
z = x / y ; // z = 1 car z est entier
z = x % y ; // z = 2 modulo reste d’une division
x++ ; // x = 6
x-- ; // x= 5 car x a déjà la valeur 6 dans le programme
7|Page
b. Opérateurs de comparaison
Egalité = = ; Inégalité != ; Inférieur < ; Supérieur > ; Inférieur ou égal <= ; Supérieur ou
égal >=
Exemple :
int x = 5 ;
int y = 3 ;
bool z = x = = y ; // z = false
z = x != y ; // z = true
z = x < y ; // z = false
z = x > y ; // z = true
c. Opérateurs logiques
ET (&&) ; OU (||) ; NON (!)
Exemple :
bool x = true ;
bool y = false ;
bool z = x&&y ; // z = false
z = x || y ; // z = true
z = ! x ; // z = false
d. Opérateurs d’assignation
Affectation (=) ; Addition (+=) ; Soustraction (-=) ; Multiplication (*=) ; Division (/=) ;
Modulo (%=)
Exemple :
int x = 5 ;
x = 3 ; // x = 3
x += 2 ; // x = 5
x -= 2 ; // x = 3
x *= 2 ; // x = 6
x /= 2 ; // x = 3
x %= 2 ; // x = 1
8|Page
e. Opérateurs spéciaux
Adresse (&) ; Contenu (*) ; Taille (sizeof) nombre d’octets nécessaire pour stocker le
type.
Exemple :
int x = 5 ;
int *ptr = &x ; // ptr pointe vers x
int z = *ptr ; // z = 5
z = sizeof (x) ; // z = 4
z = (int) 3.14 ; // z = 3
%type est une chaine de caractères qui spécifie le format de la variable ou valeur à
afficher : %d pour le type entier, %f pour le type flottant, %c pour le type caractère,
%s pour les chaînes de caractères et %p pour les pointeurs.
Exemple :
int age = 25 ;
float note = 12.5 ;
char lettre = ‘A’ ;
Printf ("J’ai %d ans \n", age) ;
Printf ("Ma note est de %f /20 \n", note) ;
Printf ("La lettre est %c. \n", lettre) ;
b. Scanf ()
La fonction Scanf permet de lire des données saisies par l'utilisateur via le clavier.
Exemple :
# include <stdio.h>
int main() {
int age;
printf ("Entrez votre âge : ") ;
scanf ("%d", &age) ;
printf ("Vous avez %d ans.\n", age) ;
return 0;
}
10 | P a g e
III. Les structures de contrôle
Elles permettent de gérer le flux d’exécution d’un programme en fonction de conditions
ou de répétitions.
Syntaxe :
Exemples :
# include <stdio.h>
# include <stdlib.h>
int main ()
{
int a = 10;
int b = 20;
if (a < b)
{
Printf ("%d est inférieur à %d\n", a, b);
}
return 0;
}
# include <stdio.h>
# include <stdlib.h>
int main ()
{
int age ;
if (age >= 18)
11 | P a g e
{
Printf ("Vous êtes majeur \n") ;
}
return 0;
}
b. If Else (Sinon)
Elle exécute un bloc de code si une condition est vraie sinon exécute un autre bloc. Il
suffit de rajouter Else après l’accolade de fermeture du "If".
# include <stdio.h>
# include <stdlib.h>
int main ()
{
int age ;
if (age >= 18)
{
Printf ("Vous êtes majeur \n") ;
}
Else
{
Printf ("Vous êtes mineur \n") ;
}
return 0;
}
c. Switch
L’instruction switch permet de comparer la valeur d’une expression entière par rapport
à une liste de constantes entières. Techniquement, elle permet d’écrire de manière
plus concise une suite d’instructions if else qui auraient pour objectif d’accomplir
différentes actions suivant la valeur d’une expression.
if (a == 1)
{
/* Instruction(s) */
12 | P a g e
}
else if (a == 2)
{
/* Instruction(s) */
}
/* Etc. */
else
{
/* Instruction(s) */
}
Avec l’instruction switch on obtient:
switch (a)
{
case 1:
/* Instruction(s) */
break;
case 2:
/* Instruction(s) */
break;
/* Etc... */
default: /* Si aucune comparaison n'est juste */
/* Instruction(s) à exécuter dans ce cas */
break;
}
#include <stdio.h>
#include <stdlib.h>
13 | P a g e
int main ()
{
int note;
printf ("Quelle note as-tu obtenue (sur cinq) ? ");
scanf ("%d", ¬e);
switch (note)
{
/* Si note == 0 */
case 0:
printf ("No comment.\n");
break;
/* Si note == 1 */
case 1:
printf ("Cela te fait 4/20, c'est accablant.\n");
break;
/* Si note == 2 */
case 2:
printf ("On se rapproche de la moyenne, mais ce n'est pas encore ça. \n");
break;
/* Si note == 3 */
case 3:
printf ("Tu passes.\n");
break;
/* Si note == 4*/
case 4:
printf ("Bon travail, continue ainsi !\n");
break;
/* Si note == 5 */
case 5:
Printf ("Excellent !\n");
break;
/* Si note est différente de 0, 1, 2, 3, 4 et 5 */
14 | P a g e
default:
printf ("Tu possèdes une note improbable...\n");
break;
}
return 0;
}
d. L’opérateur ternaire
L’opérateur conditionnel ou opérateur ternaire est un opérateur particulier dont le
résultat dépend de la réalisation d’une condition.
Cet opérateur permet d’écrire de manière condensée une structure if {} else {}.
Exemple :
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int heure;
scanf ("%d", &heure);
(heure > 8 && heure < 20) ? printf ("Il fait jour.\n") : printf ("Il fait nuit.\n");
return 0;
}
Exercice :
15 | P a g e
2. Les structures de contrôle itératives (les boucles)
Une boucle est un moyen de répéter des instructions suivant le résultat d’une
condition.
a. La boucle while
Elle permet de répéter un bloc d’instructions tant qu’une condition est remplie.
Syntaxe :
while (/* Condition */)
{
/* Bloc d'instructions à répéter */
}
Si vous n’avez qu’une seule instruction à réaliser, vous avez la possibilité de ne pas
mettre d’accolades.
Exemple :
# include <stdio.h>
# include <stdlib.h>
int main ()
{
int i = 0;
while (i < 5)
{
Printf ("La variable i vaut %d\n", i);
i++;
}
return 0;
}
Au départ, notre variable i vaut zéro. Étant donné que zéro est bien inférieur à cinq, la
condition est vraie, le corps de la boucle est donc exécuté. La valeur de i est affichée,
i est augmentée d’une unité et vaut désormais un. La condition de la boucle est de
16 | P a g e
nouveau vérifiée. Ces étapes vont ainsi se répéter pour les valeurs un, deux, trois et
quatre. Quand la variable i vaudra cinq, la condition sera fausse, et l’instruction while
sera alors passée.
Exercice :
Réaliser un programme qui détermine si un nombre entré par l’utilisateur est premier.
Pour rappel, un nombre est dit premier s’il n’est divisible que par un et par lui-même.
Notez que si un nombre x est divisible par y alors le résultat de l’opération x % y est
nul.
b. La boucle do-while
La boucle do while fonctionne comme la boucle while, à un petit détail près : elle
s’exécutera toujours au moins une fois, alors qu’une boucle while peut ne pas
s’exécuter si la condition est fausse dès le départ.
Syntaxe :
do
{
/* Bloc d'instructions à répéter */
} while (/* Condition */);
Si vous n’avez qu’une seule instruction à exécuter, les accolades sont facultatives.
do
Exemple :
# include <stdio.h>
# include <stdlib.h>
int main ()
{
int i = 0;
do
{
17 | P a g e
Printf ("La variable i vaut %d\n", i);
++i;
} while (i < 5);
return 0;
}
c. La boucle for
Une boucle for se décompose en trois parties :
une expression et/ou une déclaration qui sera le plus souvent l’initialisation
d’une variable ;
une condition ;
une seconde expression, qui consistera le plus souvent en l’incrémentation
d’une variable.
Syntaxe :
/* Instructions à répéter */
Comme pour les deux autres boucles, si le corps ne comporte qu’une seule
instruction, les accolades ne sont pas nécessaires.
Exemple :
# include <stdio.h>
# include <stdlib.h>
int main()
{
for (int i = 0; i < 5; ++i)
printf ("la variable i vaut %d\n", i);
return 0;
18 | P a g e
}
Notez bien que la déclaration int i = 0 est située en dehors du corps de la boucle. Elle
n’est donc pas exécutée à chaque tour.
Si vous déclarez une variable au sein de l’instruction for, celle-ci ne sera utilisable
qu’au sein de cette boucle.
Exemple :
# include <stdio.h>
# include <stdlib.h>
int main ()
printf ("i = %d\n", i); /* Faux, i n'est pas utilisable hors de la boucle for */
return 0;
Imbrication :
Exemple :
19 | P a g e
for (int i = 0; i < 1000; ++i)
/* Code */
3. Les sauts
Dans les chapitres précédents, nous avons vu comment modifier l’exécution de notre
programme en fonction du résultat d’une ou plusieurs conditions. Ainsi, nous avons
pu réaliser des tâches plus complexes que de simplement exécuter une suite
d’instructions de manière linéaire.
Cette exécution non linéaire est possible grâce à ce que l’on appelle des sauts. Un
saut correspond au passage d’un point à un autre d’un programme. Bien que cela
vous ait été caché, sachez que vous en avez déjà rencontré ! En effet, une instruction
if réalise par exemple un saut à votre insu.
/* Bloc */
}
/* Suite du programme */
/* Bloc à répéter */
20 | P a g e
}
/* Suite du programme */
Dans cet exemple, si la condition est vraie, le bloc qui suit est exécuté puis il y a un
saut pour revenir à l’évaluation de la condition. Si en revanche elle est fausse, comme
pour l’instruction if, il y a un saut au-delà du bloc d’instructions.
Tous ces sauts sont cependant automatiques et vous sont cachés. Dans ce chapitre,
nous allons voir comment réaliser manuellement des sauts à l’aide de trois instructions
: break, continue et goto.
a. L’instruction break
Nous avons déjà rencontré l’instruction break lors de la présentation de l’instruction
switch, cette dernière permettait de quitter le bloc d’un switch pour reprendre
immédiatement après.
Cependant, l’instruction break peut également être utilisée au sein d’une boucle pour
stopper son exécution (autrement dit pour effectuer un saut au-delà du bloc à répéter).
Le plus souvent, une instruction break est employée pour sortir d’une itération
lorsqu’une condition (différente de celle contrôlant l’exécution de la boucle) est
remplie. Par exemple, si nous souhaitons réaliser un programme qui détermine le plus
petit diviseur commun de deux nombres, nous pouvons utiliser cette instruction
comme suit.
#include <stdio.h>
#include <stdlib.h>
int main()
int a;
int b;
21 | P a g e
for (int i = 2; i <= min; ++i)
if (a % i == 0 && b % i == 0)
break;
return 0;
Comme vous le voyez, la condition principale permet de progresser parmi les diviseurs
possibles alors que la seconde détermine si la valeur courante de i est un diviseur
commun. Si c’est le cas, l’exécution de la boucle est stoppée et le résultat affiché.
Dans le cas où il n’y a aucun diviseur commun, la boucle s’arrête lorsque le plus petit
des deux nombres est atteint.
b. L’instruction continue
L’instruction continue permet d’arrêter l’exécution de l’itération courante. Autrement
dit, celle-ci vous permet de retourner (sauter) directement à l’évaluation de la
condition.
Afin d’améliorer un peu l’exemple précédent, nous pourrions passer les cas où le
diviseur testé est un multiple de deux (puisque si un des deux nombres n’est pas
divisible par deux, il ne peut pas l’être par quatre, par exemple).
#include <stdio.h>
#include <stdlib.h>
int main()
int a;
int b;
22 | P a g e
printf ("Entrez deux nombres : ");
if (i != 2 && i % 2 == 0)
continue;
if (a % i == 0 && b % i == 0)
break;
return 0;
Remarques :
23 | P a g e
break dans une boucle imbriquée dans une autre, vous sortirez de la première,
mais pas de la seconde.
Exemple :
#include <stdio.h>
#include <stdlib.h>
int main()
if (i * j == 1000)
return 0;
c. L’instruction goto
Nous venons de voir qu’il était possible de réaliser des sauts à l’aide des instructions
break et continue. Cependant, d’une part ces instructions sont confinées à une boucle
ou à une instruction switch et, d’autre part, la destination du saut nous est imposée (la
condition avec continue, la fin du bloc d’instructions avec break).
L’instruction goto permet de sauter à un point précis du programme que nous aurons
déterminé à l’avance. Pour ce faire, le langage C nous permet de marquer des
instructions à l’aide d’étiquettes (labels en anglais). Une étiquette n’est rien d’autre
qu’un nom choisi par nos soins suivie du caractère : . Généralement, par souci de
lisibilité, les étiquettes sont placées en retrait des instructions qu’elles désignent.
Exemple :
24 | P a g e
Reprenons (encore) l’exemple du calcul du plus petit commun diviseur. Ce dernier
aurait pu être écrit comme suit à l’aide d’une instruction goto.
#include <stdio.h>
#include <stdlib.h>
int main()
int a;
int b;
int i;
if (a % i == 0 && b % i == 0)
goto trouve;
return 0;
trouve:
return 0;
Comme vous le voyez, l’appel à la fonction printf() a été marqué avec une étiquette
nommée
trouve. Celle-ci est utilisée avec l’instruction goto pour spécifier que c’est à cet endroit
que nous souhaitons nous rendre si un diviseur commun est trouvé. Vous
remarquerez également que nous avons désormais deux instructions return, la
première étant exécutée dans le cas où aucun diviseur commun n’est trouvé.
25 | P a g e
Exercice 1 :
Réaliser un programme qui calcule la somme de tous les nombres compris entre un
et n (n étant une constante déterminée par vos soins). Autrement dit, pour un nombre
n donné, vous allez devoir calculer 1 + 2 + 3 + ::: + (n − 2) + (n − 1) + n.
Exercice 2 :
Réaliser un programme qui détermine la liste des nombres dont le produit vaut mille.
26 | P a g e
IV. Les fonctions
1. Définition
Une fonction est une suite d’instructions ; elle est marquée à l’aide d’un nom (comme
une variable) et a vocation à être exécutée à plusieurs reprises ;
Elle rassemble des instructions qui permettent d’effectuer une tâche précise (comme
afficher du texte à l’écran, calculer la racine carrée d’un nombre, …).
Exemple : Code qui permet de calculer le plus petit commun diviseur de deux nombres
donnés
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a;
int b;
printf ("Entrez deux nombres : ");
scanf ("%d %d", &a, &b);
int min = (a < b) ? a : b;
for (int i = 2; i <= min; ++i)
if (a % i == 0 && b % i == 0)
{
printf ("Le plus petit diviseur de %d et %d est %d\n", a, b, i);
break;
}
return 0;
}
Imaginons à présent que nous souhaitions faire la même chose, mais avec deux
paires de nombres. Le code ressemblerait alors à ceci.
#include <stdio.h>
27 | P a g e
#include <stdlib.h>
int main()
{
int a;
int b;
if (a % i == 0 && b % i == 0)
break;
min = (a < b) ? a : b;
if (a % i == 0 && b % i == 0)
break;
return 0;
28 | P a g e
Comme vous le voyez, ce n’est pas très pratique : nous devons recopier les
instructions de calcul deux fois, ce qui est assez dommage et qui plus est source
d’erreurs. C’est ici que les fonctions entrent en jeu en nous permettant par exemple
de rassembler les instructions dédiées au calcul du plus petit diviseur commun en un
seul point que nous solliciterons autant de fois que nécessaire.
- son nom : les règles sont les mêmes que pour les variables ;
- son corps (son contenu) : le bloc d’instructions à exécuter ;
- son type de retour : le type du résultat de la fonction ;
- d’éventuels paramètres : des valeurs reçues par la fonction lors de l’appel.
/* Corps de la fonction */
#include <stdio.h>
#include <stdlib.h>
void bonjour(void)
printf("Bonjour !\n");
int main(void)
bonjour();
29 | P a g e
return 0;
Comme vous le voyez, la fonction se nomme « bonjour » et est composée d’un appel
à printf ().
Les deux mots-clés void :
a. Le type de retour
Le type de retour permet d’indiquer deux choses : si la fonction retourne une valeur et
le type de cette valeur.
#include <stdio.h>
#include <stdlib.h>
int deux(void)
return 2;
int main(void)
return 0;
Dans l’exemple ci-dessus, la fonction deux () est définie comme retournant une valeur
de type int. Vous retrouvez l’instruction return, une instruction de saut (comme break,
continue et goto). Ce return arrête l’exécution de la fonction courante et provoque un
retour (techniquement, un saut) vers l’appel à cette fonction qui se voit alors attribuer
la valeur de retour (s’il y en a une). Autrement dit, dans notre exemple, l’instruction
30 | P a g e
return 2 stoppe l’exécution de la fonction deux () et ramène l’exécution du programme
à l’appel qui vaut désormais 2, ce qui donne finalement printf("Retour : %d\n", 2).
b. Les paramètres
Un paramètre sert à fournir des informations à la fonction lors de son exécution. La
fonction printf() par exemple récupère ce qu’elle doit afficher dans la console à l’aide
de paramètres. Ceux-ci sont définis de la même manière que les variables si ce n’est
que les définitions sont séparées par des virgules.
Vous pouvez utiliser un maximum de 127 paramètres, toutefois nous vous conseillons
de vous limiter à cinq afin de conserver un code concis et lisible.
Maintenant que nous savons tout cela, nous pouvons réaliser une fonction qui calcule
le plus petit commun diviseur entre deux nombres et ainsi simplifier l’exemple du
dessus.
#include <stdio.h>
#include <stdlib.h>
if (a % i == 0 && b % i == 0)
return i;
return 0;
int main()
int a;
int b;
31 | P a g e
scanf("%d %d", &a, &b);
if (resultat != 0)
if (resultat != 0)
return 0;
#include <stdio.h>
#include <stdlib.h>
++nombre;
32 | P a g e
int main(void)
int nombre = 5;
fonction(nombre);
return 0;
Comme vous le voyez, les deux variables nombre sont bel et bien distinctes. En fait,
lors d’un appel de fonction, vous spécifiez des arguments à la fonction appelée. Ces
arguments ne sont rien d’autre que des expressions dont les résultats seront ensuite
affectés aux différents paramètres de la fonction.
3. Les prototypes
Jusqu’à présent, nous avons toujours défini notre fonction avant la fonction main ().
Cela paraît logique (nous définissons la fonction avant de l’utiliser), cependant cela
est, surtout indispensable. En effet, si nous déplaçons la définition après la fonction
main (), le compilateur se retrouve dans une situation délicate : il est face à un appel
de fonction dont il ne sait rien (nombre d’arguments, type des arguments et type de
retour). II serait possible de stopper la compilation, mais le compilateur va considérer
que la fonction retourne une valeur de type int et qu’elle reçoit un nombre indéterminé
d’arguments.
Pour résoudre ce problème, il est possible de déclarer une fonction à l’aide d’un
prototype.
33 | P a g e
Celui-ci permet de spécifier le type de retour de la fonction, son nombre d’arguments
et leur type, mais ne comporte pas le corps de cette fonction. La syntaxe d’un
prototype est la suivante :
#include <stdio.h>
#include <stdlib.h>
void bonjour(void);
int main(void)
bonjour();
return 0;
void bonjour(void)
printf("Bonjour !\n");
34 | P a g e
À la place, il est possible de définir une variable dite « globale » qui sera utilisable par
toutes les fonctions. Pour définir une variable globale, il vous suffit de définir une
variable en dehors de tout bloc, autrement dit en dehors de toute fonction.
#include <stdio.h>
#include <stdlib.h>
int compteur = 0;
void incrementer()
compteur++;
int main()
incrementer();
incrementer();
incrementer();
return 0;
35 | P a g e
La variable globale int compteur = 0 est définie en dehors de toute fonction ; Elle est
accessible dans tout le fichier, aussi bien dans main que dans incrementer .
Résultat :
#include <stdio.h>
#include <stdlib.h>
void incrementer()
compteur++;
int main()
incrementer();
incrementer();
incrementer();
return 0;
36 | P a g e
À chaque appel, une nouvelle variable est créée et initialisée à 0.
Les variables locales sont par défaut de classe de stockage automatique. Cela signifie
qu’elles sont allouées automatiquement à chaque fois que le bloc auquel elles
appartiennent est exécuté et qu’elles sont détruites une fois son exécution terminée.
if (a % i == 0 && b % i == 0)
return i;
return 0;
Par exemple, à chaque fois que la fonction ppcd() est appelée, les variables a, b, min
sont allouées en mémoire vive et détruites à la fin de l’exécution de la fonction. La
variable i quant à elle est allouée au début de la boucle for et détruite à la fin de cette
dernière.
Les variables globales sont toujours de classe de stockage statique. Ceci signifie
qu’elles sont allouées au début de l’exécution du programme et sont détruites à la fin
de l’exécution de celui-ci.
En conséquence, elles conservent leur valeur tout au long de l’exécution du
programme.
37 | P a g e
Exercice : Afficher un rectangle de longueur et largeur entrées au clavier par
l’utilisateur.
Voici ce que devra donner l’exécution de votre programme pour une longueur de 5 et
une largeur de 3.
***
***
***
***
***
Une portée au niveau d’un bloc signifie qu’une variable est utilisable, visible de sa
déclaration jusqu’à la fin du bloc dans lequel elle est déclarée.
#include <stdio.h>
#include <stdlib.h>
int main(void)
int nombre = 3;
printf("%d\n", nombre);
/* Incorrect ! */
38 | P a g e
printf("%d\n", nombre);
return 0;
Dans ce code, la variable nombre est déclaré dans un sous-bloc. Sa portée est donc
limitée à ce dernier et elle ne peut pas être utilisée en dehors.
Une portée au niveau d’un fichier signifie qu’une variable est utilisable, visible, de sa
déclaration jusqu’à la fin du fichier dans lequel elle est déclarée. En fait, il s’agit de la
portée des variables « globales ».
#include <stdio.h>
#include <stdlib.h>
int nombre = 3;
int triple(void)
return nombre * 3;
int main(void)
nombre = triple();
printf("%d\n", nombre);
return 0;
Dans ce code, la variable nombre a une portée au niveau du fichier et peut par
conséquent être aussi bien utilisée dans la fonction triple() que dans la fonction main().
39 | P a g e
b. La notion de masquage
En voyant les deux types de portées, vous vous êtes peut-être posé la question
suivante : que se passe-t-il s’il existe plusieurs variables de même nom ? Cela dépend
de la portée de ces dernières. Si elles ont la même portée comme dans l’exemple ci-
dessous, alors le compilateur sera incapable de déterminer à quelle variable ou à
quelle fonction le nom fait référence et, dès lors, retournera une erreur.
En revanche, si elles ont des portées différentes, alors celle ayant la portée la plus
petite sera privilégiée, on dit qu’elle masque celles de portées plus grandes.
Autrement dit, dans l’exemple qui suit, c’est la variable du bloc de la fonction main()
qui sera affichée.
#include <stdio.h>
#include <stdlib.h>
int main()
printf("%d\n", nombre);
return 0;
Notez que nous disons : « celles de portée plus petite », car les variables déclarées
dans un sous-bloc ont une portée plus limitée (car confinée au sous-bloc) que celle
déclarée dans un bloc supérieur. Ainsi, le code ci-dessous est parfaitement valide et
affichera 30.
#include <stdio.h>
#include <stdlib.h>
int main()
40 | P a g e
{
if (nombre == 20)
printf("%d\n", nombre);
return 0;
41 | P a g e