0% ont trouvé ce document utile (0 vote)
14 vues41 pages

02 Programmation C

Ce document est un cours sur la programmation en C et C++, couvrant les bases du langage, les structures de contrôle, les fonctions, les pointeurs, les tableaux et les chaînes de caractères. Il explique les concepts fondamentaux tels que les variables, les types de données, les opérateurs, ainsi que les méthodes d'interaction avec l'utilisateur. Des exemples de code illustrent chaque concept pour faciliter la compréhension.

Transféré par

remymvomo1
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
14 vues41 pages

02 Programmation C

Ce document est un cours sur la programmation en C et C++, couvrant les bases du langage, les structures de contrôle, les fonctions, les pointeurs, les tableaux et les chaînes de caractères. Il explique les concepts fondamentaux tels que les variables, les types de données, les opérateurs, ainsi que les méthodes d'interaction avec l'utilisateur. Des exemples de code illustrent chaque concept pour faciliter la compréhension.

Transféré par

remymvomo1
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

COURS SUR LA PROGRAMMATION EN C et C++

Programme :

I. Présentation du Langage C ................................................................................ 2

II. Les bases du langage C ..................................................................................... 6

III. Les structures de contrôle .............................................................................. 11

IV. Les fonctions .................................................................................................. 27

V. Les pointeurs..................................................................................................... 42

VI. Les tableaux ................................................................................................... 42

VII. Les chaines de caractères.............................................................................. 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.

Un programme est une séquence d’instructions, d’ordres, donnés à notre ordinateur


afin qu’il exécute des actions.

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.

Ces instructions sont exécutées par un composant précis de l’ordinateur : le


processeur.

2. Les outils nécessaires


Les outils nécessaires pour programmer en C sont :

 Un éditeur de texte : pour écrire le code source du programme. Exemple :


Notepad++, Sublime Text, Visual Studio Code (VS Code) sous Windows ;
 Un compilateur : pour transformer une source en binaire ;
 Un débogueur pour vous aider à traquer les erreurs dans votre programme.

Pour cela on utilise un IDE (Environnement de Développement Intégré) qui est un


programme 3 en 1 qui combine : éditeur de texte, compilateur et débogueur. (Code
Blocks dans le cadre de ce cours).

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.

Printf ("Hello word!\n"); demande à l’ordinateur d’afficher le message «Hello word!»


à l’écran. Quand le programme arrivera à cette ligne il va donc afficher un message à
l’écran, puis passer à l’instruction suivante :

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.

Pour afficher le message « Bonjour » à l’écran il suffit de remplacer « Hello Word! »


par « Bonjour » dans la ligne qui fait appel à printf.

Printf est une instruction qui commande à l’ordinateur « affiche ce message à l’écran».

La bibliothèque stdio.h contient la fonction printf.

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 :

 Ouvrez des guillemets à l’intérieur des parenthèses


 Tapez le texte à afficher entre ces guillemets

Printf ("Bonjour") ;

c. Les caractères spéciaux


Ils permettent d’indiquer qu’on veut aller à la ligne, faire une tabulation…C’est un
ensemble de deux caractères : le premier est toujours un antislash \, le second un
nombre ou une lettre.

 \n : saut à la ligne suivante


 \t : tabulation horizontale

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

Exemple : Printf ("Bonjour") ; // Affiche Bonjour à l’écran

 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.

Exemple : /*Ceci est un commentaire

sur plusieurs lignes*/.

Lors de la compilation, tous les commentaires sont ignorés. Ces commentaires


n’apparaitront pas dans le programme final.

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.

Type Valeur stockée


int Un entier
short int Un entier
float Un réel
double Un réel
char Un caractère
bool Un booléen
array Tableau de variables du même type
pointer Pointeur, adresse mémoire d’une variable
struct Structure regroupant plusieurs variables

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 :

 seules les 26 lettres de l’alphabet latin (majuscules ou minuscules), le trait de


soulignement « _ » (underscore en anglais) et les chiffres sont acceptés ;
 Pas d’accents, pas de ponctuation ni d’espaces ;
 un identificateur ne peut pas commencer par un chiffre.

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 de noms de variables : NombreDeVies, Numero_de_telephone, nom,


prenom…

d. Déclarer une variable


Une variable est déclarée en spécifiant son type, son nom et éventuellement sa valeur
initiale.

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

3. Interagir avec l’utilisateur


a. Printf ()
La fonction Printf est une fonction qui permet d’afficher des informations à l’écran.

Syntaxe : Printf ("chaîne de format", argument1, argument2, ...);

"chaîne de format" : contient du texte à afficher et des spécificateurs de format


(%type).

%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.

arguments : les variables ou valeurs à insérer dans la chaîne, en correspondance


avec les spécificateurs.

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.

Syntaxe : Scanf ("chaîne de format", &variable1, &variable2, ...);


9|Page
"chaîne de format" : contient des spécificateurs de format.

&variable : adresse de la variable où est stockée la donnée saisie.

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.

1. Structures de contrôle conditionnelles


a. If (Si)
Elle exécute un bloc de code si une condition est vraie.

Syntaxe :

 Commencer par écrire "If" ;


 Ouvrez des parenthèses (écrire une condition à l’intérieur) ;
 Ouvrez une accolade {puis la refermer plus loin}, tout ce qui se trouve à
l’intérieur des accolades sera exécuté uniquement si la condition est vérifiée.

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;
}

Ici, la valeur de la variable a est comparée successivement avec chaque entrée de la


liste, indiquées par le mot-clé case. En cas de correspondance, les instructions suivant
le mot-clé case sont exécutées jusqu’à rencontrer une instruction break. Si aucune
comparaison n’est bonne, alors ce sont les instructions de l’entrée marquée avec le
mot-clé default qui seront exécutées.

#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", &note);
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.

Syntaxe : (condition) ? expression si vrai : expression si faux

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 :

Imaginez que vous avez un score de jeu vidéo sous la main :

 si le score est strictement inférieur à deux cent, affichez « C’est la


catastrophe!»;
 si le score est supérieur ou égal à deux cent et que le score est strictement
inférieur à cinq cent, affichez : « Tu peux mieux faire!»;
 si le score est supérieur ou égal à cinq cent et que le score est strictement
inférieur à neuf cent, affichez : « Tu es sur la bonne voie!»;
 sinon, affichez : « Tu es le meilleur!».

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.

while (/* Condition */)

/* Une seule instruction */

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

/* Une seule instruction */

while (/* Condition */);

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 :

for (/* Expression/Déclaration */; /* Condition */; /* Expression */)

/* 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.

for (/* Expression/Déclaration */; /* Condition */; /* Expression */)

/* Une seule instruction */

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 ()

for (int i = 0; i < 5; ++i)

printf ("la variable i vaut %d\n", i);

printf ("i = %d\n", i); /* Faux, i n'est pas utilisable hors de la boucle for */

return 0;

Notez que le nombre de compteurs, de déclarations ou de conditions n’est pas limité,


comme le démontre la ligne suivante :

for (int i = 0, j = 2; i < 10 && j < 12; i++, j += 2)

Ici, nous définissons deux compteurs i et j initialisés respectivement à zéro et deux.


Le contenu de la boucle est exécuté tant que i est inférieur à dix et que j est inférieur
à douze, i étant augmentée de une unité et j de deux unités à chaque tour de boucle.
Le code est encore assez lisible, cependant la modération est de mise, un trop grand
nombre de paramètres rendant la boucle for illisible.

Imbrication :

Il est parfaitement possible d’imbriquer une ou plusieurs boucles en plaçant une


boucle dans le corps d’une autre boucle.

Exemple :

19 | P a g e
for (int i = 0; i < 1000; ++i)

for (int j = i; j < 1000; ++j)

/* 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.

if (/* Condition */)

/* Bloc */

}
/* Suite du programme */

Dans le cas où la condition est fausse, l’exécution du programme passe le bloc de


l’instruction if et exécute ce qui suit. Autrement dit, il y a un saut jusqu’à la suite du
bloc. Dans la même veine, une boucle while réalise également des sauts.

while (/* Condition */)

/* 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;

printf ("Entrez deux nombres : ");

scanf ("%d %d", &a, &b);

int min = (a < b) ? a : b;

21 | P a g e
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;

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).

Ceci peut s’exprimer à l’aide de l’instruction continue.

#include <stdio.h>

#include <stdlib.h>

int main()

int a;

int b;

22 | P a g e
printf ("Entrez deux nombres : ");

scanf("%d %d", &a, &b);

int min = (a < b) ? a : b;

for (int i = 2; i <= min; ++i)

if (i != 2 && i % 2 == 0)

printf ("je passe %d\n", i);

continue;

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;

Remarques :

 Dans le cas de la boucle for, l’exécution reprend à l’évaluation de sa deuxième


expression (ici ++i) et non à l’évaluation de la condition (qui a lieu juste après).
Il serait en effet mal venu que la variable i ne soit pas incrémenté lors de
l’utilisation de l’instruction continue.
 Notez bien que les instructions break et continue n’affectent que l’exécution de
la boucle dans laquelle elles sont situées. Ainsi, si vous utilisez l’instruction

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()

for (int i = 0 ; i <= 1000 ; ++i)

for (int j = i ; j <= 1000 ; ++j)

if (i * j == 1000)

printf ("%d * %d = 1000 \n", i, j);

break; /* Quitte la boucle courante, mais pas la première. */

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;

printf ("Entrez deux nombres : ");

scanf("%d %d", &a, &b);

int min = (a < b) ? a : b;

int i;

for (i = 2; i <= min; ++i)

if (a % i == 0 && b % i == 0)

goto trouve;

return 0;

trouve:

printf ("le plus petit diviseur de %d et %d est %d\n", a, b, i);

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, …).

printf(), scanf(), et main() sont des fonctions.

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;

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;

printf ("Entrez deux autres nombres : ");

scanf ("%d %d", &a, &b);

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;

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.

2. Définir et utiliser une fonction


Pour définir une fonction, nous allons devoir donner quatre informations sur celle-ci :

- 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.

La syntaxe est la suivante :

type nom (paramètres)

/* Corps de la fonction */

Prenons un exemple en créant une fonction qui affiche « bonjour! » à l’écran.

#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 :

- dans le cas du type de retour, il spécifie que la fonction ne retourne rien ;


- dans le cas des paramètres, il spécifie que la fonction n’en reçoit aucun (cela
se manifeste lors de l’appel : il n’y a rien entre les parenthèses).

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)

printf("Retour : %d\n", deux());

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>

int ppcd(int a, int b)

int min = (a < b) ? a : b;

for (int i = 2; i <= min; ++i)

if (a % i == 0 && b % i == 0)

return i;

return 0;

int main()

int a;

int b;

printf("Entrez deux nombres : ");

31 | P a g e
scanf("%d %d", &a, &b);

int resultat = ppcd(a, b);

if (resultat != 0)

printf("Le plus petit diviseur de %d et %d est %d\n", a,b, resultat);

printf("Entrez deux autres nombres : ");

scanf("%d %d", &a, &b);

resultat = ppcd(a, b);

if (resultat != 0)

printf("Le plus petit diviseur de %d et %d est %d\n", a,


b, resultat);

return 0;

Remarquez la présence de deux instructions return dans la fonction ppcd(). La valeur


zéro est retournée afin d’indiquer l’absence d’un diviseur commun.

c. Les arguments et les paramètres


Il est important de préciser qu’un paramètre est propre à une fonction, il n’est pas
utilisable en dehors de celle-ci. Par exemple, la variable a de la fonction ppcd() n’a
aucun rapport avec la variable a de la fonction main().

Voici un autre exemple plus explicite à ce sujet.

#include <stdio.h>

#include <stdlib.h>

void fonction(int nombre)

++nombre;

printf("Variable nombre dans `fonction' : %d\n", nombre);

32 | P a g e
int main(void)

int nombre = 5;

fonction(nombre);

printf("Variable nombre dans `main' : %d\n", 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.

Ainsi, la valeur de la variable nombre de la fonction main() est passée en argument à


la fonction fonction() et est ensuite affectée au paramètre nombre. La variable nombre
de la fonction main() n’est donc en rien modifiée.

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.

Toutefois, si cette décision a l’avantage d’éviter un arrêt de la compilation, elle peut


en revanche conduire à des problèmes lors de l’exécution si cette supposition du
compilateur s’avère inadéquate. Or, il serait pratique de pouvoir définir les fonctions
dans l’ordre que nous souhaitons sans se soucier de qui doit être défini avant qui.

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 :

type nom (paramètres);

#include <stdio.h>

#include <stdlib.h>

void bonjour(void);

int main(void)

bonjour();

return 0;

void bonjour(void)

printf("Bonjour !\n");

Notez bien le point-virgule à la fin du prototype qui est obligatoire.

4. Variables globales et classes de stockage


a. Les variables globales
Il arrive parfois que l’utilisation de paramètres ne soit pas adaptée et que des fonctions
soient amenées à travailler sur des données qui doivent leur être communes. Prenons
un exemple simple : vous souhaitez compter le nombre d’appels de fonction réalisé
durant l’exécution de votre programme. Ceci est impossible à réaliser, sauf à définir
une variable dans la fonction main(), la passer en argument de chaque fonction et de
faire en sorte que chaque fonction retourne sa valeur augmentée de un, ce qui est
très peu pratique.

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>

// Déclaration d'une variable globale

int compteur = 0;

// Fonction qui incrémente la variable globale

void incrementer()

compteur++;

printf("Compteur après incrémentation : %d\n", compteur);

int main()

printf("Valeur initiale du compteur : %d\n", compteur);

// Appels successifs à la fonction

incrementer();

incrementer();

incrementer();

printf("Valeur finale du compteur : %d\n", compteur);

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 .

La Fonction incrementer modifie directement la variable globale sans avoir besoin de


paramètre ni de valeur de retour.

Résultat :

Valeur initiale du compteur : 0

Compteur après incrémentation : 1

Compteur après incrémentation : 2

Compteur après incrémentation : 3

Valeur finale du compteur : 3

#include <stdio.h>

#include <stdlib.h>

void incrementer()

int compteur = 0; // variable locale

compteur++;

printf("Compteur (local) : %d\n", 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.

Résultat : la sortie sera toujours compteur (local) : 1.

b. Les classes de stockage


Les variables locales et les variables globales ont une autre différence de taille : leur
classe de stockage. La classe de stockage détermine (entre autre) la durée de vie
d’un objet, c’est-à-dire le temps durant lequel celui-ci existera en mémoire.

 Classe de stockage automatique

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.

int ppcd(int a, int b)

int min = (a < b) ? a : b;

for (int i = 2; i <= min; ++i)

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.

 Classe de stockage statique

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.

***

***

***

***

***

5. Découper son projet


a. La notion de portée
Avant de voir comment diviser nos programmes en plusieurs fichiers, il est nécessaire
de vous présenter une notion importante, celle de portée. La portée d’une variable est
la partie du programme où cette dernière est utilisable.

- au niveau d’un bloc ;

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.

- au niveau d’un fichier.

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 nombre = 10;

int main()

int nombre = 20;

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 nombre = 10;

int main()

40 | P a g e
{

int nombre = 20;

if (nombre == 20)

int nombre = 30;

printf("%d\n", nombre);

return 0;

41 | P a g e

Vous aimerez peut-être aussi