Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

الدرس الأول

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 31

République Algérienne démocratique et Populaire

Ministère de l’Enseignement Supérieure et de la Recherche Scientifique


Université Echahid hamma Lakhdar-El Oued
Faculté de technologie

COURS D’INFORMATIQUE 2

LANGAGE C

M. Berhoum Adel

2020/2021
2

PLAN DU COURS
I. Introduction

II. Notions de bases

III. Types de base, opérateurs, expressions

IV. Lecture et écriture de données

V. La structure alternative

Informatique 2 Langage C - Notes de cours 2020/2021


3

Chapitre I – Introduction

Le langage C a connu une croissance en popularité énorme ces dernières années.


On trouve ses sources en 1972, dans les laboratoires Bell, afin de développer une version portable
du système d'exploitation Unix. C'est un langage de programmation structuré, mais très "près"
de la machine.
Publication en 1978 de "The C programming language" par Kernighan et Ritchie: définition
classique du C.
Le développement de compilateurs C par d'autres maisons ont rendu nécessaire la définition d'un
standard précis : le standard ANSI-C.
1983: Développement du C++
1988: Seconde édition du livre "The C programming language"
1990: Standard ANSI-C++
Le succès du C est dû aux faits que :
- C'est un langage universel : C n'est pas orienté vers un domaine d'applications spécifique (au
contraire du FORTRAN: applications scientifiques, COBOL: applications commerciales). -
C'est un langage compact: C est basé sur un noyau de fonctions et d'opérateurs limités,
permettant la formulation d'expressions simples et efficaces.
- Il est près de la machine : comme il a été développé initialement pour programmer le système
UNIX, il offre des opérateurs très proches de ceux du langage machine et des fonctions qui
permettent un accès simple et direct aux fonctions internes de l'ordinateur (par exemple la
mémoire).
- Il est rapide : puisqu'il est près de la machine.
- Il est portable : en respectant le standard ANSI-C il est possible d'utiliser le même programme
sur tout autre système d'exploitation en possession d'un compilateur C. C est devenu
aujourd'hui le langage de programmation des micro-ordinateurs.
- Il est extensible : C ne se compose pas seulement des fonctions standard, le langage est animé
par des bibliothèques de fonctions privées ou livrées par de nombreuses maisons de
développement.

Dés avantage :
- La possibilité d'expressions compactes entraîne le risque de se retrouver avec des programmes
incompréhensibles (pour les autres, mais aussi pour nous-même), d'où la nécessité d'inclure des
commentaires dans les programmes.
- C’est langage proche de la machine, il est donc dangereux. Bien qu'il soit un langage de
programmation structuré, il ne nous oblige pas à adopter un style de programmation (comme,
par exemple le PASCAL). Le programmateur a donc beaucoup de libertés, mais aussi des
responsabilités : il doit veiller à adopter un style de programmation propre, solide et
compréhensible.
-

Informatique 2 Langage C - Notes de cours 2020/2021


4

Chapitre II – Notions de base

1) Bibliothèques de fonctions

La pratique du C exige l'utilisation de bibliothèques de fonctions. Ces bibliothèques sont


disponibles sous forme précompilées (.lib). Afin de pouvoir les utiliser, il faut inclure des fichiers
en-tête (.h) dans nos programmes. Ces fichiers contiennent les prototypes des fonctions
prédéfinies dans les bibliothèques et créent un lien entre les fonctions précompilées et nos
programmes.
Pour inclure les fichiers en-tête:
#include <fichier.h>
Pour le compilateur que nous utiliserons, différents types de fichiers seront identifiés par leurs
extensions:
.c : fichier source
.obj : fichier compilé
.exe : fichier exécutable
.lib : bibliothèque de fonctions précompilées
.h : bibliothèque en-tête

2) Composantes d'un programme en C

- La fonction main
Elle constitue le programme principal :
main()
{
déclaration des variables instructions
}

- Les fonctions
Type_du_resultat Nom_fonction (Type_param Nom_param,…)
{
déclaration des variables locales instructions
}

- Les identificateurs
Les noms des fonctions et des variables en C sont composés d'une suite de lettres et de chiffres:
- le premier caractère doit être une lettre
- L'ensemble des symboles utilisables est: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, …., x, y, z, A,
B, C, …., X, Y, Z, _}
- Le C distingue les minuscules et les majuscules
- La longueur des identificateurs n'est pas limitée, mais le C distingue des 31 premiers
caractères
Remarque:
Il est déconseillé d'utiliser le symbole "_" comme premier caractère pour un identificateur, car il
est souvent employé pour définir les variables globales de l'environnement C.

Informatique 2 Langage C - Notes de cours 2020/2021


5

Exercice 1

- Les commentaires
Un commentaire commence toujours par les deux symboles /* et se termine par les deux
symboles*/. Il est interdit d'utiliser des commentaires imbriqués.
Exemple:
/* ceci est un commentaire correct */
/* ceci est /* évidemment */ incorrect */

- Les variables
Type_variable Nom_variable

3) Premier programme en C

Le classique "bonjour" (affiche bonjour à l'écran). Pour le faire, il faut:


- Inclure les bibliothèques
- Inclure le main main() {
déclaration des variables:
aucune instruction:
écrire "bonjour" }

La fonction prédéfinie qui permet d'écrire à l'écran est printf, elle est contenue dans le fichier
en-tête stdio.h; sa syntaxe est: printf("ce que l'on veut écrire");

Voici donc notre premier programme:


#include <stdio.h> main()
{
printf("bonjour\n"); /*toute instruction se termine par un point virgule*/
}
Remarque: les séquences d'échappement
La suite de symboles \n à la fin de la chaîne de caractère est la notation C signifiant le passage à
la ligne (n comme new ligne). Il existe en C plusieurs couples de symboles qui contrôlent
l'affichage ou l'impression du texte. Les séquences d'échappement sont toujours précédées par le
caractère d'échappement "\".

\t tabulation
\n nouvelle ligne
\b batch (curseur arrière)
\r return (retour au début de ligne, sans saut de ligne)
\a attention (signal acoustique)

Si l'on veut écrire le symbole " ou \: \" et \\

Informatique 2 Langage C - Notes de cours 2020/2021


6

Chapitre III – Types de base, opérateurs, expressions


On trouvera dans un programme des variables et des constantes, il faut fixer leurs types. Pour
produire de nouvelles valeurs, les variables et les constantes peuvent être combinées à l'aide
d'opérateurs dans des expressions.

1) Les types de base

En mathématiques, on distingue divers ensembles de nombres (entiers naturels, entiers relatifs,


réels, complexes,…). L'ordre de grandeur des nombres est illimité, ils peuvent être exprimés sans
perte de précision. Un ordinateur utilise le système binaire pour sauvegarder et calculer les
nombres, il existe pour un ordinateur deux grands systèmes de nombres: les entiers et les
rationnels.

- Les entiers
Définition Description Valeur min Valeur max Nombre d'octets
char caractère -128 127 1
short entier court -32768 32767 2
int entier standard -32768 32767 2
long Entier long -2147483648 2147483647 4

Si l'on ajoute le préfixe unsigned (non signé), les domaines sont déplacés ainsi :
Définition Valeur min Valeur max
unsigned char 0 255
unsigned short 0 65535
unsigned int 0 65535
unsigned long 0 4294967295
Les valeurs des limites des différents types sont indiquées dans le fichier limits.h.

- Les rationnels
Définition Précision Mantisse* Valeur min Valeur max Nb d'octets
-38 +38
float simple 6 3,4.10 3,4.10 4
double double 15 1,7.10-308 1,7.10+308 8
-4932 +4932
long double avancée 19 3,4.10 1,1.10 10
*
La mantisse est le nombre de chiffres significatifs après la virgule.
- Les variables booléennes
Il n'existe pas de type spécifique pour les variables booléennes, tous les types de variables
numériques peuvent être utilisés pour exprimer des opérations logiques:
La variable logique FAUX correspond à la valeur numérique 0. La variable logique VRAI
correspond toute valeur différente de 0.

- Déclaration de variables Syntaxe:


type nom;
On peut déclarer plusieurs variables d'un même type: Exemple:
int a, b, c;
On peut initialiser une variable lors de sa déclaration:

Informatique 2 Langage C - Notes de cours 2020/2021


7

Exemple:
float pi = 3.14;

2) Les opérateurs standards

- L'affectation (=)
Nom_variable=expression;
Affectation avec des valeurs constantes:
Pi = 3.1416;
Lettre = 'L';
Affectation avec des valeurs variables:
a=b;
Affectation avec des expressions: voir la suite des opérateurs

- Les opérateurs arithmétiques


+ addition
- soustraction
*
multiplication
/ division
% modulo (reste de la division entière) (par exemple, 5%2=1)

- Les opérateurs logiques


&& ET
|| OU
! NON
Les résultats des opérations logiques sont de type int: la valeur 0 correspond à la valeur booléenne
FAUX, la valeur 1 correspond à la valeur booléenne VRAI.

- Les opérateurs de comparaison


== EGALITE != INEGALITE
< INFERIEUR <= INFERIEUR OU EGAL
> SUPERIEUR >= SUPERIEUR OU EGAL
Les résultats des opérations de comparaison sont de type int: la valeur 0 correspond à la valeur
booléenne FAUX, la valeur 1 correspond à la valeur booléenne VRAI
Les opérateurs logiques considèrent toute valeur différente de 0 comme VRAI, toute valeur nulle
comme FAUX.
Exemple :
32&&2.3 → 1
!65,43 → 0
0||!(32>12) → 1
Les expressions sont constituées de variable ou constantes combinées entre elles par des
opérateurs.
Exemple :
aire = pi*R*R; moyenne
= (A+B)/2
plus_grand = (x>y) (la variable plus_grand est une variable logique qui vaut 1 (resp. 0) si x
est supérieur (resp. inférieur) à y)

Informatique 2 Langage C - Notes de cours 2020/2021


8

- L'opérateur
d'affectation i = i + 2;
En C, on peut écrire: i+
= 2;
Pour la plupart des expressions de la forme: expr1 = (expr1) Opérateur (expr2);
Il existe une formulation équivalente:expr1 Opérateur = expr2; Cette
formulation (i+ = 2) suit la logique humaine: on ajoute 2 à i.
L'opérateur d'affectation aide le compilateur à générer un code plus efficace car expr1 n'est
évalué qu'une fois.

- L'opérateur
d'incrémentation et de
décrémentation
i=i+1 s'écrit: i++ ou ++i i
=i-1 s'écrit: i-- ou --i
Les opérateurs ++ et -- sont utilisés:
- pour incrémenter ou décrémenter une variable, par exemple dans une boucle (dans ce cas,
pas de différence entre la notation préfixe (++i,--i) et la notation postfixe (i++,i--).
- pour incrémenter ou décrémenter une variable et en même temps affecter sa valeur à une
autre variable. Dans ce cas, on choisit entre la notation préfixe et postfixe:

X = i++; passe d'abord la valeur de i à X, puis incrémente i (le ++ est après i, on l'incrémente
après)
X = i--; passe d'abord la valeur de i à X, puis décrémente i
X = ++i; incrémente d'abord i puis passe la valeur de i incrémentée à X (le ++ est avant i, on
l'incrémente avant)
X = --i; décrémente d'abord i puis passe la valeur de i décrémentée à X
Exemple 1:
N = 5;
X = N++; Résultat: X = 5 et N = 6
Exemple 2: N
= 5;
X = ++N; Résultat: X = 6 et N = 6

- Priorités des opérateurs


L'ordre d'évaluation des différentes parties d'une expression correspond à celle que nous
connaissons en maths.
Exemple:
A = 3;
B = 4;
X = 2 * A + 3 * B;
6 + 12
18
Ensuite, on affecte 18 à X
Comme en maths, si l'on veut forcer l'ordinateur à commencer par un opérateur de priorité plus
faible, on entoure le terme par des parenthèses.
Exemple:

Informatique 2 Langage C - Notes de cours 2020/2021


9

A = 3;
B = 4;
X = 2 *(A + 3) * B;
2* 6
12 * 4
48

Classes de priorités:
Priorité 1 (la plus élevée) ()
Priorité 2 !, ++, --
Priorité 3 *, /, %
Priorité 4 +, -
Priorité 5 <, <=, >, >=
Priorité 6 ==, !=
Priorité 7 &&
Priorité 8 ||
Priorité 9 (la plus basse) =, +=, -=, *=, /=, %=

Dans chaque classe, les opérateurs ont la même priorité. Si on a une suite d'opérateurs binaires
de la même classe, l'évaluation se fait en passant de la gauche vers la droite.
: pour les opérateurs unaires (!, ++, --) et pour les opérateurs d'affectation, l'évaluation se fait
de la droite vers la gauche.
Exemple 1 :
10 + 20 + 30 – 40 sera évaluée comme suit:
10 + 20 ) → 30
30 + 30 → 60
60 – 40 → 20
Exemple 2 : pour A = 3 et B = 4 A* =
B+ = 5 sera évaluée comme suit:
B+ = 5 → B=9
A* = 9→ A = 27
Exemple 3 : pour A = 1 et B = 4
!- - A == ++!B sera évaluée comme suit:
- -A→ 0 !B → 0
!0 → 1 ++0 → 1
1 == 1 →1
Exemple 4 : X* = Y + 1 équivalent à X = X*(Y + 1)

Exercice 2

3) Conversions de type

- Calculs et affectations
Si un opérateur a des opérandes de types différents, les valeurs des opérandes sont converties
automatiquement dans un type commun. Cette conversion implicite s'effectue en général des
types "plus petits" vers les types "plus larges", afin de ne pas perdre en précision.

Informatique 2 Langage C - Notes de cours 2020/2021


10

Lors d'une affectation, la donnée à droite du signe "=" est convertie dans le type à gauche du
signe "=". Dans ce cas, il peut y avoir perte de précision. Exemple : int a =8; float x = 10.5;
double y; y = a*x;
La valeur de a est convertie en float pour pouvoir être multipliée à x. Le résultat de la
multiplication est de type float, mais avant d'être affectée à y, il est converti en double, il peut
donc y avoir une perte de précision.

- Appels de fonctions
Lors de l'appel d'une fonction, les paramètres sont automatiquement convertis dans les types
déclarés dans la définition de la fonction.
Exemple : int A
=8, Res; Res =
pow(A, 2);
Appel de pow(): 2 et A sont convertis en doubles, le résultat est double, il est converti en int pour
être affecté à Res.

- Règles de conversion lors d'une opération avec: - 2 entiers:


D'abord les types char et short sont convertis en int, ensuite, l'ordinateur choisit le plus
large des deux types selon l'échelle: int, unsigned int, long, unsigned long.
- Un entier et un rationnel:
Le type entier est converti dans le type du rationnel -
2 rationnels:
L'ordinateur choisit le plus large des deux types selon l'échelle: float, double, long
double.
- Affectation:
Lors d'une affectation, le résultat est toujours converti dans le type de la destination.
: si le type est plus faible, il peut y avoir perte de précision. Erreur classique: int A = 4, B
= 3; float C;
C = A / B;
A / B est entier (A et B sont int), donc A / B = 1, converti en float, C = 1!

Exercice 3

- Conversion de type forcée


Il est possible de convertir explicitement une valeur en un type quelconque:
(type) expression

Exemple:
int A = 4, B = 3; float
C;
C = (float)A / B;
Le contenu de A reste inchangé, seule la valeur utilisée dans le calcul est convertie.

Informatique 2 Langage C - Notes de cours 2020/2021


11

Chapitre IV – Lire et écrire des données


La bibliothèque standard <stdio.h> contient un ensemble de fonctions qui assurent la
communication de la machine avec le monde extérieur.

Les fonctions les plus importantes sont:


Pour la lecture: Pour l'écriture:
printf(): écriture formatée de données scanf(): lecture formatée de données
putchar(): écriture d'un caractère getchar (): lecture d'un caractère

1) Ecriture formatée de données

printf(): cette fonction est utilisée pour transférer du texte, des valeurs de variables ou des
résultats d'expression vers le fichier de sortie standard stdout (par défaut l'écran).

Syntaxe:
printf("format", expr_1, expr_2)
↑ ↑ ↑
Format de Expressions ou variables dont les valeurs sont à représenter
représentation

"format" est une chaîne de caractère qui peut contenir :


- du texte
- des séquences d'échappement
- des spécificateurs de format (un spécificateur pour chaque expression)

Les spécificateurs de format : ils commencent toujours par le symbole %


Symbole Impression comme Type
%d ou %i Entier relatif int
%u Entier naturel (non signé) int
%o Entier exprimé en octal int
%x Entier exprimé en hexadécimal int
%f Rationnel en notation décimale float
%e Rationnel en notation scientifique float
%g Rationnel en notation décimale/scientifique float
%lf Rationnel en notation décimale double
%lg Rationnel en notation décimale/scientifique double
%le Rationnel en notation scientifique double
%c Caractère char
%s Chaîne de caractère char*

Arguments de type long:


Entiers : on utilise : %ld, %li, %lu, %lo, %lx
Rationnels : pour les "long double", on utilise : %Lf, %Lg ou %Le

Informatique 2 Langage C - Notes de cours 2020/2021


12

Remarque :
%e, %le, %Le : représentation avec 1 chiffre (non nul) avant le point décimal
%g, %lg, %Lg : choisit la représentation la plus "économique" (la plus courte) entre la notation
décimale et la notation scientifique
- Largeur minimale des entiers
Il est possible d'indiquer la largeur minimale de la valeur à afficher. Dans le champ ainsi réservé,
les nombres sont justifiés à droite:
Affichage:
printf("%4d", 1); 1
∨∨∨
printf("%4d", 123); 123

printf("%4d", 1234); 1234

- Largeur minimale et précision pour les rationnels La précision par défaut est de 6 décimales.
printf("%f", 12.34); Affichage:12.340000

La syntaxe est: "%n.mf" où: n


est la largeur du champ m est
le nombre de décimales
Affichage:
printf("%10.3f", 100.123); 100.123
∨∨∨
printf("%10.f", 100.123); 100.12
∨∨∨∨

2) Lecture formatée de données


scanf(): fonction symétrique de printf().

Syntaxe: scanf("format", adr_var_1, adr_var_2)


↑ ↑ ↑
Format de Adresses des variables auxquelles les données sont attribuées
lecture des données (adresse d'une variable= nom de la variable précédé de &)

- La fonction scanf reçoit ses données à partir du fichier standard stdin (le clavier)
- La chaîne de format détermine comment les données reçues doivent être interprétées
- Les données reçues correctement sont mémorisées aux adresses indiquées par adr_var_1,
adr_var_2, …

Informatique 2 Langage C - Notes de cours 2020/2021


13

Les spécificateurs de format pour scanf sont:


Symbole Lecture d'un(e) Type
%d ou %i Entier relatif int
%u Entier naturel (non signé) int
%o Entier exprimé en octal int
%b Entier exprimé en hexadécimal int
%f Rationnel en notation décimale float
%e Rationnel en notation scientifique float
%g Rationnel en notation décimale/scientifique float
%lf Rationnel en notation décimale double
%lg Rationnel en notation décimale/scientifique double
%le Rationnel en notation scientifique double
%c Caractère char
%s Chaîne de caractère char*
Arguments de type long:
Entiers: on utilise: %ld, %li, %lu, %lo, %lx
Rationnels: pour les "long double", on utilise: %Lf, %Lg ou %Le

scanf("%d", &nombre); On entre au clavier 33, nombre = 33

Indication de la largeur maximale: il est possible de la spécifier, mais ceci est peu recommandé,
si les chiffres d'une variable passent au-delà du champ spécifié, ils seront assimilés à la prochaine
variable qui sera lue!

On peut traiter plusieurs variables avec une seule instruction scanf: Lors de l'entrée des données,
une suite de signes d'espacement (espace, tab, interligne) est évaluée comme un seul espace
(idem si dans la chaîne de format on tape les symboles \n, \t, \r =1 seul espace). Exemple
int jour, mois, annee;
scanf("%d %d %d",&jour, &mois, &annee);
Les entrées suivantes sont correctes et équivalentes
24∨11∨1973
24111973
24
11
1973

Si la chaîne de format contient aussi d'autres caractères que des signes d'espacement, alors ces
symboles doivent être introduits exactement dans l'ordre indiqué. Exemple
int jour, mois, annee;
scanf("%d/%d/%d",&jour, &mois, &annee); Entrées
acceptées Entrées rejetées
24/11/1973 24 11 1973
∨∨
24/011/1973 24 /11/ 1973
∨∨

Informatique 2 Langage C - Notes de cours 2020/2021


14

scanf retourne comme résultat le nombre d'arguments correctement reçus et affectés. Exemple
int jour, mois, annee; recu=scanf("%d %d
%d",&j, &m, &a); si l'entrée est 24 11
1973 , alors recu = 3.
∨∨

3) Ecriture d'un caractère

Syntaxe:
putchar (caractere)
putchar transfère le caractère "caractere" vers le fichier de sortie standard stdout (l'écran), les
arguments de putchar sont des caractères (type char, i.e. des nombres entiers entre 0 et 255).

Exemples: Affichage
putchar('x'); x
putchar('?'); ?
putchar(65); A (65 est
le code ASCII
de A)
putchar('\n'); retour à la
ligne
putchar(A); valeur de la
variable A si
c'est un char

4) Lecture d'un caractère

Syntaxe:
getchar ()
Les valeurs retournées par getchar() sont des caractères. Le type du résultat de getchar est int.

Exemple: int
C;
C=getchar();

getchar lit les données de la zone tampon stdin (clavier) et fournit les données seulement après
confirmation par "Enter".

Il existe dans la bibliothèque <conio.h> une fonction getch() qui fournit immédiatement le
prochain caractère entré au clavier (sans validation).

Informatique 2 Langage C - Notes de cours 2020/2021


15

Chapitre V – Structure alternative


Les structures de contrôle définissent l'ordre dans lequel les instructions sont effectuées.
Particularité des instructions de contrôle en C: les "conditions" peuvent être des expressions qui
fournissent un résultat numérique.
On rappelle que: valeur 0 -> FAUX et toute valeur ≠ 0 -> VRAI

1) if-else

Structure:
if(condition) si condition est vrai (≠0)
{ on exécute
bloc d'instructions 1; } bloc d'instructions 1

else sinon
{ on exécute
bloc d'instructions 2; bloc d'instructions 2
}

Remarques :
- S'il n'y a qu'une seule instruction, les accolades sont inutiles.
- "condition" peut être:
- une variable de type numérique
- une expression fournissant un résultat numérique
- La partie else est facultative
- On peut imbriquer plusieurs if-else

Exemple 1 :
if(a>b) si a est plus grand que b
max=a; on affecte à max la valeur de a
else sinon
max=b; on affecte à max la valeur de b
Exemple 2 :
if(A-B) si A-B est vrai, si A-B est différent de 0, si A est différent de B
printf("A est différent de B\n"); else
printf("A est différent de B\n");
Remarque sur les exemples: Comme une seule instruction suit le if et le else, les accolades ne
sont pas obligatoires.

2) if-else imbriqués

Il est possible d'imbriquer plusieurs structures if-else, cela permet de prendre des décisions entre
plusieurs alternatives. Mais, afin de gagner en lisibilité, on conseille d'adopter une écriture
tabulée.

Informatique 2 Langage C - Notes de cours 2020/2021


16

Exemple : if(N>0) if(A>B) MAX=A;


else MAX=B;
Que fait ce programme? A quel if est rattaché le else?
La première remarque est qu’un else est toujours rattaché au dernier if qui ne possède pas de
else, dans cet exemple, le else est donc rattaché au if (A>B). La seconde est qu'en adoptant une
écriture lisible, c’est-à-dire tabulée, on verra tout de suite et beaucoup plus facilement
l'imbrication des if-else.
if(N>0) if(A>B)
MAX=A;
else
MAX=B;

Comment faire pour forcer le programme à la seconde interprétation ? (Le else est rattaché au
premier if) if(N>0)
{
if(A>B)
MAX=A;
}
else MAX=B;

3) L'opérateur conditionnel
structure: result = expr1 ? expr2 : expr3 ; si expr1 est vraie (≠0) result=expr2, sinon,
result=expr3
Exemple :
MAX=(A>B)?A :B ;

Informatique 2 Langage C - Notes de cours 2020/2021


17

Chapitre VI – Structure répétitive

Il existe trois sortes de structures répétitives: while, do while et for.

1) while = tant que

Structure:
while(condition) tant que condition est vraie (≠0)
{ on exécute
bloc d'instructions ; bloc d'instructions
}

Remarques:
- S'il n'y a qu'une seule instruction, les accolades sont inutiles.
- Le bloc d’instructions est exécuté 0 ou plusieurs fois.

2) Do-while = faire - tant que

Il est semblable au while, mais : while évalue la condition avant d’exécuter, alors que dowhile
exécute une fois avant d’évaluer la condition.

Structure:
do on exécute
{
bloc d'instructions ; } bloc d'instructions

while(condition) ; tant que condition est vrai (≠0)


Remarques :
- S'il n'y a qu'une seule instruction, les accolades sont inutiles.
- Le bloc d’instructions est exécuté au moins une fois, et aussi longtemps que condition fournit
une valeur vraie (différente de 0).
En pratique, do-while est moins courant que while, mais fournit parfois une solution plus
élégante.

3) for

structure:
for(expr1;expr2;expr3)
{
bloc d'instructions ;
}
expr1 est évaluée une fois avant le passage dans la boucle, elle est utilisée pour initialiser les
données de la boucle.
expr2 est évaluée à chaque passage de la boucle, elle est utilisée pour savoir si la boucle est
répétée ou non (c'est une condition de répétition, et non d'arrêt).

Informatique 2 Langage C - Notes de cours 2020/2021


18

expr3 est évaluée à la fin de chaque passage de la boucle, elle est utilisée pour réinitialiser les
données de la boucle.
Equivalence entre une boucle for et une boucle while:
for(expr1;expr2;expr3) expr1;
{ while(expr2)
bloc d'instructions ; {
} bloc d'instructions ;
expr3;
}

Le plus souvent, for est utilisé comme boucle de comptage:


for(init;cond_repetition;compteur)
{
bloc d'instructions ;
}

Remarque :
Les parties expr1 et expr2 peuvent contenir plusieurs initialisations ou réinitialisations, séparées
par des virgules.

Exemple :
int n,tot;
for(tot=0, n=1;n<101;n++) tot+=n;
printf("La somme des nombres de 1 à 100 est égale à: %d\n",tot);

Informatique 2 Langage C - Notes de cours 2020/2021


19

4) Choix de la structure répétitive

On choisit la structure qui reflète le mieux l'idée du programme que l'on veut réaliser, en
respectant les directives suivantes:
- Si le bloc d'instructions ne doit pas être exécuté si la condition est fausse -> while ou for
- Si le bloc d'instructions doit être exécuté au moins une fois -> do-while
- Si le nombre d'exécution du bloc d'instructions dépend d’une ou plusieurs variables qui sont
modifiées à la fin de chaque répétition--> for
- Si le bloc d'instructions doit être exécuté aussi longtemps qu'une condition extérieure est
vraie (par exemple aussi longtemps qu'il y a des données dans un fichier d'entrées) ->
while

Le choix entre for et while est souvent une question de préférence et d’habitude.
- for permet de réunir les instructions qui influencent le nombre de répétitions au début de la
structure.
- while a l’avantage de correspondre plus exactement aux structures d’autres langages et à la
logique humaine.
- for a le désavantage de favoriser la programmation de structures surchargées et par la suite
illisibles.
- while a le désavantage de mener parfois à de longues structures dans lesquelles il faut
chercher pour trouver les instructions influençant la condition de répétition.

Informatique 2 Langage C - Notes de cours 2020/2021


20

Chapitre VII – Les tableaux

Les tableaux sont des variables structurées. Dans une première approche, leur traitement en C ne
diffère pas de celui dans d’autres langages. On verra plus loin (Ch. IX – Les pointeurs) que le C
permet un accès encore plus direct et rapide aux données d’un tableau.

1) Tableaux à 1 dimension

Un tableau unidimensionnel est une variable structurée formée d’un nombre entier N de variables
simples du même type (composantes du tableau). Lors de la déclaration de variable, N doit être
défini.

a) Déclaration et mémorisation

• Déclaration :
type Nom_du_tableau[dimension] ;

Remarque: Nom_du_tableau est un identificateur

Exemples: int A[25]; tableau de 25 entiers de type int


float B[10]; tableau de 10 décimaux de type float char
C[30]; tableau de 30 caractères (entiers de type char)

• Mémorisation :
En C, le nom d’un tableau est le représentant de l’adresse du premier élément du tableau. Les
adresses des autres composantes sont calculées automatiquement, relativement à cette adresse.

Si un tableau possède N composantes et si le type déclaré des composantes requiert M octets, la


mémoire réservée pour ce tableau est de N×M octets.

Exemple: int
A[6];
Un entier int requiert 2 octets, il y a 6 éléments, la mémoire réservée pour le tableau A est donc
de 2×6=12 octets.

b) Initialisation et réservation automatique

- Il est possible d’initialiser un tableau lors de sa déclaration, en indiquant la liste des


valeurs Exemple: int A[5]={100,200,300,400,500};
Le premier élément du tableau, A[0] contiendra la valeur 100. le second élément, A[1],
contiendra la valeur 200, le dernier élément, A[4], contiendra la valeur 500.

- Lors de sa déclaration, on peut initialiser le tableau, si le nombre de valeur dans la liste


est inférieur à la dimension du tableau, les composantes restantes sont mises à 0.
Exemple:
int A[4]={10,20};

Informatique 2 Langage C - Notes de cours 2020/2021


21

Le premier élément du tableau, A[0] contiendra la valeur 10. le second élément, A[1], contiendra
la valeur 20, le troisième, A[2] sera mis par défaut à 0, de même pour le dernier élément, A[3].

- Si la dimension n’est pas indiquée, l’ordinateur réserve automatiquement le nombre


d’octets nécessaires.
Exemple:
int A[]={10,20,30};
Les trois éléments du tableau sont initialisés à 10, 20 et 30, la taille du tableau sera
automatiquement mise à 3.

Remarque: Il faut bien évidemment que le nombre de valeurs dans la liste soit inférieur ou égal
à la dimension du tableau !

c) Accès aux composantes

Lorsque l’on déclare un tableau, (par exemple int A[5] ;), on définit un tableau avec 5
composantes, auxquelles on peut accéder par :
A[0], A[1], A[2], A[3], A[4]

Remarque: Le premier élément du tableau est l’élément 0, donc, pour un tableau de dimension
N, le premier sera l’élément 0, le dernier l’élément N-1.

d) Affichage et affectation

La structure for se prête particulièrement bien au travail avec les tableaux.

• Affichage du
contenu d’un tableau
Exemple:
int A[5]={1,2,3,4,5} ; Affichage:
int i ;
for(i=0 ;i<5 ;i++) 1 2 3 4 5
printf("%3d",A[i]);

Remarque : Avant de pouvoir afficher les composantes d'un tableau, il faut bien sûr leur affecter
des valeurs!

• Affectation
Exemple:
int A[5]={1,2,3,4,5} ;
int i ;
for(i=0 ;i<5 ;i++)
scanf("%d",&A[i]);

Remarque: De la même manière que pour une variable "normale", on indique l'adresse (&A[i])
Exercice 6

Informatique 2 Langage C - Notes de cours 2020/2021


22

2) Tableaux à 2 dimensions

En C, un tableau A à deux dimensions est à interpréter comme un tableau (à une dimension) de


dimension L dont chaque composante est un tableau (unidimensionnel) de dimension C.
On appelle L le nombre de lignes, C le nombre de colonnes.
L et C sont les dimensions du tableau.
Un tableau à deux dimensions contient donc L×C composantes.
Rapprochement avec les maths: "A est un vecteur de L vecteurs de dimension C", ou encore "A
est une matrice de dimensions L et C".

a) Déclaration, mémorisation, réservation automatique

• Déclaration :
type Nom_du_tableau[ligne][colonne] ;

Exemple : int A[10][10]; tableau de 10×10 entiers de type int


float B[5][4]; tableau de 5×4 décimaux de type float
char C[2][25]; tableau de 2×25 caractères

• Mémorisation :
Comme pour les tableaux à une dimension, le nom d'un tableau est le représentant de l'adresse
du 1er élément du tableau, c'est-à-dire l'adresse de la première ligne. Les composantes d'un
tableau sont stockées ligne par ligne.

Exemple : int A[3][2]={{1,2},{10,20},{100,200}}; tableau de 3×2 entiers


Si le nombre de lignes ou de colonnes n'est pas déclaré explicitement, l'ordinateur réserve
automatiquement le nombre d'octets nécessaires.

Exercice 7

b) Accès aux composantes

Comme pour les tableaux à une dimension, les indices des tableaux varient de 0 à N-1.
Soit un tableau à deux dimensions A[n][m]:
Premier élément→ A[0][0] ………… A[0][m-1]
: :
: :
A[n-1][0] ………… A[n-1][m-1] ←dernier élément

c) Affichage et affectation

Lors du travail avec les tableaux à deux dimensions, on utilisera (souvent imbriqués) deux
indices (par exemple i et j), et la structure for, pour parcourir les lignes et les colonnes.

Informatique 2 Langage C - Notes de cours 2020/2021


23

• Affichage
Exemple 1 :
int A[3][2]={{1,2},{10,20},{100,200}}; int Affichage:
i=2, j=1;
printf("élément [%d][%d ]= %d",i,j,A[i][j]); élément[2][1]=200
Exemple 2 :
int A[3][2]={{1,2},{10,20},{100,200}}; int Affichage:
i, j;
for(i=0;i<3;i++) /* boucle sur les lignes*/ 1 2
{ 10 20
for(j=0;j<2;j++) /* boucle sur les */ 100 200
{ /* colonnes */
printf("%5d",A[i][j]);
}
printf("\n");
}

• Affectation
Exemple : int A[5][4];
int i, j;
for(i=0;i<5;i++) /* boucle sur les lignes*/
for(j=0;j<4;j++) /* boucle sur les colonnes */
scanf("%d",&A[i][j]);

Exercice 8
Exercice 9

Informatique 2 Langage C - Notes de cours 2020/2021


24

Chapitre X – Les fonctions

1) Variables locales, variables globales

Si une variable est utilisée uniquement de manière locale, sa déclaration se fait dans la fonction
où elle est utilisée.

Exemple:
main() void fonction()
{ {
int A; int A;
} }
Si une variable doit être disponible pour plusieurs fonctions du programme, elle doit être déclarée
de manière globale, c'est à dire juste après les include (et donc aussi avant le main).

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

}
On cherchera à utiliser au minimum les variables globales car:
- elles créent des liens invisibles entre les fonctions
- elles risquent d'être cachées par des variables locales du même nom

On utilisera couramment le passage des variables comme paramètre de fonction.

2) Déclaration et définition

En général, le nom d'une fonction apparaît trois fois dans un programme:


1) Lors de sa déclaration
2) Lors de son appel
3) Lors de sa définition

a) Déclaration

En C, il faut déclarer une fonction avant de pouvoir l'utiliser. Cette déclaration informe le
compilateur du type des paramètres et du résultat de la fonction. Seule la fonction main n'a pas
besoin d'être déclarée.
Si on définit la fonction (dans le programme) avant de l'appeler, la déclaration est inutile, mais:
afin de faciliter la lecture d'un programme, on conseille de définir les fonctions après le main(),
il faut donc les déclarer avant (le main), juste après les include.

Syntaxe:
type nom_fontion ( type var1, type var2 );

Informatique 2 Langage C - Notes de cours 2020/2021


25

nom de la fonction noms des variables(facultatif) type du résultat


type des variables

Déclaration locale: une fonction peut être déclarée localement dans la fonction qui l'appelle
(avant les déclarations de variables), elle est alors disponible à cette fonction.
Déclaration globale: une fonction peut être déclarée globalement au début du programme
(derrière les include), elle est alors disponible à toutes les fonctions du programme.

b) Définition

Syntaxe:
type nom_fontion ( type var1, type var2 )
{
déclarations des variables locales;
instructions;
}
Si une fonction fournit un résultat de type T, on dit que la fonction est de type T, ou a le type T.

Exemple 1:
int MAX (int N1, int N2) Fonction ayant deux paramètres int, retournant un
{ résultat int (le max)
if(N1>N2) return N1;
else return N2;
}
Exemple 2: fonction sans paramètre
float PI(void)
{
return 3.14159;
}

Une fonction peut fournir comme résultat:


• un type arithmétique
• une structure, une réunion (Cf. chapitre XII)
• un pointeur
• void
Elle ne peut pas fournir des tableaux, des fonctions (mais OK pour les pointeurs) Si
une fonction n'a pas de paramètres:
Liste des paramètres= (void) ou ()
Si une fonction ne fournit pas de résultats, il faut indiquer void comme type du résultat
: Le type par défaut d'une fonction est int, si le type n'est pas déclaré explicitement, le résultat
sera de type int.

Remarque: la fonction main est de type int: int main(void) mais on peut écrire main()

Exemple: main() Définition


de main
{

Informatique 2 Langage C - Notes de cours 2020/2021


26

int FA(int X, int Y); déclaration de FA (locale à main)


int I;
I=FA(2,3); appel de FA
}

int FA(int X, int Y) Définition de FA


{
int FB(int N, int M); déclaration de FB (locale à FA)
int J;
J=FB(20,30); appel de FB
}
int FB(int N, int M) Définition de FB
{

}
Dans ce cas, la fonction FB ne peut être appelée que par FA, et FA ne peut être appelée que par
main. On préférera:
int FA(int X, int Y); Déclaration de FA (globale) int FB(int
N, int M); Définition de FB (globale)
main() Définition de main
{ int
I;
I=FA(2,3); appel de FA
}
int FA(int X, int Y) Définition de FA
{
int J;
J=FB(20,30); appel de FB
}
int FB(int N, int M) Définition de FB
{

}

3) Renvoyer un résultat

On utilise à la fin des instructions dans la fonction la commande:


return expression;

La commande return a pour effet:


• L'évaluation de l'expression
• La conversion automatique du résultat de expression dans le type de la fonction
• Le renvoie du résultat
• La terminaison de la fonction

Exemple 1: double
CARRE (double X)

Informatique 2 Langage C - Notes de cours 2020/2021


27

{
return X*X; Fournit comme résultat le carré d'un double fourni
} comme paramètre
Exemple 2: double
TANGENTE (double X)
{
if(cos(X)!=0)
return sin(X)/cos(X); Fournit comme résultat le rapport sin/cos
else sinon
printf("Erreur!\n"); affiche erreur
}
Exemple 3: void
LIGNE (int L)
{
int I;
for(I=0;I<L;I++) printf("*")
printf("\n");
}

Exercice 14

4) Paramètres d'une fonction

a) Passage des paramètres par valeur

En C, le passage des paramètres se fait toujours par valeur, c'est-à-dire: les fonctions n'obtiennent
que les valeurs de leurs paramètres et n'ont pas accès aux variables elles-mêmes. Les paramètres
d'une fonction sont à considérer comme des variables locales qui sont initialisées
automatiquement par les valeurs indiquées lors d'un appel. A l'intérieur de la fonction, on peut
donc changer les valeurs des paramètres sans influencer les valeurs originales dans les fonctions
appelantes.

Exemple:
La fonction ETOILE dessine une ligne de N étoiles, le paramètre N est modifié à l'intérieur de
la fonction.
void ETOILE(int N)
{
while(N>0) En utilisant N comme compteur, on n'a pas besoin
{ de l'indice d'aide l comme dans la fonction LIGNE
printf("*"); précédente
N--;
}
printf("\n");
}
La fonction TRIANGLE appelle la fonction ETOILE en utilisant la variable L comme paramètre.
void TRIANGLE (void)
{
int L;

Informatique 2 Langage C - Notes de cours 2020/2021


28

for(L=1;L<10;L++)ETOILE(L);
}
Au moment de l'appel, la valeur de L est copiée dans N. La variable N peut donc être décrémentée
dans ETOILE, sans influencer la valeur originale de L.

b) Passage de l'adresse d'une variable

On l'a vu précédemment, une fonction n'obtient que les valeurs de ses paramètres.

Informatique 2 Langage C - Notes de cours 2020/2021


29

Pour changer la valeur d'une variable de la fonction appelant , nous procédons ainsi:
• La fonction appelante doit fournir l'adresse de la variable
• La fonction appelée doit déclarer le premier paramètre comme
pointeur On pourra alors atteindre la variable à l'aide du pointeur.

Exemple:
On veut écrire une fonction "PERMUT" qui échange le contenu de deux variables int. En
première approche (fausse) on écrirait:
void PERMUT (int A, int B)
{
int AIDE;
AIDE=A;
A=B;
B=AIDE;
}
On appelle PERMUT(X, Y), résultat: X et Y restent inchangés. Pourquoi? Lors de l'appel, les
valeurs de X et Y sont copiées dans les paramètres A et B. PERMUT échange bien le contenu
des variables locales A et B, mais les valeurs de X et Y restent les mêmes.
APPEL PERMUT
X Y A B AIDE
3 4 ---appel--> 3 4
3 4 <--retour--- 4 3 3

Pour pouvoir modifier le contenu de X et Y, la fonction PERMUT a besoin des adresses de X


et Y. En utilisant les pointeurs, on écrit une deuxième fonction:
void PERMUT (int *A, int *B)
{
int AIDE;
AIDE=*A;
*A=*B;
*B=AIDE;
}
Résultat: le contenu des variables X et Y est échangé. Pourquoi? Lors de l'appel, les adressses
de X et Y sont copiées dans les pointeurs A et B, PERMUT échange ensuite le contenu des
adresses indiquées par les pointeurs A et B.
L'appel se fera de la manière suivante: PERMUT(&X, &Y)
APPEL PERMUT
X Y *A *B AIDE
3 4 ---appel--> 3 4
4 3 <--retour--- 4 3 3

c) Passage de l'adresse d'un tableau à une dimension

Informatique 2 Langage C - Notes de cours 2020/2021


30

Comme il est impossible de passer la "valeur" de tout un tableau à une fonction, on fournit
l'adresse d'un élément du tableau. En général, on fournit l'adresse du premier élément du
tableau: le nom du tableau.

Dans la liste des paramètres d'une fonction, on peut déclar r un tableau par le nom suivit de
crochets:
type NOM[]
Ou, plus simplement par un pointeur sur le type des éléments du tableau:
type *NOM

Exemple:
La fonction strlen calcule et retourne la longueur d'une chaîne de caractères fournie comme
paramètre. int strlen(char *s)  on aurait pu écrire char s[]
{
int N;
for(N=0;*s!='\0',s++)
N++;
return N;
}
On utilisera par la suite cette première notation, afin de mettre en évidence que le paramètre est
un pointeur variable que l'on peut modifier à l'intérieur de la fonction.

Exercice 15 (Remarque: on voit qu'il est possible de fournir une partie d'un tableau à une
fonction)
: pour qu'une fonction puisse travailler correctement avec un tableau, il est prudent de lui
fournir la dimension du tableau, ou le nombre d'éléments à traiter, sinon la fonction risque de
sortir du tableau.

d) Passage de l'adresse d'un tableau à deux dimensions

Le plus simple est de passer l'adresse du premier élément du tableau:&tab[0][0], ou d'utiliser le


cast: (float *)tab.

Exemple: On cherche à faire une fonction qui calcule la somme des éléments d'un tableau à
deux dimensions dont on fournit les dimensions N et M comme paramètres.
Comment pouvons-nous passer l'adresse de la matrice à la fonction ?
Par analogie avec ce que nous avons vu précédemment, nous pourrions envisager de déclarer le
tableau concerné dans l'en-tête de la fonction sous la forme A[][] . Dans le cas d'un tableau à
deux dimensions, cette méthode ne fournit pas assez de données, parce que le compilateur a
besoin de la deuxième dimension du tableau pour déterminer l'adresse d'un élément A[i][j]. Une
solution praticable consiste à faire en sorte que la fonction reçoive un pointeur (de type float*)
sur le début de la matrice et de parcourir tous les éléments comme s'il s'agissait d'un tableau à
une dimension N*M.

Cela nous conduit à cette fonction : float


SOMME (float *A, int N, int M)

Informatique 2 Langage C - Notes de cours 2020/2021


31

{ int
I;
float S;
for (I=0; I<N*M; I++)
S += A[I]; return
S;
}
Lors d'un appel de cette fonction, la seule difficulté consist à transmettre l'adresse du début du
tableau sous forme d'un pointeur sur float. Prenons par exemple un tableau déclaré par: float
A[3][4];
Le nom A correspond à la bonne adresse, mais cette adresse est du type "pointeur sur un tableau
de 4 éléments de type float". Si notre fonction est correctement déclarée, le compilateur la
convertira automatiquement dans une adresse du type "pointeur sur float". Toutefois, comme
nous l'avons déjà remarqué au chapitre IX, on gagne en lisibilité et l'on évite d'éventuels
messages d'avertissement si on utilise l'opérateur de conversion forcée (cast).

Solution:
Voici finalement un programme faisant appel à notre fonction SOMME:
#include <stdio.h>
float SOMME(float A, int N, int M); / déclaration de la fonction SOMME */ main()
{
float T[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9,10,11,12}}; printf("Somme
des éléments : %f \n",SOMME((float*)T, 3, 4) );
}

Rappel: Rappelons encore une fois que lors de l'interprétation d'un tableau à deux dimensions
comme tableau unidimensionnel, il faut calculer les adresses des composantes à l'aide du

Informatique 2 Langage C - Notes de cours 2020/2021

Vous aimerez peut-être aussi