Você está na página 1de 87

Universit Hassan II Casablanca

Facult de Sciences de Ben MSik

Programmation C
Filire : Licence fondamentale SMA/SMI S3,
Dpartement Mathmatique et Informatique

Prof : S.ELFIALI
Ce document prsente les bases du langage C.
Ce sera votre document de rfrence pendant
les sances de travaux dirigs et de travaux
pratiques.

Table des matires


1. Prambule .......................................................................................................................... 8
1.
Un programme informatique .............................................................................. 8
2.
Un langage informatique ...................................................................................... 8
2. Historique........................................................................................................................... 9
3. Intrts du langage C ................................................................................................... 9
4. De ldition lexcution............................................................................................ 10
LEdition du programme ................................................................................................ 10
La compilation ................................................................................................................... 10
Ldition de liens .............................................................................................................. 11
1. Les variables .................................................................................................................... 12
1.1 Quest-ce quune variable ? ................................................................................. 12
4.1 Mmoire centrale .......................................................................................................... 13
4.2 Valeur ................................................................................................................................ 13
Classification des types de donnes simples ........................................................ 13
Identificateur dune variable ....................................................................................... 14
1.4 Dclaration des variables ..................................................................................... 14
2. Constantes littrales ..................................................................................................... 15
3. Constantes symboliques : const .............................................................................. 16
4. Oprateurs et expressions .......................................................................................... 16
4.2 Niveau de priorit des oprateurs..................................................................... 18
5. Les Instructions .............................................................................................................. 19
1. Fonction printf() .............................................................................................................. 20
1.1 Le champ code de conversion ............................................................................ 20
Le champ modificateur .................................................................................................. 21
Spcificateur de prcision ............................................................................................ 22
Le champ largeur ............................................................................................................. 22
Le champ drapeau ........................................................................................................... 22
2. Fonction scanf() .............................................................................................................. 23
3. Exemple de programme complet ......................................................................... 25
1. Les instructions conditionnelles ................................................................................ 26
Instruction conditionnelle if ......................................................................................... 26
2. Instructions itratives................................................................................................... 33
2.1 Instruction do-while <faire-tant que> : ......................................................... 33
2.2 Linstruction while <tant que> :........................................................................ 35
2.3 Instruction itrative for <Pour> : ..................................................................... 37
3. Remarque sur les instructions itratives .............................................................. 40
4. Les instructions de rupture de squences ............................................................ 40
4.1 Linstruction break ................................................................................................... 40
2.4 Adressage des lments d'un tableau ............................................................. 45
5

2.5 Recherche squentielle .......................................................................................... 47


2.6 Tri par extraction ..................................................................................................... 48
3.Tableau deux dimensions ......................................................................................... 51
3.1 Dclaration ................................................................................................................. 51
3.2 Reprsentation mmoire ...................................................................................... 51
3.3 Initialisation dune matrice .................................................................................. 51
3.4 Accs aux lments dune matrice ................................................................... 52
3.5 Parcours des matrices ............................................................................................ 52
3.6 Exercice d'application ............................................................................................. 55
1. Gnralits. ..................................................................................................................... 56
2. Dclarations et initialisations de chanes. ........................................................... 56
a. Tableau de caractres (dimensionn ou non). .............................................. 56
b.
Pointeur de caractres. ....................................................................................... 56
3. Tableau de chanes de caractres. ........................................................................ 57
4. Saisie de chane. ........................................................................................................... 58
5. Impression de chane. ................................................................................................ 58
6. Fonctions de manipulation de chane. .................................................................. 59
a)
Copie de chanes. .................................................................................................. 59
b)
Concatnation de chanes. ............................................................................... 59
c)
Comparaison de chanes. .................................................................................. 59
d)
Longueur de chane. ........................................................................................... 59
1. Rappels ............................................................................................................................... 60
1.1 Notion d'adresse ...................................................................................................... 60
1.2. Oprateur d'adresse : & ...................................................................................... 60
2. Notion de pointeur ......................................................................................................... 61
3. Dclaration dune variable pointeur ........................................................................ 61
4. Initialisation dun pointeur .......................................................................................... 62
5. Accder une variable pointe ................................................................................ 63
6. Arithmtique de pointeurs .......................................................................................... 63
6.1 Incrmentation / Dcrmentation dun pointeur ........................................ 64
6.2 Addition / Soustraction dun entier ................................................................... 64
6.3 Soustraction de deux pointeurs ......................................................................... 65
6.4 Comparaison de deux pointeurs ........................................................................ 65
6.5 Accs aux lments d'un tableau une dimension par pointeur ......... 65
7. Relations entre tableaux une dimension et pointeurs ................................. 66
7.1. Conversion des noms de tableaux une dimension ................................ 66
7.2 L'oprateur d'indexation [] .................................................................................. 66
8. Relations entre tableaux deux dimensions et pointeurs ............................. 68
8.1 La taille des lments dun tableau deux dimensions ........................... 68
8.2 Conversion des noms de tableaux deux dimensions : .......................... 69
1. Introduction ...................................................................................................................... 72
2. Dfinition de fonctions ................................................................................................. 73
3. Appel dune fonction ..................................................................................................... 75
4. Prototype de fonctions ................................................................................................. 76
6

5. Variables locales ............................................................................................................. 78


6. Variables globales .......................................................................................................... 78
7. Conflit de noms entre variables globales et locales ......................................... 79
8. Transmission des paramtres une fonction ..................................................... 80
9. Passage de tableau une dimension en paramtre ........................................ 82
10. Passage de tableau deux dimensions en paramtre ................................. 83
1. Gnralits. ..................................................................................................................... 85
2. Ouverture/fermeture de fichier. ............................................................................. 85
a)
Ouverture. ................................................................................................................ 85
b)
Fermeture. ............................................................................................................... 86
3. Lecture/criture de caractres. ............................................................................... 86
Lecture de caractres. ................................................................................................... 87
Ecriture de caractres. .................................................................................................. 87
4. Lecture/criture de lignes. ........................................................................................ 87
a) Lecture de lignes. ......................................................................................................... 87
b)
Ecriture de lignes. ..................................................................................................... 87
5. Lecture/criture formates. ...................................................................................... 88
Lecture formate. ............................................................................................................ 88
Ecriture formate. ........................................................................................................... 88
6. Lecture/criture de blocs. ......................................................................................... 88
a) Lecture de blocs. ......................................................................................................... 88
b)
Ecriture de blocs. ..................................................................................................... 88
7. Instructions de contrle............................................................................................. 88
a) Test de fin fichier.......................................................................................................... 88
b)
Erreur dE/S. ............................................................................................................... 89
c) Positionnement direct sur un octet. ...................................................................... 89
d)
Repositionnement en dbut de fichier. ............................................................ 89
e) Position courante. ......................................................................................................... 90

Chapitre 1. Introduction
1. Prambule
1. Un programme informatique
Un programme informatique est une liste d'instructions crites dans un ou plusieurs
fichiers, destin tre excut par l'ordinateur afin de raliser une ou plusieurs tche(s), de
rsoudre un problme, de manipuler des donnes.
2. Un langage informatique

On appelle langage informatique ou langage de programmation, un langage destin


dcrire l'ensemble des actions conscutives qu'un ordinateur ou plus prcisment quun
processeur doit excuter.

Le langage utilis par le processeur, c'est--dire les donnes telles qu'elles lui arrivent, est
appel langage machine. Il s'agit d'une suite de 0 et de 1 (du binaire). Toutefois le langage
machine n'est pas comprhensible facilement par l'humain.

Ainsi il est plus pratique de trouver un langage intermdiaire, comprhensible par


l'homme, qui sera ensuite transform en langage machine pour tre exploitable par le processeur.

2. Historique
Langage C a t cr en 1972 par Dennie Ritchie aux Laboratoires Bell/AT&T avec un
objectif de dvelopper une version portable du systme d'exploitation UNIX.
Il provient de deux langages : BCPL dvelopp en 1967 par Martin Richards et B
dvelopp en 1970 chez AT&T par Ken Thompson.
Il fut limit lusage interne de Bell jusquen 1978, date laquelle Brian Kernighan et
Dennie Ritchie publirent la dfinition classique du langage C (connue sous le nom de standard
K&R-C) dans un livre intitul The C Programming Language .
Le succs des annes qui suivaient et le dveloppement de compilateurs C par d'autres
maisons ont rendu ncessaire la dfinition d'un standard actualis et plus prcis. En 1983,
l'American National Standards Institute' (ANSI) chargeait une commission de mettre au point une
dfinition explicite et indpendante de la machine pour le langage C. Le rsultat tait le standard
ANSI-C. La seconde dition du livre The C Programming Language , parue en 1988, respecte
tout fait le standard ANSI-C et elle est devenue par la suite, la 'bible' des programmeurs en C.

3. Intrts du langage C
9

polyvalent : il permet le dveloppement de systmes d'exploitation, de


programmes applicatifs scientifiques et de gestion.
Il a donn naissance de nombreux langages drivs, comme le C++, l'Objective
C, le Java et le C#.
Vaste ensemble de bibliothques prdfinies, fournies avec le compilateur.
Portabilit : En respectant la norme ANSI-C, il est possible d'utiliser le mme
programme sur tout autre systme (autre hardware, autre systme d'exploitation),
simplement en le recompilant.
Permet un accs toutes les ressources de la machine (Mmoire, processeur,
priphrique, etc.).
Le C a une grande popularit.

4. De ldition lexcution
Les tapes menant de ldition lexcution dun programme en C sont : ldition,
la compilation et ldition de liens.
LEdition du programme
Ldition, cest la rdaction du programme laide de lditeur de texte de CodeBlocks ou
dun autre traitement de texte : on parle alors de programme source .
En gnrale, ce texte sera conserv dans un fichier que lon nommera fichier source
dont lextension est .C .
La compilation
Elle consiste traduire le programme source en langage machine, en faisant appel
un programme nomm compilateur. Le fichier gnr, appel fichier objet, possde le mme
nom que le fichier source, mais son extension est .OBJ .

10

Ldition de liens
Il permet d'intgrer dans le fichier final tous les lments annexes (fonctions ou
librairies) auquel le programme fait rfrence mais qui ne sont pas stocks dans le fichier source.
Le fichier gnr est un fichier excutable qui contient tout ce dont il a besoin pour fonctionner
de faon autonome.

Ces tapes sont illustres dans la figure suivante :

fichier source
compilateur

fichier objet

fichier excutable

diteur de liens

Rsultat
excution

Exercice : Editer, compiler et excuter le programme suivant:


#include <stdio.h>
void main()
{
printf("Soyez les bienvenues dans le monde du dveloppement informatique a la FSB
SMI S3!");
}

11

Chapitre 2. Manipulation de donnes en C


1. Les variables
1.1 Quest-ce quune variable ?
Une variable est un emplacement mmoire qui sert stocker une valeur qui peut changer
pendant l'excution d'un programme. Elle est dfinie par cinq lments :

L'identificateur: c'est le nom que l'on donne la variable.

Le type : il dtermine la nature de linformation (nombre entier, nombre rel,


caractre, ).

12

La taille: c'est le nombre d'octets occups en mmoire, elle est en fonction du type.

La valeur: c'est la valeur que l'on attribue la variable.

L'adresse: c'est lemplacement o est stock la valeur de la variable.

Adresse

FF00

4.1 Mmoire
centrale
x
Nom
de la variable

15

4.2 Val
eur

Classification des types de donnes simples


Le tableau suivant prsente tous les types de donnes simples qui nous permettront de
dfinir les variables.
Type de donne
Char
unsigned char
short int
unsigned short int

Signification
caractre
caractre non sign
entier court
entier court non sign

Int

entier

unsigned int

entier non sign

long int
unsigned long int
Float
Double
long double

entier long
entier long non sign
flottant (rel)
flottant double
flottant double long

Taille (en octets)


1
1
2
2
2 (sur processeur 16 bits)
4 (sur processeur 32 bits)
2 (sur processeur 16 bits)
4 (sur processeur 32 bits)
4
4
4
8
10

13

Valeurs limites
-128 127
0 255
-32 768 +32 767
0 65 535
-32 768 +32 767
-2 147 483 648 +2 147 483 647
0 65 535
0 4 294 967 295
-2 147 483 648 +2 147 483 647
0 4 294 967 295
3.4*10-38 3.4*1038
1.7*10-308 1.7*10308
3.4*10-4932 3.4*104932

Identificateur dune variable


Il existe un certain nombre de limites pour choisir lidentificateur dune variable :
un identificateur peut contenir des lettres minuscules ou majuscules, des chiffres,
ou le caractre spcial de soulignement _ . Par contre, il ne doit pas
commencer par un chiffre ou possder des lettres accentues.
les espaces ne sont pas admis dans lidentificateur
un identificateur ne doit pas comporter plus de 32 caractres ;
les majuscules sont distingues des minuscules, ainsi : Montant et montant
dsignent deux noms diffrents.
un identificateur ne peut pas tre un mot rserv du langage :
Auto

double

int

struct

Break

else

long

switch

Case

enum

register

typedef

Char

extern

return

union

Const

float

short

unsigned

Continue

for

signed

void

Default

goto

sizeof

volatile

do

if

static

while

Identificateurs valides :
x

x1

_x

Identificateurs non valides :


2eme

commence par un chiffre

a#b

caractre non autoris (#)

num-employe caractre non autoris (-)


racine carree caractre non autoris (espace)
1.4 Dclaration des variables
Avant dutiliser une variable dans un programme C, il faut la dclarer c'est--dire rserver
son emplacement mmoire.

14

Pour dclarer une variable, on doit :


1. spcifier le type de donne;
2. indiquer lidentificateur de la variable.
Une variable peut tre initialise lors de sa dclaration.
Syntaxe :

Type identificateur [= valeur_initiale];

Exemples :
int x=-10, y, z=20 ;
char touche = A' ;
float hauteur, largeur;

2. Constantes littrales
Quand une valeur comme

apparat dans un programme, elle est appele constante

littrale : littrale car on ne peut parler d'elle qu' travers sa valeur, et constante car sa valeur ne
peut tre change. Chaque littral possde un type associ. Par exemple,
3.1459

est de type entier,

est une constante littrale de type double.


Le tableau suivant prsente les quatre types de constantes littrales du langage C : les

constantes entires, relles, caractres et chane de caractres.


Type
Entire
Relle

Caractre

Description
Dcimale
Octale
Hexadcimale
Dcimale
Imprimable

Exemples
-12, 20
015,027
0x1A5, 0xFFFF
15.25, 1.53e2, 314E-2
a' ..... 2'.....,' ..... (espace)

Non-imprimable

Chane de caractre

\n : saut de ligne (Line Feed)


\t : tabulation horizontale (Horizontal Tab)
\v : tabulation verticale (Vertical Tab)
\b : retour arrire (Backspace)
\r : retour chariot (Carriage Return)
\f : saut de page (Form Feed)
\a : sonnerie ou bip (Alert)

"Bonjour"

15

3. Constantes symboliques : const


Une constante est une variable dont l'initialisation est obligatoire et dont la valeur ne
pourra pas tre modifie en cours d'excution. Elle est dclare avec le mot cl : const qui doit
prcder le type.
Syntaxe :

const type identificateur = valeur_initiale;

Exemples :

const double PI = 22.0 / 7.0;


const float TVA = 0.2;
const float remise ;
remise = 0.4;
Erreur !

4. Oprateurs et expressions
Une expression peut tre une variable, une constante, un appel dune fonction (avec retour
de valeur) ou d'une combinaison de chacun de ces lments par des oprateurs. Toute expression
un type et une valeur.

Exemples :

b*b 4*a*c
'A' + 1
(-b + sqrt(b*b 4*a*c)) / (2*a)

4.1 Classification et description


Les tableaux suivants prsentent la liste de tous les oprateurs disponibles en C.

Oprateurs arithmtiques
Fonction
Addition
Soustraction
Multiplication
Division
Modulo

Symbole
+
*
/
%

Remarques

Reste dune division entre entiers : 7/5 = 1, reste 2; donc 7%5 = 2

16

Oprateurs de relation
Fonction
Symbole
Remarques
Plus grand que
>
Plus petit que
<
Plus grand ou gal
>=
Plus petit ou gal
<=
Egal
Attention! Trop souvent confondu avec loprateur daffectation =
==
Diffrent de
!=
Note : Ces oprateurs servent comparer des expressions. Le rsultat des oprations est VRAI ou FAUX.

Oprateurs logiques
Fonction
Symbole Remarques
ET
( (a>2) && (a<10) ) VRAI si a = 6, FAUX si a = 16
&&
OU
( (a<2) || (a>10) ) FAUX si a = 6, VRAI si a = 16
||
Ngation
!( (a<2) || (a>10) ) VRAI si a = 6, FAUX si a = 16
!
Note : Ces oprateurs servent tester ltat logique dune expression : VRAI ou FAUX, OUI ou NON, 0 ou 1. Une
valeur numrique peut galement tre teste : VRAI si diffrente de 0, FAUX si gale 0.

Oprateurs de manipulation de bits


Fonction
Symbole Remarques
ET
c = a & b; si a = 1001 0011 et b = 0101 0110, c = 0001 0010
&
OU
c = a | b; si a = 1001 0011 et b = 0101 0110, c = 1101 0111
|
OU exclusif
c = a ^ b; si a = 1001 0011 et b = 0101 0110, c = 1100 0101
^
Dcalage droite
(a>>2) dcale la valeur de a de 2 bits vers la droite
>>
Dcalage gauche
(a<<2) dcale la valeur de a de 2 bits vers la gauche
<<
Complment un
c = ~a si a = 1001 0011, c = 0110 1100
~
Note : Ces oprateurs ne modifient pas la valeur de la variable, sauf si le rsultat de loprateur affecte celle-ci : a >>
2 ne change pas la valeur de a, a = a >> 2 change la valeur de a.

Oprateurs daffectation
Fonction
Symbole Remarques
Affectation simple
=
Ajoute et affecte
a += b; quivaut a = a + b ;
+=
Soustrait et affecte
a -= b; quivaut a = a - b ;
-=
Multiplie et affecte
a *= b; quivaut a = a * b ;
*=
Divise et affecte
a /= b; quivaut a = a / b ;
/=
Modulo et affecte
a %= b; quivaut a = a % b ;
%=
OU (bit) et affecte
a |= b; quivaut a = a | b ;
|=
OU exclusif (bit) et affecte
a ^= b; quivaut a = a ^ b ;
^=
ET (bit) et affecte
a &= b; quivaut a = a & b ;
&=
Dcale droite et affecte
a >>= b; quivaut a = a >> b ;
>>=
Dcale gauche et affecte
a <<= b; quivaut a = a << b ;
<<=
Note : Ces oprateurs modifient la valeur des variables.

Oprateur dvaluation squentielle


Fonction
Evaluation squentielle

Symbole
,

Remarques
int a, b; b = 3, a = 94;

Symbole
?:

Remarques
min = (a<b) ?a :b; si (a<b) est VRAI, min=a ;.sinon min=b ;

Oprateur conditionnel
Fonction
Evaluation conditionnelle

17

Note : Lutilisation de cet oprateur fait partie des thmes traits au chapitre 4.

Oprateurs unaires
Fonction
Incrmentation

Symbole
++

Remarques
c=a + (b++) ; b=b + 1 aprs excution de linstruction
c=a + (++b) ; b=b + 1 avant excution de linstruction
Dcrmentation
c=a + (b--) ; b=b - 1 aprs excution de linstruction
-c=a + (--b) ; b=b - 1 avant excution de linstruction
Conversion explicite
char a; int b; b=(int)a; une copie de la valeur de a est transforme en
(nom
int avant dtre dpos dans b.
Type)
Adressage indirect
*ptr=a ; copie la valeur de a ladresse pointe par ptr.
*
Adresse de
&a est ladresse de a.
&
Evalue grandeur mmoire
sizeof
sizeof(expr). sizeof(nom Type).
Plus unaire
force lvaluation dune expression avant une autre cause de son niveau
+
de priorit.
Moins unaire
-a est le complment 2 de a.
Note : Un oprateur unaire est un oprateur qui ncessite 1 seul oprande : a++.
Un oprateur binaire est un oprateur qui ncessite 2 oprandes : a + b.

Oprateurs primaires
Fonction
Parenthse
Expression dindice
Slecteur de membre
Slecteur de membre

Symbole
()
[]
->
.

Remarques
char tableau[8] ; tableau[3] = a + tableau[5] ;
Slection par pointeur : ptrstruct->mois = 12 ;
Slection par la structure : date.mois = 12 ;

4.2 Niveau de priorit des oprateurs


Le niveau de priorit des oprateurs dtermine dans quel ordre ceux-ci seront appliqus
lors de lvaluation dune expression : les oprateurs de niveau plus lev seront toujours valus
en premier.

Lorsque plusieurs oprateurs de mme niveau de priorit se trouvent dans une expression,
cest lassociativit (gauche droite ou droite gauche), qui dtermine si les oprations seront
effectues de droite gauche ou de gauche droite.

Priorit des oprateurs


Niveau de priorit
15
14
13
12
11
10
9

Type doprateur
Primaire
Unaire
Arithmtique
Arithmtique
De manipulation de bits
De relation
De relation

()
++
*
+
>>
>
==

Oprateurs
[ ] . ->
-- (nom Type) * & sizeof + / %
<<
< >= <=
!=

18

Associativit
gauche droite
droite gauche
gauche droite
gauche droite
gauche droite
gauche droite
gauche droite

8
7
6
5
4
3
2
1

De manipulation de bits
De manipulation de bits
De manipulation de bits
Logique
Logique
Conditionnel
Daffectation
Dvaluation squentielle

&
^
|
&&
||
?:
= +=
,

-=

*=

/=

|=

^= &= >>= <<=

gauche droite
gauche droite
gauche droite
gauche droite
gauche droite
droite gauche
droite gauche
gauche droite

5. Les Instructions
Une instruction simple est soit une expression termine par un point virgule, soit
une instruction de contrle (traite au chapitre 4) soit un bloc dinstructions
dlimit par { et }.
Exemple : a=a +1;
Les instructions composes (ou blocs) qui permettent de considrer une succession
d'instructions comme tant une seule instruction :
o elles commencent par "{" et finissent par "}"
o laccolade ouvrante est lquivalente du dbut en algorithme
o laccolade fermante est lquivalente de la fin en algorithme
Exemple :
{
float tauxConversion=6.55957, valeurEnFranc;
int valeurEnEuro=50;
valeurEnFranc = valeurEnEuro * tauxConversion;
}

19

Chapitre 3. Les entres-sorties


conversationnelles
La bibliothque standard contient un ensemble de fonctions dentres-sorties
conversationnelles (lecture au clavier, affichage l'cran).

1. Fonction printf()
La fonction printf() permet dafficher du texte, des valeurs de variables ou des rsultats
d'expressions l'cran.
Syntaxe : printf(format[,arg1, arg2,,argn]).

Le paramtre format dsigne une chane de caractres comprenant :


1. des caractres afficher tels quels,
2. des caractres non imprimables (squences d'chappement),
3. des spcificateurs de format : suite de caractres prcde du symbole %
prcisant la manire dont les valeurs des arguments <arg1..n> sont affiches.

Une spcification de format est de la forme :

% [drapeau] [largeur] [.prcision] [modificateur] code_conversion.


Les arguments afficher peuvent tre des constantes littrales ou des variables ou
des expressions.
Note : Il doit y avoir autant de spcificateurs de format que darguments.
1.1 Le champ code de conversion
Le format minimum dimpression est constitu du caractre % suivi dun code de
conversion qui spcifie le type de donne de largument afficher, dont voici les principaux :
20

Code de conversion
d ou i
U
O
x ou X
C
F
e ou E
S

Type
int
unsigned int
int
int
char
float ou double
float ou double
char*

Remarque

affich en octal
affich en hexadcimale

affich en notation scientifique

Exemple 1 :
int q = 100;
float p = 60.50;
char t =A;
printf("Quantite = %d\n",q);
printf("Prix = %f\n", p) ;
printf("Taille = %c\n",t) ;
printf("Prix total = %f", q*p);

ou bien
printf("Quantite = %d\nPrix = %f\nTaille = %c\nPrix total = %f",q,p,t,q*p);

Imprime
Quantite = 100
Prix = 60.500000
Taille = A
Prix total = 6050.000000

Le champ modificateur
Le champ modificateur est optionnel, il est constitu dune simple lettre (l, h ou L) place
devant le champ code de conversion qui spcifie short ou long.

Exemples des combinaisons typiques des champs modificateurs et codes de conversion :


ld ou li
lu
hd
Lf ou Le

:
:
:
:

long int.
unsigned long int.
short int.
long double.

21

Spcificateur de prcision
Par dfaut, les flottants sont affichs avec six chiffres aprs le point dcimal (aussi bien
pour la notation dcimale que pour la notation exponentielle).Il est possible de modifier cette
reprsentation en utilisant un point dcimal et un spcificateur de prcision.
Exemple 2 :
float val = 25.1234;
printf("%f",val);
printf("%.0f",val);
printf("%.1f",val);
printf("%.2f",val);
printf("%e",val);
printf("%.3e",val);

/* affiche : 25.123400 */
/* affiche : 25 */
/* affiche : 25.1*/
/* affiche : 25.12*/
/* affiche : 2.512340e+01*/
/* affiche : 2.512e+01*/

Le champ largeur
Le champ largeur permet de spcifier le nombre minimal de caractres afficher.
Exemple 3 :
int val1 = 125;
float val2 = 4.5;
printf("|%d|",val1);
printf("|%2d|",val1);
printf("|%5d|",val1);
printf("|%05d|",val1);

/* affiche : |125| */
/* affiche : |125| */
/* affiche : |--125| */
/* affiche : |00125| */

printf("|%8.2f|\n",val2);

/* affiche : |----4.50| */

Le champ drapeau

"-" : Cadrage gauche (sinon droite par dfaut).


"+" : affichage du signe pour les nombres positifs.

Exemple 4 :
int val1 = 125;
float val2 = 4.5;
printf("|%-5d|",val1);
printf("|%+05d|",val1);

/*affiche : |125--|*/
/*affiche : |+0125|*/

printf("|%-8.2f|\n",val2); /*affiche : |4.50----|*/

22

2. Fonction scanf()

La fonction scanf permet de lire des donnes au clavier et de les affecter des variables.
Syntaxe : scanf(format,arg1, arg2,,argn).

Une spcification de format est de la forme :


%[largeur][modificateur] code_conversion.

Remarques :
Chaque nom d'argument qui correspond un scalaire doit tre prcd de &
(oprateur dadresse), ceci indique que l'information saisie va tre place
l'adresse de la variable.

La chane de format ne doit comporter que des spcifications de format, sinon tout
autre caractre indiqu dans la chane de format doit tre saisi par lutilisateur.

Le code de conversion "f" sapplique aux donnes de type float et double dans le
cas de la fonction printf(). Par contre, pour la fonction scanf(), une distinction
simpose : "f" ne sapplique quaux donnes de type float ; pour les donnes de
type double, il faut utiliser le code de conversion "lf" qui signifie long float.

Le champ largeur change par rapport printf. Il permet de spcifier le nombre


maximal de caractres lire.

Exemples :

Saisie d'une variable


{
float rayon, perimetre;
printf("Donnez le Rayon : ");
/* Saisie du Rayon */
scanf("%f",&rayon);
/* Calcul du primtre */
perimetre = 2*3.14*rayon;
/* Affichage de primtre */
printf("Le primtre = %.2f", perimetre);
}

23

Saisie de plusieurs variables.


{
float a, b, c, det ;
printf("Donnez les valeurs de a,b et c : ");
/* Saisie de a, b, c */
scanf("%f %f %f",&a,&b,&c);
/* Calcul du dterminant */
det = b*b- 4*a*c;
printf("Le dterminant = %.2f", det);
}

Tampon de scanf
Les informations tapes au clavier sont d'abord mmorises dans un emplacement
mmoire appel tampon (buffer). Elles sont mises la disposition de scanf aprs lactivation de la
touche <Entre>

Pour les nombres : scanf avance jusqu'au premier caractre diffrent d'un
sparateur (espace, tabulation, retour la ligne) puis scanf prend en compte
tous les caractres

jusqu' la rencontre d'un sparateur ou d'un caractre

invalide ou en fonction du largeur.

Pour les caractres %c : scanf prend le caractre courant sparateur ou non


sparateur.

Exemple (^ = espace, @ = fin de ligne) :


scanf("%d%d",&a,&b);
123^45@
==>
10@@20@
==>

a = 123 b = 45
a = 10 b = 20

scanf("%d%c",&a,&b);
200^z
==>

a = 200 b = ' '

scanf("%d^ %c",&a,&b);
200^z
==>
a = 200 b = 'z '
scanf("%d",&a);
15@
==>
scanf("%c",&b); ==>

a = 15
b = \n

24

3. Exemple de programme complet


Le programme suivant calcule la moyenne de deux nombres entrs au clavier et l'affiche :

#include <stdio.h>
void main()
// Point d'entr du programme
{
/*Dbut du programme*/
float x, y;

printf("\t\t\tCalcul de la moyenne\n\n");
/*Affiche le titre*/
printf("Entrez le premier nombre : ");
scanf("%f", &x);
/*Lecture du premier nombre*/
printf("Entrez le deuxieme nombre : ");
scanf("%f", &y);
/*Lecture du deuxime nombre*/
printf("La valeur moyenne de %.2f et de %.2f est %.2f\n",x, y,(x+y)/2);
// Fin du programme

Commentaire :
Inclusion des fichiers : La premire ligne contient la directive #include suivi dun nom de
fichier a pour effet dinsrer le fichier spcifi entre < et >, ici stdio.h, dans le fichier source
lendroit o la directive est place. Le fichier den-tte stdio.h contenant les dclarations
ncessaires lutilisation des fonctions dentres-sorties standard. Le compilateur dispose ainsi
des informations ncessaires pour vrifier si lappel de la fonction (en l'occurrence printf et scanf)
est correct.
A propos de main() : Tout programme C doit contenir au moins une fonction appele
main. Le code quil contient est encadr par deux accolades, { et }. Lexcution du programme
dbute immdiatement aprs laccolade ouvrante et se termine lorsque laccolade fermante
correspondante est rencontre.

Ajout de commentaires : Les commentaires permettent de documenter les programmes


sources. Ils sont encadrs par " /*" et par " */".
Vous pouvez, en outre, utiliser des commentaires de fin de ligne en introduisant les
deux caractres : //. Dans ce cas, tout ce qui est situ entre // et la fin de la ligne est un
commentaire. Les commentaires sont alors ignors par le compilateur.

25

Chapitre 4. Les instructions de contrle


Les instructions de contrle servent contrler le droulement de lenchanement des
instructions lintrieur dun programme, ces instructions peuvent tre des instructions
conditionnelles ou itratives.

1. Les instructions conditionnelles


Les instructions conditionnelles permettent de raliser des tests, et suivant le rsultat de
ces tests, dexcuter des parties de code diffrentes.
Le langage C offre deux types d'instructions conditionnelles :
l'instruction if
l'instruction switch
Instruction conditionnelle if
A) linstruction if-else
Syntaxe :
if ( <expression>) <instruction1>
if ( <expression>) <instruction1> else <instruction2>
Description :

Instruction1 et instruction2 : sont des instructions quelconques, cest--dire :


o simple,
o bloc,
o instruction structure.

Si le rsultat de lexpression est vrai , c'est--dire non nul, on excute linstruction


<instruction1>, dans le cas contraire on excute linstruction <instruction2> si elle
existe. Puis, le programme passe lexcution de linstruction suivante.

26

Diagramme syntaxique du if :

Dbut de if

Expression

non

!=0

oui
instruction1

instruction2 *

* facultatif
Fin de if
Exemples :
int qte_cmd ;
float prix, remise=0 ;
printf("La quantit commande : ") ;scanf("%d",&qte_cmd) ;
printf("Prix unitaire : ") ;scanf("%f",&prix) ;
if(qte_cmd > 100) remise = 0.1;
printf("Prix payer : %.2f",prix*qte_cmd*(1 remise) ) ;

char car ;
printf("Tapez une lettre minuscule non accentue : ");
scanf("%c",&car);
if (car == 'a' || car == 'e' || car == 'i' || car == 'o' || car == 'u' || car == 'y')
printf("la lettre %c est une voyelle",car);
else
printf("la lettre %c est une consonne",car);

if (qte_cmd <= qte_stock)


{
printf("Prix total = %.2f", qte_cmd*prix);
qte_stock -= qte_cmd;
}
else
printf("\aLa quantit commande est sup. la quantit en stock ! ");

27

Exercice 1 :
L'utilisateur saisit un caractre, le programme teste s'il s'agit d'une lettre majuscule, si oui
il affiche cette lettre en minuscule, sinon il affiche un message d'erreur.
Solution :
....................................................................................................................................................................................... .....
............................................................................................................................................................................................
............................................................................................................................................................................................
................................................................................................................................ ............................................................
............................................................................................................................................................................................
............................................................................................................................................................................................
............................................................................................................................................................................................
............................................................................................................................................ ................................................
............................................................................................................................................................................................
............................................................................................................................................................................................
............................................................................................................................................................................................
........................................................................................................................................................ ....................................
............................................................................................................................................................................................
...........................................................................................................................................................................................
............................................................................................................................................................................................

Exercice 2 :
Quel rsultat affiche le programme suivant :
#include<stdio.h>
void main()
{
int x = 3 ;
if (x < 0) ;
{
x = -x ;
printf("x = %d ", x);
}
if (x = 4) printf("x = %d", x);
}

Solution :
............................................................................................................................................................
B) Imbrication dinstructions if
Il est possible dimbriquer une instruction if lintrieur dune autre.

28

Syntaxe :
if (<expression1>) if (<expression2>) <instruction1> else <instruction2>

Exemple :
if (a < b) if (c < b) z = b ; else z = a ;

A quel if se rapporte else ?


Rgle : le else se rapporte au dernier if rencontr auquel un else na pas encore t attribu sauf si
on utilise les accolades.
La bonne mise en page du code ci-dessus est :
if (a < b)
if (c < b)
z=b;
else
z=a;

On peut mettre des { } pour rendre les choses plus claires.


if (a < b)
{
if (c < b)
z=b;
else
z=a;
}

Si lon veut que else se rapporte au premier if :


if (a < b)
{
if (c < b)
z=b;
}
else
z=a;

C)Linstruction if-else if
Il est frquemment utile dutiliser une srie dinstructions if-else if pour rpondre une situation
dans laquelle les choix sont multiples.
Syntaxe :

if (<expression1>) <instruction1>
else if (<expression2>) <instruction2>
else if (<expression3>) <instruction3>
...
[else <instruction_n+1>]

29

Chaque instruction est associe une condition et le dernier else, sil existe, correspond au cas o
aucune condition nest vraie.
Exemples :
if ( qte < 1000)
taux_remise = 5;
else if ( qte < 10000)
taux_remise = 10;
else
taux_remise = 15;

#include<stdio.h>
void main()
{
char c;
printf("Entrez une lettre non accentue : ");
scanf("%c", &c);
if (c >='A' && c<='Z')
printf("Cette lettre en minuscule est : %c",c+32);
else if (c >='a' && c<='z')
printf("Cette lettre en majuscule est : %c",c-32) ;
else
printf("Erreur ! Ce nest pas une lettre non accentue") ;
}

Exercice 3 :
Ecrivez un programme qui permet de saisir une valeur de type entire et indiquez
l'utilisateur si celle-ci est positive, ngative ou nulle.
Solution :

Remarque :
Le langage C offre la possibilit de remplacer linstruction conditionnelle if-else dans le
cas dune affectation conditionnelle de variable par loprateur conditionnel ?: et qui a
l'avantage de pouvoir tre intgr dans une expression.
Syntaxe :
expr1 ? expr2 : expr3

30

On value expr1:

Si elle n'est pas nulle (donc elle est vraie), alors la valeur de <expr2> est fournie
comme rsultat.
Sinon, la valeur de <expr3> est fournie comme rsultat.

Exemples :
int x = 5, y = 4, max;
if (x>y)
max=x;
else
max=y;
printf("Le max est : %d",max) ;

int x = 5, y = 4, max;
max = (x>y) ? x : y;
printf("Le max est : %d",max) ;

int x = 5, y = 4;
printf("Le max est : %d",(x>y) ? x : y) ;

1.1 Instruction conditionnelle switch


Linstruction conditionnelle swtich permet de remplacer plusieurs if-else imbriqus
lorsquil sagit deffectuer un choix multiple.

Sa syntaxe est la suivante :


switch (expression)
{
case expression_const_1 :
instruction_1;
[break;]
case expression_const_2 :
instruction_2;
[break;]
.
case expression_const_n :
instruction_n;
[break;]
[default:
instruction_par_dfaut;]
}

Notes :

expression et expression_const_i ne peuvent tre ni de type rel ni de type chane de


caractre.

expression_const_1,expression_const_2,,expression_const_n
ment tre distinctes.

31

doivent

obligatoire-

break et default sont optionnelles.

Description :
L<expression> est value puis le rsultat est compar chacune des expressions
constantes spcifies aprs les diffrentes cases. Si l<expression> vaut l<expression_const_i>,
lexcution se poursuit par l<instruction_i> jusqu la fin du switch moins de rencontrer une
instruction break qui permet de la terminer. Si l<expression> ne correspond aucune
<expression constante> alors l<instruction_par_dfaut> qui sera excuter.
Diagramme syntaxique de switch :
Dbut de switch

Evaluer
lexpression

expression
==
expression_const_1 ?

non

oui

oui

non

oui

instruction_1

break ?

expression
==
expression_const_2 ?

break ?

non

oui

instruction_2

non

expression
==
expression_const_n ?

instruction_n

non

oui

break ?

instruction_par_dfaut

non

oui

Fin de switch

32

Exemples :
void main()
{
int jour;
printf("Entrez le numro dun jour de la semaine (1 7) : ");
scanf("%d",&jour);
printf("Le jour %d de la semaine est le ",jour);
switch (jour)
{
case 1 : printf("DIMANCHE");
break;
case 2 : printf("LUNDI");
break;
case 3 : printf("MARDI");
break;
case 4 : printf("MERCREDI");
break;
case 5 : printf("JEUDI");
break;
case 6 : printf("VENDREDI");
break;
case 7 : printf("SAMEDI");
break;
default: printf("Erreur!");
}
}

2. Instructions

void main()
{
int jour;
printf("Entrez le numro dun jour de la
semaine (1 7) : ");
scanf("%d",&jour);
printf("Le jour %d de la semaine est le ",jour);

if (jour == 1)
printf("DIMANCHE");
else if (jour == 2)
printf("LUNDI");
else if (jour == 3)
printf("MARDI");
else if (jour == 4)
printf("MERCREDI");
else if (jour == 5)
printf("JEUDI");
else if (jour == 6)
printf("VENDREDI");
else if (jour == 7)
printf("SAMEDI");
else
printf("Erreur!");

itratives

Les instructions itratives ou boucles sont ralises l'aide d'une des trois instructions de
contrle suivantes : do-while, while et for.
2.1 Instruction do-while <faire-tant que> :
La boucle do-while permet de rpter une instruction ou un bloc dinstructions, un certain
nombre de fois, tant qu'une condition est vrifie.
Syntaxe :
do
<instruction> /*ou <bloc dinstructions> */
while (<expression>);

33

Description :
La boucle do-while dbute par lexcution de l<instruction>, puis l<expression> est
value. Tant quelle est VRAIE, lexcution de l<instruction> est rpte ; lorsquelle devient
fausse, le programme quitte la boucle et passe aux instructions suivantes.
Diagramme syntaxique :
Dbut de
do...while

Instruction

oui
Expression != 0

non
Fin de
do...while

Remarques :
L<instruction> est excute au moins une fois, car le test de l<expression>
seffectue la fin de la boucle.

Il faut sassurer que l<instruction> modifie la valeur de l<expression> si on veut


viter dtre pris dans une boucle sans fin.
void main ()
{
int compteur = 1;
do
{
printf("La valeur du compteur vaut : %d\n", compteur);
compteur++ ;
}while (compteur <=10);
printf("La valeur finale du compteur
vaut : %d",compteur);
34
}

Exemples :

#define PI 22/7.0
void main ()
{
float rayon ;
do
{
printf("Donnez le rayon : ") ;scanf("%f",&rayon);
if(rayon < 0) printf("\aLe rayon doit tre positif\n") ;
}while (rayon < 0);
printf("Aire = %.2f",rayon*rayon*PI);
}
#include <stdio.h>
void main ()
{
char rep ;
do
{
.
printf("Vous-voulez continuer (o/n) : ") ;
scanf(" %c",&rep); /* rep = getche(); */
}while (rep == o || rep == O);
}

2.2 Linstruction while <tant que> :


Linstruction itrative while se comporte comme la boucle do-while, la diffrence prs
que l<expression> est value en dbut de boucle. Il y a donc possibilit que l<instruction>
rpter ne soit jamais excute, si le premier test nest pas vrifi.
Syntaxe :

while (<expression>)
<instruction>; /*ou <bloc dinstructions>*/

Diagramme syntaxique :

Dbut de
while

Expression != 0

non

35
oui
Instruction

Fin de
while

Exemple :
#include <conio.h>
void main ()
{
int color = 1 ;
while (color <= 15)
{
textcolor(color) ;
cprintf("Couleur N %d\n\r", color++) ;
}
}

Exercice 4 :
Ecrire un programme qui demande un entier positif n et qui affiche la somme des n premiers
entiers.
Solution :

36

Exercice 5 :
Ecrire un programme qui calcule la somme des nombres positifs donns par l'utilisateur, le
programme lira des nombres tant qu'ils seront positifs.
Solution :

2.3 Instruction itrative for <Pour> :


La syntaxe de la boucle for en C est la suivante :
for ([expression_1];[expression_2];[expression_3])
<instruction>; /*ou <bloc dinstructions>*/

Description :
La boucle for sutilise avec trois expressions, spares par des points virgules :
expression_1 : est value une seule fois, au dbut de lexcution de la boucle .
Elle sert initialiser les donnes de la boucle.
expression_2 : est la condition dexcution de l<instruction> rpter. Elle est
value et teste avant chaque parcours de la boucle. Si son rsultat est
VRAI alors l<instruction> est excute sinon la boucle est termine.
expression_3 : est value aprs lexcution de l<instruction> rpter. Elle
utilise pour mettre jour les donnes de la boucle.

37

Diagramme syntaxique :
Dbut de
for

Expression_1

Expression_2 !=0

non

Fin de
for

oui
Instruction

Expression_3

Remarques :

La boucle for est quivalente la structure suivante :


expression_1;
while (expression_2)
{
instruction ;
expression_3;
}

Par rapport la boucle while, la boucle for met en valeur l<expression_1> et


l<expression_3>.

Expression_1,

expression_2

et

expression_3

sont

facultatives.

Si

l<expression_2> est omise alors la boucle est infinie.

Quand tout le traitement peut tre spcifi dans les trois expressions du for,
linstruction rpter peut se rduire une instruction vide.
38

Exemples :
#include <stdio.h>
void main ()
{
int m,i ;
printf("Donnez le multiplicande compris entre 1 et 9 : ") ;
scanf("%d",&m);
printf("\n\t\t\tTable de multiplication par %d\n",m) ;
for (i=1; i <= 10 ; i++)
printf("%2d x %2d = %2d\n",m,i,m*i) ;
}

Exercice 6 :
Ecrire un programme qui affiche la somme des n premiers termes d'une progression arithmtique
de raison r et de premier terme m.
Par exemple, si n = 7, r = 3 et m = 23 alors somme = 23 + 26 + 29 + 32 + 35 + 38 + 41 = 224
Solution :

39

3. Remarque sur les instructions itratives


Les diffrentes boucles peuvent tre imbriques.
Exemple :

#include <stdio.h>
#include <conio.h>
void main ()
{
int m,n ;
for (m=1; m <= 9 ; m++)
{
clrscr();
printf("\t\t\tTable de multiplication par %d\n\n",m) ;
for (n=1; n <= 10 ; n++)
printf("\t\t\t\t%2d x %2d = %2d\n",m,n,m*n);
getch();
}
}

Lorsque lon imbrique des instructions for, il faut veiller ne pas utiliser le mme
compteur pour chacune des instructions.

4. Les instructions de rupture de squences


Ces instructions permettent de rompre le droulement squentiel d'une suite d'instructions.
4.1 Linstruction break
L'instruction break provoque le passage l'instruction qui suit immdiatement le corps de
la boucle while, do-while, for ou switch.
Exemples :
#include <stdio.h>
void main()
{
int i;
for(i=0; ;i++)
{
printf("La valeur du compteur vaut : %d\n", i);
if(i == 10) break;
}
}

40

#include <stdio.h>
void main()
{
int i = -1;
do
{
printf("La valeur du compteur vaut : %d\n", ++i);
if(i == 10) break;
}while(1) ;
}

Remarques :
Linstruction break ne peut tre utilise que dans le corps d'une boucle ou d'un
switch.
Laction de break ne sapplique qu la boucle la plus intrieure dans laquelle elle
se trouve. Elle ne permet pas de sortir de plusieurs boucles imbriques.
4.2 Linstruction continue
Elle relance immdiatement la boucle while, do, for, dans laquelle elle se trouve.
pour les boucles while et do, la condition darrt est immdiatement rvalue.
pour la boucle for, on passe lvaluation de l<expression_3>. C'est pour cette
raison que l'quivalence entre le for et le while n'est pas totale.
Exemple :

#include <stdio.h>
void main()
{
int i;
for(i=0; i<=20; i++)
{
if(i%2 == 0) continue;
printf("La valeur du compteur vaut : %d\n", i);
}
}

4.3 Linstruction goto


Cette instruction permet de se brancher (inconditionnellement) une tiquette (identificateur)
lintrieur de la mme fonction.
Sa syntaxe est la suivante :

goto tiquette ;

Et la dclaration d'une tiquette se fait de la manire suivante :


Exemple :

tiquette :

void main()
{

int i,j,k;
for(i=1 ;i<=5 ;i++)
for(j=1;j<=5;j++)
for(k=1;k<=5;k++)
{
printf("i = %d; j = %d; k = %d",i,j,k);
if (i*j*k== 40) goto sortie;
}
sortie : printf("Fin du programme") ;
}

41

instruction ;

Remarque :
Il est dconseill de l'utiliser systmatiquement, elle n'est vraiment utile que dans des cas trs
extrmes.

Chapitre 5. Les tableaux


Il est courant davoir besoin de grer plusieurs lments qui appartiennent au mme type de
donnes. A titre dexemple, supposez que nous souhaitions dterminer, partir de 30 notes
fournies en donne, combien dlves ont une note infrieure la moyenne de la classe. Pour
parvenir un tel rsultat, nous devons :
Dterminer la moyenne des 30 notes, ce qui demande de les lire toutes,
Dterminer combien parmi ces 30 notes,

sont infrieures la moyenne

prcdemment obtenue.
Vous constatez que si nous ne voulons pas tre oblig de demander deux fois les notes
lutilisateur, il nous faut les conserver en mmoire. Pour ce faire, il parat peu raisonnable de
prvoir 30 variables diffrentes. Le tableau va nous offrir une solution convenable ce problme.

1. Dfinition :
Un tableau reprsente un ensemble demplacements mmoire regroups dune faon
squentielle, qui portent le mme nom et contiennent le mme type de donnes. Chacun de ces
emplacements est appel lment du tableau.
Un tableau peut tre une ou plusieurs dimensions. Il ny a pas de limite au nombre de
dimensions.

2. Les tableaux une dimension :


Un tableau une dimension N lments est reprsent en mmoire comme suit :
donne

donne

donne

lment 1

lment 2

lment 3

donne
lment N

2.1 Dclaration dun tableau

42

La forme gnrale de la dclaration d'un tableau une dimension est :


Type Nom_du_tableau [nb_elements];
Cette dclaration rserve en mmoire nb_elements emplacements conscutifs en mmoire
permettant de stocker des lments du type demand.

Exemple : float notes[30];


Remarques :
Le nombre dlments dun tableau ne peut tre une variable.
Pour avoir un programme plus volutif on utilise une constante symbolique pour
la taille dun tableau.
Exemple :
#define NB_ETUDIANTS 30

float notes[NB_ETUDIANTS];
2.2 Initialisation dun tableau
Tout comme pour les variables simples, il est possible d'initialiser un tableau lors de sa
dclaration en mettant entre accolades les valeurs, spares par des virgules :
int Tab1[5]={10, 20, 13, 4, 5};

Tab1

10

20

13

float Tab2[5]={1.5,6.75};

Tab2

1.5

6.75

int Tab3[]={10, 2 , 75};

Tab3

10

75

int Tab4[3]={10,20,30,40,50}; /* Erreur ! */


Remarques:
Le nombre de valeurs entre accolades ne doit pas tre suprieur au nombre
d'lments du tableau
Les valeurs entre accolades doivent tre des constantes (l'utilisation de variables
provoquera une erreur du compilateur)
Si le nombre de valeurs entre accolades est infrieur au nombre d'lments du
tableau, les derniers lments sont initialiss 0
Il doit y avoir au moins une valeur entre accolades

43

Si le nombre dlments n'est pas indiqu explicitement lors de l'initialisation,


alors le compilateur rserve automatiquement le nombre d'octets ncessaires.

2.3 Accs aux lments dun tableau


Pour accder un lment du tableau, le nom que l'on a donn celui-ci ne suffit pas car
il comporte plusieurs lments. Ainsi, Un lment du tableau est identifi par le nom du tableau
et, entre crochets, lindice reprsentant sa position dans le tableau :
Nom_du_tableau [indice]
L'indice du premier lment du tableau est 0.
L'indice du dernier lment du tableau est gal au nombre d'lments 1.
Lindice i dsigne le i+1me lment du tableau.
Lindice peut tre nimporte quelle expression arithmtique entire.
L'accs hors tableau n'est pas dtect.
Ainsi, on accdera au 6me lment du tableau en crivant : Nom_du_tableau[5].
Exemple 1 :
#define Nmax 10
void main()
{
/* Dclaration dun tableau dentiers de 10 lments*/
int tab[Nmax] , indice;
/* Initialisation du tableau tab*/
for(indice=0; indice<Nmax; indice++)
tab[indice] = indice*2;
/* Affichage du tableau tab*/
for(indice=0; indice<Nmax; indice++)
printf("Tab[%d]= %d\n",indice,tab[indice]);
}

44

2.4 Adressage des lments d'un tableau


Deux mthodes diffrentes sont utilises pour obtenir ladresse dun lment : la mthode
de lindice et la mthode de loffset (fait partie des thmes traits au chapitre 6).
La mthode de lindice est illustre la figure suivante :

int tab[3]={10,20,30} ;

&Tab[2]
&Tab[1]
&Tab[0]

FF07
FF06
FF05
FF04
FF03
FF02

30

Tab[2]

20

Tab[1]

10

Tab[0]

Tab

Remarques :
La notation &Tab[i] dsigne ladresse de llment Tab[i].

Lidentificateur du tableau correspond ladresse du premier lment du tableau :


Tab = &Tab[0] = FF02

Exemple 2 :
#define NB_ELEVES 30
void main()
{
float notes[NB_ELEVES], som, moy;
int i, nbr;
printf("Donnez vos %d notes : \n\n", NB_ELEVES);
for(i=0, som=0; i<NB_ELEVES; i++)
{
printf("Note N%d : ",i+1);
scanf("%f",&notes[i]);
som += notes[i];
}
for(nbr=0, moy=som/NB_ELEVES, i=0; i<NB_ELEVES; i++)
if(notes[i] < moy) nbr++;

45

printf("La moyenne de la classe est %.2f\n",moy);


printf("%d lves ont moins de cette moyenne",nbr);
}

Exercice 1 :
Soit un tableau T ayant N lments. Transfrer les lments positifs de T dans un tableau
TPositif et les lments ngatifs ou nuls de T dans un tableau TNegatif. Afficher les tableaux
TPositif et Tnegatif.

46

2.5 Recherche squentielle


Soit une donne introduite dans une variable que lon appellera cible, il est courant de
devoir rechercher la prsence et ventuellement la position de cette donne dans un tableau non
tri. Dans ce cas la recherche doit se faire de manire squentielle, cest dire en comparant la
cible avec les donnes successives.
Nous prsentons ici, deux mthodes de recherche squentielle :
1/

i=0;
while( i<n && Tab[i]!=cible)
i++;
/* Sortie
i == n ou (i <n et Tab[i] == cible) */

2/

for(i=0, trouve=0; i<n && trouve == 0; i++)


if(Tab[i]==cible)
trouve = 1;
/* Sortie
i == n ou trouve= = 1*/

47

Voici le programme qui ralise la recherche squentielle avec la 1re mthode :


#define Nmax 100
void main()
{
int tab[Nmax] , n, i, cible;
/* Saisie des donnes */
do
{
printf("Donnez le nombre dlments (max. %d) : ",Nmax);
scanf("%d",&n);
}while(n<=0 || n>Nmax);
for(i=0; i<n; i++)
{
printf("tab[%d] = ",i);
scanf("%d",&tab[i]);
}
printf("Donnez la valeur rechercher : ");
scanf("%d",&cible);
/* Recherche squentielle */

for(i=0; i<n && tab[i] != cible ; i++ ) ;


/* Affichage du rsultat */
if(i == n)
printf("La valeur recherche est inexistante");
else
printf("La valeur recherche se trouve la position %d",i);
}

2.6 Tri par extraction


On a trs souvent besoin de traiter des donnes en ordre croissant (de la plus petite la
plus grande) ou en ordre dcroissant (de la plus grande la plus petite).
Le tri par extraction (ou tri par slection) est la mthode la plus facile comprendre et
utiliser.
Il consiste parcourir le tableau une premire fois pour trouver le plus petit lment (ou le
plus grand lment, suivant le type de tri), ensuite

48

mettre cet lment au dbut (par une

permutation), puis parcourir une seconde fois le tableau (de la 2me au dernier lment) pour
trouver le second plus petit lment (le second plus grand lment), le placer en 2 me position, et
ainsi de suite...
Supposons quon veut trier en ordre croissant le tableau suivant :

44
33
55

3
4

22
11

La premire itration place la valeur minimale dans le premier lment :


44
33
55
22
11

0
1
2

33
44
55
22
11

22

33
44
55
22
11

44
55
33
11

La deuxime itration place la valeur immdiatement suprieure la plus petite dans le


deuxime lment :
11
11
44
44
55
55
33
33
22
22
La troisime itration extrait la valeur minimale suivante :
11

11

22

22

55

44

44

55

33

33

La quatrime itration fournit le tableau tri :

Rsultat

11

11

22

22

33
55

49

33
44

11
33
55
44
22

Programme :
#define Nmax 100
void main()
{
int tab[Nmax], n, i, j, temp;
do
{
printf("Donnez le nombre dlments (max. %d) : ",Nmax);
scanf("%d",&n);
}while(n<=0 || n>Nmax);
for(i=0; i<n; i++)
{
printf("Tab[%d] = ",i);
scanf("%d",&tab[i]);
}
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(tab[i]>tab[j])
{
temp = tab[i];
tab[i] = tab[j];
tab[j] = temp;
}
printf("Tableau Tri par ordre croissant : \n");
for(i=0;i<n;i++)
printf("Tab[%d] = %d\n",i,tab[i]);
}

2.7 Affectations globales de tableaux


Pour deux tableaux tab1 et tab2 de mme taille, on ne peut pas copier lun dans lautre avec
tab1=tab2. Il faut faire une boucle et faire la copie lment par lment :
int tab1[Nmax], tab2[Nmax];

for(i=0; i<Nmax; i++)


tab1[i] = tab2[i] ;

50

3.Tableau deux dimensions


3.1 Dclaration
Un tableau deux dimensions, ou matrice, se dclare selon le schma suivant :
type nomTableau[nbLignes][nbColonnes];
Cette dclaration rserve en mmoire : nbLignes * nbColonnes * sizeof(type) octets.
3.2 Reprsentation mmoire
La mmoire de lordinateur est une succession dadresses. Cest donc une structure une seule
dimension. La reprsentation dun tableau deux dimensions dans une structure une dimension
est obtenue en stockant les lignes les unes la suite des autres.
Exemple :
int mat[2][4] : 2 lignes de 4 colonnes

Ligne 1
2 lignes
Ligne 2
4 colonnes
Reprsentation mmoire
3.3 Initialisation dune matrice
Une matrice peut tre initialise sa cration en fournissant la liste des lments ligne par ligne.
Exemples :
int MatA[2][4] = { {1, 2, 3, 4},
{5, 6, 7, 8} } ;
int MatA[][4]= { {1, 2, 3, 4},
{5, 6, 7, 8} } ;
int MatA[2][4] = {1, 2, 3, 4, 5, 6, 7, 8} ;

51

MatA

0
0
2

1
0
3

0
1
4

int MatB[3][3] = { {1},{0,1},{0,0,1} } ;

int MatC[][4] = {1, 2, 3, 4, 5, 6};

MatB

MatC

int MatD[3][3] = {{1, 2, 3}, {4}} ;

4
0

0
0

0
0

MatD

3.4 Accs aux lments dune matrice


Laccs se fait en utilisant la notation Mat[i][j], i dsignent le numro de ligne, j
le numro de colonne.
Exemple :
Mat[0][0] = 1 ;
Mat[0][1] = 2 ;
Mat[1][0] = 3 ;
Mat[1][1] = 4 ;

1
3

2
4

Mat

3.5 Parcours des matrices


Les parcours des matrices se font avec des boucles imbriques : une boucle externe pour
parcourir les lignes, pour des indices compris entre 0 et LIGMAX-1, et une boucle interne, qui
pour chaque ligne, fait le parcours des lments dans toutes les colonnes de cette ligne. Les
indices des colonnes seront alors compris entre 0 et COLMAX-1.

52

Exemple 1 : Remplissage dune matrice par lutilisateur.


#define LIGMAX 10
#define COLMAX 10
void main()
{
int Mat[LIGMAX][COLMAX],i,j,l,c;
do
{
printf("Nombre de lignes : ");
scanf("%d",&l);
}while(l<1 || l>LIGMAX);

do
{
printf("Nombre de colonnes : ");
scanf("%d",&c);
}while(c<1 || c>COLMAX);
/********************** Lecture *****************/
for (i=0;i<l;i++)
for (j=0;j<c;j++)
{
printf("Mat[%d][%d] = ",i,j);
scanf("%d",&Mat[i][j]);
}
/*********************** Affichage ***************/
for (i=0;i<l;i++)
{
for (j=0;j<c;j++)
printf("%d\t",Mat[i][j]);
printf("\n");
}
}

53

Exemple 2 : Gestion de notes.


Le programme suivant demande lutilisateur dintroduire les notes des lves pour
chaque matire, puis calcule la moyenne de chaque lve et la moyenne de la classe par matire.
La note [i][j] reprsente la note de llve i de la matire j.
#define LIGMAX 10
#define COLMAX 10
void main()
{
float notes[LIGMAX][COLMAX],som;
int i,j,l,c;
do
{
printf("Nombre d'lves : ");
scanf("%d",&l);
}while(l<1|| l>LIGMAX);
do
{
printf("Nombre de matires : ");
scanf("%d",&c);
}while(c<1 || c>COLMAX);
/********************** Lecture *****************/
for (i=0;i<l;i++)
{
printf("\nNotes pour l'lve %d = \n",i+1);
for (j=0;j<c;j++)
{
printf("\tNote de la matire %d = ",j+1);
scanf("%f",&notes[i][j]);
}
}
/******* Calcul de la moyenne de chaque lve ***********/
for (i=0;i<l;i++)
{
for (som=0,j=0;j<c;j++)
som += notes[i][j];
printf("\nLa moyenne de l'lve %d : %.2f", i+1, som/c);
}
/******* Calcul de la moyenne par matire ***********/
for (j=0;j<c;j++)
{
for (som=0,i=0;i<l;i++)
som += notes[i][j];

54

printf("\nLa moyenne de la matire %d : %.2f", j+1, som/l);


}
}

3.6 Exercice d'application


Ecrire un programme qui permet dinitialiser la matrice B par la transpose de la matrice A.
Exemple 1 :
1 2 3
A= 4 5 6
7 8 9

B=

1 4 7
2 5 8
3 6 9

Exemple 2 :

A=

1 2 3
4 5 6

1 4
B= 2 5
3 6

55

Chapitre 6. Les chanes de caractres.


1. Gnralits.
Il ny a pas de type chane de caractres en C. Une chane est reprsente par un tableau
de caractres contenant un caractre marqueur de fin de chane, \0. Toute fonction standard
manipulant une chane devra connatre ladresse de dbut de la chane, cest--dire ladresse de
son premier caractre, et terminera son travail la rencontre du caractre de fin \0.

2. Dclarations et initialisations de chanes.


a. Tableau de caractres (dimensionn ou non).
char texte1[10]={e,x,e,m,p,l,e,\0} ;
On rserve 10 caractres et on initialise comme un tableau, en nomettant pas le caractre
\0.

char texte2[10]= "exemple";


Nous reviendrons plus tard sur le travail de la notation "". C alloue de la mmoire pour
reprsenter la chane avec son \0, puis recopie cette zone mmoire dans la zone rserve pour
le tableau texte2 . 10 octets ont t rservs, alors que 8 suffisaient.
char texte3[]= "exemple";
Dans ce cas, 8 octets ont t rservs, cest--dire exactement la taille utile.
b. Pointeur de caractres.
char * texte4= "exemple";
Prcisons maintenant le travail effectu par la notation "":
56

allocation de N+1 octets si la chane a une taille de N caractres.


Copie des N caractres dans la zone mmoire rserve.
Ajout de \0 la fin
Ladresse de la zone mmoire alloue est renvoye
texte4 est un pointeur de caractres pointant vers cette zone mmoire alloue par "".
texte4

exemple\0
Attention, il y a une diffrence avec la dclaration de texte3[], on pourra faire, par la
suite, texte4= "salut" mais on ne pourra pas faire texte3= "salut" , car un tableau
est analogue un pointeur constant (la dernire affectation reviendrait modifier la valeur de
ladresse associe texte3.
On portera galement attention aux diffrences dimpression dans les exemples suivants :
printf("%c",* texte4) ;/*affiche : e */
printf("%s", texte4) ;/*affiche : exemple */

3. Tableau de chanes de caractres.


On peut dclarer soit un tableau de caractres 2 dimensions, soit un tableau de pointeurs
de caractres 1 dimension .
char fruit[3][8]= {"pomme","abricot","orange"};
char *fruit[3]= {"pomme","abricot","orange"};

fruit
fruit[0]

pomme\0

fruit[1]

abricot\0

fruit[2]

orange\0

57

fruit
pomme\0
abricot\0
Orange\0

4. Saisie de chane.
scanf({"%s",<adresse dbut de chaine>)
Effectue la saisie dune chane de caractres taps au clavier, jusqu la rencontre du
premier espace ou \n.
Attention
char * nom ;
scanf("%s",nom) ;
ne produira pas derreur de compilation, mais les caractres lus vont tre installs
nimporte o en mmoire, puisquaucune place mmoire na t rserve.
gets(<adresse dbut de chaine>)
Effectue la saisie dune chane de caractres taps au clavier, jusqu la rencontre du
premier \n. L\0 est rajout automatiquement.
gets renvoie ladresse de dbut de chane ou NULL si on est en fin de fichier.

5. Impression de chane.
printf({"%s",<adresse dbut de chaine>)
puts(<adresse dbut de chaine>)

58

6. Fonctions de manipulation de chane.


a) Copie de chanes.
strcpy( <adresse chaine1>, <adresse chaine2>)
Recopie le contenu de la mmoire depuis <adresse chaine2> jusqu la rencontre
dun \0, partir de <adresse chaine1>. Attention, le compilateur neffectue aucune
vrification quant la rservation dun espace mmoire suffisant pour stocker chane1.
b) Concatnation de chanes.
strcat(<adresse chaine1>, <adresse chaine2>)
concatne le contenu de la mmoire depuis <adresse chaine2> jusqu la rencontre
dun \0, au contenu de la mmoire partir de <adresse chaine1>. Attention, le
compilateur neffectue aucune vrification quant la rservation dun espace mmoire suffisant
pour stocker le rsultat de la concatnation de chane1 et chane2.

c) Comparaison de chanes.
strcmp(<adresse chaine1>, <adresse chaine2>)
compare le contenu de la mmoire depuis <adresse chaine1> jusqu la rencontre
dun \0, au contenu de la mmoire partir de <adresse chaine2> jusqu la rencontre
dun \0. La valeur retourne est 0 si les chanes sont gales, une valeur ngative si chane1
prcde chane2 au sens lexicographique, ou une valeur positive si chane1 suit chane2 au sens
lexicographique.

d) Longueur de chane.
strlen(<adresse chaine1>)
La valeur retourne est la longueur de la chaine sans compter le caractre \0.

59

Chapitre 7. Les pointeurs


1. Rappels
1.1 Notion d'adresse
Chaque donne stocke en mmoire a un emplacement unique, reprsent par son
adresse. Les adresses sont ordonnes linairement : on peut reprsenter la mmoire comme un
tableau une dimension (une suite de cases) dont les cases contiennent les donnes et o les
adresses sont les indices. Une donne peut elle-mme occuper plusieurs cases. Son adresse est
alors celle de la premire case (et le nombre de cases occupes se dduit de son type).
Pour les dclarations de variables suivantes :
int val1 = 2000 ;
long int val2 = 2000000;
Ceci est stock en mmoire :

Nom

Adresse en hexa

Valeur code en hexa

val1

(9027 0FFE)

07

D0

val2

(9027 0FFA)

00

1E

84

80

val1 est cod sur 2 octets et son adresse est 9027 0FFE
val2 est cod sur 4 octets et son adresse est 9027 0FFA

1.2. Oprateur d'adresse : &


En C, loprateur & permet de connatre ladresse dune variable en mmoire. On place le
symbole & devant le nom de la variable.

60

Syntaxe : &<NomVariable>

Exemple :
printf ("Adresse de val1 : %lx", &val1);
printf ("Adresse de val2 : %p", &val2);

/* 90270FFE */
/* 9027:0FFA */

2. Notion de pointeur
Un pointeur est une variable contenant l'adresse d'une autre variable dun type donn. Il
permet donc daccder indirectement une variable.
Nom

Adresse en hexa

A :Variable

(9027 0FFE)

Valeur code en hexa

PTR : Variable pointeur

07

D0

90

27

0F

FE

Le schma ci-dessus montre que le pointeur PTR contient ladresse de la variable A, on


dit que PTR pointe sur A . Ici, pointer signifie faire rfrence . La valeur d'un pointeur
peut changer : cela ne signifie pas que la variable pointe est dplace en mmoire, mais plutt
que le pointeur pointe sur autre chose.

2000
Variable pointeur

Variable pointe

3. Dclaration dune variable pointeur


On dclare un pointeur comme on le ferait pour une variable, mais on rajoute * (toile)
devant son identificateur lors de la dclaration :

61

Syntaxe : type *pointeur [ = valeur_initiale ];


Le type utilis doit tre celui qui sera point par le pointeur.
Le type de pointeur est pointeur de type et se note type * .

Exemple :
int *ptr_i;

/* ptr_i est un pointeur sur des entiers , cest--dire il ne


doit contenir que des adresses des variables du type int */

char *ptr_c; /* ptr_c pointeur sur des caractres*/

Note : Pour dclarer plusieurs pointeurs, il faut donc rpter l'toile devant chaque nom de
pointeur.

4. Initialisation dun pointeur


Aprs avoir dclar un pointeur il faut linitialiser. En effet, si on ne prend pas cette
prcaution, le pointeur est susceptible de pointer vers une zone arbitraire de la mmoire, et
accder cette zone risque de produire une erreur (dtecte par le systme dexploitation).
Pour initialiser un pointeur, la syntaxe est la suivante :
Nom_du_pointeur = &nom_de_la_variable_pointee;
Exemple :
int x = 10, *ptr_i;
ptr_i = &x;

/* affecte ladresse de la variable x au pointeur ptr_i */

printf("Adresse de x : %p\n",&x) ;
printf("Valeur de ptr_i : %p\n",ptr_i);

10
x

ptr_i

Remarque : Une valeur usuelle pour linitialisation des pointeurs est la valeur NULL
(quivalente 0), qui reprsente un pointeur ne pointant vers rien.
62

5. Accder une variable pointe


Pour accder la valeur pointe par un pointeur, nous utiliserons l'oprateur dindirection
* (= contenu de) devant le nom du pointeur. En utilisant la syntaxe *pointeur, nous avons
accs au contenu de la variable, aussi bien en lecture qu'en criture, exactement comme si nous
avions travaill directement sur la variable pointe.
Exemple :
int *ptr,
int i;
i = 10;
ptr = &i;
printf("la valeur de i avant : %d\n",i);/*affiche :la valeur de i avant : 10*/
*ptr = 20; /*la variable pointe par ptr reoit 20, autrement dit *ptr
dsigne le contenu de i*/
printf("la valeur de i aprs:%d\n",i);/*affiche : la valeur de i aprs : 20*/

Exercice 1 :
Quaffiche le programme suivant :
void main()
{
int A = 10 , B = 20 , C , D;
int *ptr1=NULL, *ptr2=NULL ;
ptr1 = &A;
ptr2 = &B;
C = *ptr1 + *ptr2;
ptr1 = &C;
++*ptr1;
D = *ptr1;
*ptr1 = *ptr2;
*ptr2 = D;
printf("A = %d \nB = %d \nC = %d \nD = %d", A, B, C, D);
}

6. Arithmtique de pointeurs
63

On appelle arithmtique des pointeurs la possibilit de faire des oprations arithmtiques


(incrmentation, dcrmentation, addition et soustraction, etc.) sur les pointeurs. Cela revient
effectuer un dplacement en mmoire.
6.1 Incrmentation / Dcrmentation dun pointeur

Soit ptr un pointeur de type T.


Soit a la valeur de ptr (adresse contenue dans ptr).
Si on excute ptr++, alors la nouvelle valeur de ptr sera gale : a + sizeof(T).

Exemple 1:
int i = 10 ;
int *ptr = &i;
printf("Valeur de ptr avant incrmentation : %p\n",ptr); /* 8E18 : FFF4 */
ptr++ ;
printf("Valeur de ptr aprs incrmentation : %p\n",ptr); /* 8E18 : FFF6 */

Le mme principe sapplique que ptr--.

6.2 Addition / Soustraction dun entier

Soit ptr un pointeur de type T.


Soit a la valeur de ptr (adresse contenue dans ptr).
Soit i un entier.
Si on excute ptr+i alors la nouvelle valeur sera gale : a + i*sizeof(T).

Exemple 2:
int i = 10 ;
int *ptr = &i;
printf("Valeur de ptr avant laddition : %p\n",ptr); /* 8E18 : FFF4 */
ptr = ptr + 2 ;
printf("Valeur de ptr aprs laddition : %p\n",ptr); /* 8E18 : FFF8 */

Le mme principe sapplique pour la soustraction dun entier.

Exemple rcapitulatif

64

Soit ptr un pointeur dentier.


36

37

38

39

40

ptr--

41

42

43

44

ptr++

ptr-2

ptr+2
ptr

6.3 Soustraction de deux pointeurs


Si ptr1 et ptr2 sont deux pointeurs sur des objets de type T, l'expression ptr1 ptr2
dsigne un entier dont la valeur est gale (ptr1 ptr2)/sizeof(T).

6.4 Comparaison de deux pointeurs


Les oprateurs de comparaison sont galement applicables aux pointeurs, condition de
comparer des pointeurs qui pointent vers des objets de mme type.
6.5 Accs aux lments d'un tableau une dimension par pointeur
L'utilisation des oprations arithmtiques sur les pointeurs est particulirement utile pour
parcourir des tableaux. Ainsi, le programme suivant initialise un tableau avec la valeur 1 en
employant le formalisme pointeur.
#define Nmax 10
void main ()
{
int tab[Nmax], i ;
int *ptr;
/* mthode 1 */
for(ptr = tab, i = 0; i < Nmax; i++)
*ptr++ = 1; /* ou bien {*ptr = 1; ptr++ ;}*/
/* mthode 2 */
for(ptr = tab, i = 0; i < Nmax; i++)
*(ptr + i) = 1;
/* mthode 3 */
for(ptr = tab; ptr < tab + Nmax; ptr++)

65

*ptr = 1;
}

Commentaires :
Comme nous lavons dj constat au chapitre 5, le nom dun tableau reprsente
ladresse de son premier lment. En dautre termes &tab[0] et tab sont une seule et
mme adresse.
ptr = tab ptr = &tab[0].
ptr + i : dsigne ladresse de llment dindice i de tab.
*(ptr + i) : dsigne llment dindice i de tab.

7. Relations entre tableaux une dimension et pointeurs


7.1. Conversion des noms de tableaux une dimension
Un nom de tableau apparaissant dans une expression est converti en (non pas quivalent
) un pointeur vers le premier lment du tableau.
Cas particulier : si tab est un nom de tableau, alors il nest pas converti en pointeur
si tab est utilis comme oprande de sizeof (renvoie la taille du tableau en octets)
si tab est utilis comme oprande de loprateur &
7.2 L'oprateur d'indexation []
En C, l'oprateur d'indexation est en fait une abrviation : tab[i] est un raccourci
dcriture mis pour *(tab + i), donc tab[i] et *(tab + i) sont deux critures strictement
quivalentes sur le plan syntaxique.
En effet, ds que le compilateur rencontre une expression de la forme :
Exp1[Exp2]
o Exp1 et Exp2 sont deux expression tout fait quelconques, il la remplace par :
*( (Exp1) + (Exp2) )
sans mme chercher savoir si Exp1 (ou Exp2) a un quelconque rapport avec un tableau.
Exemple
#define Nmax 10
void main ()

66

{
int tab[Nmax],i ;
for(i = 0; i < Nmax; i++)
scanf("%d", tab + i) ;
for(i = 0; i < Nmax; i++)
printf("%d\t", *(tab + i));
}

Remarques :
L'addition tant commutative, il est vrai que *(tab + i) == *(i + tab) ; on en dduit
quil ny a absolument aucune diffrence entre tab[i] et i[tab].
Aprs les instructions :
int tab[10], *ptr , i;
ptr = &tab[0] ;
*(ptr + i) peut scrire ptr[i] daprs ce quon a vu prcdemment.

tab++ est invalide car tab nest pas un objet.


Exercice 2 :
Soit ptr un pointeur qui pointe sur un tableau tab :
int tab[] = {10, 20, 30, 40, 50, 60, 70, 80, 90};
int *ptr = tab;
Supposons que ptr contient ladresse FF00, quelles valeurs et/ou adresses fournissent ces
expressions, sachant que chaque expression dpend de la prcdente :
1.
2.
3.
4.
5.

*ptr + 2
*(ptr + 2)
*ptr++
ptr - tab + 1
++ptr + 3

Exercice 3 :

67

Ecrire un programme qui parcoure un tableau dentiers et qui affiche les indices des lments
nuls du tableau, sans utiliser aucune variable de type entier.

Exercice 4 :
Ecrire un programme qui ralise les oprations suivantes :
1) La lecture dun tableau.
2) Le tri par extraction.
3) Laffichage du tableau.
En utilisant la dclaration suivante : int tab[Nmax], *ptr1, *ptr2, n , temp;

8. Relations entre tableaux deux dimensions et pointeurs


Nous avons parl des relations existant entre les pointeurs et les tableaux une dimension.
Un nom de tableau sans les crochets est converti en un pointeur vers le premier lment du
tableau, cela dune part. Dautre part si tab est un tableau, alors tab[i] et *(tab + i) sont deux
expressions quivalentes. Que se passe-t-il lorsque les tableaux ont deux dimensions ?
8.1 La taille des lments dun tableau deux dimensions
Lorsque le compilateur rencontre une dclaration telle que: int t[3][5]; il considre en fait
que t dsigne un tableau de 3 lments, chacun de ces lments tant lui mme un tableau de 5
entiers. Comme il sagit dun tableau de tableaux, t[i] reprsente le nom dun tableau de 5 entiers.

t[0]
t
t[2][3]

68

Le programme suivant va nous permettre de dterminer la taille des lments dun tableau
deux dimensions :
void main()
{
int t[3][5];
printf("La taille de t[0][0] : %u\n", sizeof(t[0][0]) );
printf("La taille de t[0]
: %u\n", sizeof(t[0]) );
printf("La taille de t
: %u\n\n", sizeof(t) );
}

Affiche :
La taille de t[0][0]
La taille de t[0]
La taille de t

: 2
: 10
: 30

8.2 Conversion des noms de tableaux deux dimensions :


Lorsque le compilateur rencontre une expression
lexpression *(*(t + i) + j).

de la forme t[i][j] , elle la remplace par

Elle sinterprte de la faon suivante :

t : est converti en un pointeur vers un tableau 5 entiers ayant ladresse de la premire


ligne de la matrice t ;
Note : Comment on dclare un pointeur vers un tableau 5 entiers ?
Par linstruction suivante : int (*ptr)[5] ;
En effet, si ptr pointe vers le premier tableau de la matrice t, cest dire ptr = t,
alors ptr + 1 pointe vers le deuxime tableau de cette matrice.

t + i : dsigne ladresse de la ligne dindice i de la matrice t.

*(t + i) ou t[i] : tant le nom dun tableau de 5 entiers, il est converti en un pointeur vers
le premier lment de cette ligne, cest dire un pointeur de type int*.
Par consquent, les notations suivantes sont totalement quivalentes (elles correspond
la mme adresse et elles sont de mme type) :
t[0]
t[1]
t[2]

&t[0][0]
&t[1][0]
&t[2][0]

*(t + i) + j ou t[i] + j : dsigne ladresse de llment dindice (i, j) de la matrice t.

*(*(t + i) + j) : dsigne llment dindice (i, j) de la matrice t.

69

t
t+1
*(t[2] + 3)

t+2

t[2]

t[2] + 3

Le programme suivant affiche les adresses des lments dun tableau deux dimensions :
void main()
{
int t[3][5] ;
printf("&t[0][0]
printf("t[0]
printf("t

: %p\n", &t[0][0] );
: %p\n", t[0] );
: %p\n\n", t );

printf("&t[0][0] + 1
printf("t[0] + 1
printf("t + 1

: %p\n", &t[0][0]+1 );
: %p\n", t[0]+1 );
: %p\n\n", t+1 );

Affiche :
&t[0][0]
t[0]
t

: 8E19 : FFD8
: 8E19 : FFD8
: 8E19 : FFD8

&t[0][0] + 1: 8E19 : FFDA


t[0] + 1
: 8E19 : FFDA
t + 1
: 8E19 : FFE2

/* FFD8 + 2 = FFDA */
/* FFD8 + A = FFE2 */

Remarque : Les expressions t[i]++ et t++ sont invalide car elles ne sont pas des objets.
Exemple dutilisation :
Le programme suivant permet de remplir et dafficher un tableau deux dimensions en
employant le formalisme pointeur .

70

#define LIGMAX 10
#define COLMAX 10
void main ()
{
int t[LIGMAX][COLMAX], i, j, l, c;
do
{
printf("Nombre de lignes : ");
scanf("%d",&l);
}while(l<1|| l>LIGMAX);
do
{
printf("Nombre de colonnes : ");
scanf("%d",&c);
}while(c<1 || c>COLMAX);

for(i=0;i<l;i++)
for(j=0;j<c;j++)
{
printf("t[%d][%d]= ",i,j);
scanf("%d",*(t+i)+j);
/*scanf("%d", t[i] + j );*/
}
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
printf("%d\t",*(*(t+i)+j) );/*printf("%d\t",*(t[i]+j) );*/
printf("\n");
}
}

71

Chapitre 8. Les fonctions


1. Introduction
Une fonction est un sous-programme qui accomplit une tche spcifique. Elle possde une
structure analogue celle de la fonction main.
Lutilisation de fonctions prsente plusieurs avantages :
Rendre le programme plus facile crire et beaucoup plus facile lire.
Eviter dcrire plusieurs fois la mme squence de code.
La mise au point est plus simple car les diffrentes fonctions peuvent tre testes
sparment.
Elles peuvent tre rutilises par dautres programmes.
Exemple : Supposons quon veut lire deux tableaux, les fusionner dans un nouveau
tableau puis le trier.
On utilisant les fonctions, le programme principal prend la structure suivante :

void main()
{
/* dclaration des variables */
/* ... */
printf("Lecture du premier tableau : \n");
lecture_tableau(...);
printf("Lecture du deuxime tableau : \n");
lecture_tableau(...);
fusion_tableau(...);
printf("Affichage du tableau avant son tri : ");
affiche_tableau(...);
tri_tableau(...);
printf("Affichage du tableau aprs son tri : ");
affiche_tableau(...);
}

72

void
{

main()

lecture_tableau

...
lecture_tableau(...);
...
lecture_tableau(...);
...
fusion_tableau(...);
...
affiche_tableau(...);
tri_tableau(...);
...
affiche_tableau(...);

fusion_tableau

tri_tableau

permutation

permutation(...);

}
affiche_tableau

2. Dfinition de fonctions
La dfinition d'une fonction peut tre dcrite de la faon suivante :
type nom_fonction ([type_1 param_1,type_2 param_2, ... ,type_n param_n])
{
[<dclaration des variables internes la fonction>];
instructions;
[return expression];
}

La premire ligne de cette dfinition est appele len-tte de la fonction. Dans cet en-tte,
les diffrents lments sont les suivants :
<type> : est le type de valeur qui sera renvoye la fin de lexcution de la
fonction ("char", "int", "float", "double", "int *", ...).
o Si la fonction ne renvoie aucune valeur, on la fait alors prcder du mot-cl
void.
o Si aucun type de donne n'est prcis, le type int est pris par dfaut.

73

<nom-fonction> : est le nom que le programmeur donne la fonction : les rgles


respecter pour les noms de fonctions sont les mmes que pour les noms de
variables.
<param_1, param_2, ,param_n> : se sont des variables qui permettent
dchanger des donnes avec la fonction appelante, appeles paramtres formels
ou paramtres. Dans le cas o une fonction n'a pas de paramtres formels, on place
le mot cl "void" entre les parenthses.
Le corps de la fonction se trouve entre accolades la suite de len-tte. Il contient :
La dclaration des variables utilisables uniquement dans le corps de la fonction.
Les instructions de la fonction. Ces instructions peuvent utiliser les variables
internes la fonction et les paramtres formels.
return expression : Cette instruction permet une fonction de renvoyer une valeur
la fonction appelante.
Notes :
expression doit tre d'un type compatible avec le type de retour spcifi dans lentte de la fonction.
Si la fonction ne fournit aucune valeur alors le retour lieu aprs la dernire
instruction de la fonction (fonction de type void).
Plusieurs instructions return peuvent apparatre dans une fonction. Le retour la
fonction appelante sera alors provoqu par le premier return rencontr lors de
lexcution.
Voici, par exemple, la dfinition d'une fonction qui calcule le minimum de deux entiers.
Nom de la fonction

Type du paramtre
Paramtres formels

Type de retour

int min(int a, int b)


{
int result;
result = a <74b ? a : b;
return result;

Fin de la fonction
}

En-tte de la fonction

Corps de la fonction

Remarque : Il est interdit de dfinir des fonctions lintrieur dune autre fonction.

3. Appel dune fonction


Une fonction est invoque ou appele en faisant suivre son nom d'une liste darguments
spars par des virgules et entours entre parenthses.
Syntaxe dun appel :
nomFonction (arg_1, arg_2,, arg_n);
arg_1, arg_2,, arg_n : sont appels arguments ou paramtres effectifs. Ils peuvent tre
des expressions, constantes ou variables.
A lappel dune fonction, la valeur du paramtre effectif est transmise au paramtre
formel correspondant ensuite lexcution du programme se poursuit par lexcution de la
premire instruction du corps de la fonction. Au moment o lexcution de la fonction est
termine, le contrle est rendu la fonction appelante cest dire linstruction qui suit lappel
la fonction.
Fonction appelante : main (void)

a = min(2,3) ;
printf("Min = %d" ,a) ;

Fonction appele : int min(int a, int b)

return result ;

75

Exemple :
#include<stdio.h>
int min(int a, int b) /* dfinition de la fonction min */
{
int result;
result = a < b ? a : b;
return result;
}
void main()
{
int a,b,c,d ;
scanf("%d%d%d",&a,&b,&c);
d = min(a,b);
printf("%d", min(d,c) ) ;
}

/* 1er appel de la fonction min */


/* 2me appel de la fonction min */

Notes :
Lors de lappel une fonction avec paramtres :
il doit y avoir autant de paramtres effectifs que des paramtres formels.
le type du paramtre effectif doit tre compatible avec celui du paramtre formel
associ.

4. Prototype de fonctions

76

Il est ncessaire que la fonction ait t dfinie ou dclare avant tout appel cette
fonction.
La syntaxe pour la dclaration est :

type nom_fonction (type_1 param_1, type_2 param_2, ...,type_n param_n); /* en_tte_fct ;*/
On parle de prototype de la fonction.
Exemples :
int min(int a, int b);
double pow(doube x, double y);

/* prototype de min */
/* prototype de pow */

Notez que les noms des paramtres sont facultatifs mais aident la lisibilit.
Exemples :
int som(int , int);
double pow(doube , double);

A quoi sert-il ?
La dclaration dune fonction permet au compilateur de vrifier que le nombre et le type
des paramtres formels sont en accord avec le prototype. Si ce contrle choue, le compilateur
signale une erreur.
De plus, la prsence dune dclaration permet au compilateur de mettre en place
dventuelles conversions des paramtres effectifs, lorsque la fonction est appele avec des
paramtres dont les types ne correspondent pas aux types indiqus dans le prototype.
Notes :

La dfinition de fonction peut aussi servir de prototype, si elle est dfinie avant
son utilisation.
Si la fonction nest pas dclare et elle est dfinie aprs son utilisation, alors le
compilateur ne contrle pas le nombre de paramtres, et considre que cette
fonction renvoie un int , cela dune part, dautre part, il utilise des rgles de
conversions systmatiques sur les paramtres effectifs : char et short vers int et

77

float vers double. Et par consquent les paramtres formels ne pourront pas tre de
types float, char ou short.
A viter !

5. Variables locales
Les variables dclares dans les fonctions sont dites locales. Elles ne sont modifiables et
accessibles que dans la fonction o elles sont dclares.
Dautre part, par dfaut, les variables locales sont temporaires. En effet, les emplacements
mmoire correspondants sont allous chaque entre dans la fonction o sont dfinies ces
variables et ils sont librs chaque sortie.
Note : les paramtres formels dune fonction sont traits de la mme manire que les
variables locales.

6. Variables globales
On appelle variable globale une variable dclare en dehors de tout fonction. Elle est
modifiable et accessible par toutes les fonctions qui suivent sa dclaration. Une variable globale
est systmatiquement permanente. Elle occupe un emplacement en mmoire qui reste durant
toute lexcution du programme.
Cet emplacement est allou une fois pour toutes au moment de ldition de liens. Elle est
initialise zro par le compilateur.
Exemple :
#include<stdio.h>
void affiche(void);
int x ;

/*prototype de la fonction affiche*/


/* variable globale initialis par zro */

void affiche(void)
{
printf("x = %d\n",x);

/*dfinition de la fonction affiche*/

78

x++;
}
void main(void)
{
int i ;
for(i=0 ;i<3 ;i++)
affiche();
printf("x = %d\n",x);
}

/*appel de la fonction affiche*/

Affiche
x
x
x
x

=
=
=
=

Lutilisation des variables globales soppose au principe dun programme clair, sr et


structur. En effet une variable globale peut tre modifie dans nimporte quelle partie dun
programme et, de ce fait, la difficult de la maintenance dun programme crot exponentiellement
en fonction de sa taille.

7. Conflit de noms entre variables globales et locales


Si un programme possde des variables globales, il peut parfaitement arriver quune
variable locale savre porter le mme nom. Cest le cas pour le programme suivant qui utilise
trois variables globales (a, b et c) et dont la fonction conflit_a utilise une variable locale a ainsi
que les variables globales b et c :
int a = 1, b = 2, c = 3 ; /* variables globales */
void conflit_a(void)
{
int a = 100 ; /* variable locale */
printf(" a = %d, b = %d, c = %d\n", a, b, c);
}
void main()

79

{
conflit_a();
printf(" a = %d, b = %d, c = %d\.n", a, b, c);
}

Lexcution du programme entrane laffichage suivant :


a = , b = , c =
a = , b = , c =

Lorsquun conflit de noms se produit entre variables globales et locales, le C utilise le


nom de la variable locale.

8. Transmission des paramtres une fonction


Lors de lappel dune fonction, la fonction reoit une copie de la valeur de la variable
pass comme paramtre effectif. Cette copie est affecte au paramtre formel correspondant. Cela
implique en particulier que, les valeurs des paramtres formels peuvent tre modifies dans le
corps de la fonction, mais sans influencer les valeurs des paramtres effectifs. On dit que les
paramtres dune fonction sont transmis par valeurs.

Par exemple, le programme suivant :


# include <stdio.h>
void echange (int , int);
void main (void)
{
int a = 10 , b = 20;
printf("Dbut du programme principal : \na=%d et b=%d\n" , a , b);
echange(a , b);
printf("Fin du programme principal : \na=%d et b=%d\n" , a , b);
}
void echange (int A , int B)
{
int temp;
printf("\tdbut fonction : \n\tA = %d et B = %d\n" , A , B);
temp = A;
A = B;
B = temp;
printf("\tfin fonction : \n\tA = %d et B = %d\n" , A, B);
}

80

Affiche
Dbut du programme principal :
a = 10 et b = 20
dbut fonction :
A = 10 et B = 20
fin fonction :
A = 20 et B = 10
Fin du programme principal :
a = 10 et b = 20

Cet exemple montre que la transmission de paramtres par valeur reprsente un mode
dchange dinformation dans un seul sens.
Pour changer la valeur d'une variable de la fonction appelante, on procde comme suit:
la fonction appelante doit fournir l'adresse de la variable;
la fonction appele doit dclarer le paramtre comme pointeur.
On peut alors atteindre la variable l'aide du pointeur. On parle alors de passage de
paramtres par adresse.

Par consquent, pour changer les valeurs de deux variables, il suffit de transmettre en
paramtre leurs adresses :
#include<stdio.h>
void echange (int *, int *);
void main (void)
{
int n = 10, p = 20;
printf("avant lappel: n=%d et p=%d\n" , n , p);
echange(&n , &p);
printf("aprs lappel: n=%d et p=%d\n" , n , p);
}
void echange (int *a, int *b)
{
int temp;
printf("\tdbut echange: *a = %d et *b = %d\n" , *a , *b);
temp = *a;
*a = *b;
*b = temp;
printf("\tfin echange: *a = %d et *b = %d\n" , *a , *b);
}

81

9. Passage de tableau une dimension en paramtre


Du fait de la conversion d'un identificateur de type tableau en adresse du premier lment,
lorsqu'un tableau est pass en paramtre effectif, c'est cette adresse qui est passe en paramtre.

Le paramtre formel correspondant peut tre dclar de deux manires diffrentes mais
quivalentes :

type *nom_tableau
type nom_tableau[]

Exemple :
#include<stdio.h>
#define Nmax 100
void affiche_tab(int t[], int n);
void lire_tab(int t[], int n);

/*
/*

void affiche_tab(int *t, int n); */


void lire_tab(int *t, int n); */

/*******************************************************************/
void affiche_tab(int t[], int n)
/* void affiche_tab(int *t, int n) */
{
int i;
for (i = 0; i < n; i++)
printf("%d\t", *(t + i) );
}
/*******************************************************************/
void lire_tab(int t[], int n)
/* void lire_tab(int *t, int n) */
{
int i;
for (i = 0; i < n; i++)
{
printf("Elment %d = ", i+1);

82

scanf("%d", t+i );

/* scanf("%d ",&t[i]); */

}
}
/*******************************************************************/
void main(void)
{
int tab[Nmax], n;
printf("Donnez la nouvelle dimension du tableau : ") ;
scanf("%d",&n);
lire_tab(tab, n);
affiche_tab(tab, n);
}

10. Passage de tableau deux dimensions en paramtre


Lorsquun tableau deux dimensions est pass en paramtre effectif, le paramtre formel
correspondant peut tre dclar de deux manires diffrentes mais quivalentes :

type nom_tableau[][Mmax]
type (*nom_tableau)[Mmax]

Exemple:
#include<stdio.h>
#define Nmax 100
#define Mmax 100
void affiche_tab(int t[][Mmax],int n,int m);
void lire_tab(int t[][Mmax],int n,int m);
/*******************************************************************/
void affiche_tab(int t[][Mmax],int n,int m)
{
int i,j;
for(i=0; i<n; i++)
{

83

for (j=0; j<m; j++)


printf("%d\t", t[i][j]);
printf("\n");
}
}
/*******************************************************************/
void lire_tab(int t[][Mmax],int n,int m)
{
int i,j;
for (i=0; i<n; i++)
for (j=0; j<m; j++)
{
printf("Element[%d][%d] = ", i+1,j+1);
scanf("%d", &t[i][j]);
}
}
/*******************************************************************/
void main(void)
{
int tab[Nmax][Mmax], n, m;
printf("Donnez le nombre de lignes du tableau : ");
scanf("%d",&n);
printf("Donnez le nombre de colonnes du tableau : ");
scanf("%d",&m);
lire_tab(tab, n, m);
affiche_tab(tab, n, m);
}

84

Chapitre 9 : Les Fichiers C.


1. Gnralits.
Les fichiers en C sont vus comme des flots doctets, il nexiste aucune structuration
logique ou physique en enregistrements comme cest le cas en COBOL par exemple. Si lon a
besoin dune telle structuration, cette dernire reste la charge du programmeur.
Il existe 2 types de fichiers, les fichiers texte contenant des codes ASCII et des passages
la ligne, et les fichiers binaires.
Il existe 2 mthodes de manipulation des fichiers :
Une mthode assiste avec buffer
Une mthode non assiste de bas niveau.
Le fichier header stdio.h contient :
Les fonctions dEntre/Sortie
La constante EOF
La constante NULL
Le type FILE

Avant tout travail sur un fichier, il faut louvrir dans un certain mode de travail. Quand les
travaux sont termins, il faut fermer le fichier.

2. Ouverture/fermeture de fichier.
a) Ouverture.
Syntaxe :
FILE * fopen(char * nom,char * mode)
FILE est un type descripteur de fichier

nom est une chane de caractres contenant le nom externe du fichier (nom systme).

85

mode indique le mode douverture, sous forme dune chane de caractres galement :
" r " lecture seule (erreur, si le fichier nexiste pas)
" w " criture seule(crasement, si le fichier existe)
" a" criture en fin de fichier
un + aprs le r ou w autorise la lecture.
Un t la fin du mode indique un fichier texte, un b un fichier binaire.
Si louverture choue, fopen renvoie NULL, sinon un pointeur vers un descripteur de

fichier. Toutes les autres instructions de manipulation de fichiers utilisent ce pointeur.


Exemple douverture dun fichier texte de nom f_donnees , en lecture :
#include <stdio.h>
---------------------------------FILE *fd ;
if((fd=fopen("f_donnees", "rt"))==NULL)
printf("\nerreur douverture");
else /* travailler sur le fichier */
{--------------------------------}
N.B.
Il existe 3 fichiers standards prdfinis :
stdin
stdout
stderr
b) Fermeture.
int fclose(FILE * f)
Ferme le fichier de nom interne f, et renvoie 0 si OK.

3. Lecture/criture de caractres.

86

Lecture de caractres.
int getc(FILE * f)
Retourne le caractre lu ou EOF (cest--dire la valeur -1).
Ecriture de caractres.
void putc(int c,FILE * f)
c est le caractre crire.

Exemple :
Copie dun fichier texte de nom entree dans un fichier texte de nom sortie ,
caractre par caractre.
int c ;
FILE *fentree, *fsortie ;
fentree=fopen(" entree ", "rt") ;
fsortie=fopen("sortie" , "wt");
while ((c=getc(fentree))!=EOF)
putc(c,fsortie);

4. Lecture/criture de lignes.
a) Lecture de lignes.
char * fgets(char * tampon, int taille,FILE * f)
Lit les caractres sur le fichier, les charge dans le tableau de caractres tampon, ou bien
jusqu ce quil ne reste quun seul caractre libre dans le tampon, et complte par \0.
Renvoie NULL en fin de fichier ou ladresse du tableau tampon sinon.
b) Ecriture de lignes.
int fputs(char * tampon,FILE * f)

87

5. Lecture/criture formates.
Lecture formate.
int fprintf(FILE * f, char * format,<liste de parametres>)
format est une chaine de caractres contenant des caractres afficher tels quels et des
spcifications de format, comme dans le printf. Le fonctionnement est analogue, sauf que
lcriture se fait dans le fichier f.
Ecriture formate.
int fscanf(FILE * f, char * format,<liste de parametres>)
fonctionnement est analogue celui de scanf.

6. Lecture/criture de blocs.
a) Lecture de blocs.
int fread(char * tampon, int taille,int nombre,FILE * f)
Le fread tente de lire nombre objets de taille taille, les installe, octet par octet dans
le tableau de caractres tampon, et renvoie le nombre dobjets effectivement transfrs.
b) Ecriture de blocs.
int fwrite(char * tampon, int taille,int nombre,FILE * f)
Le fwrite tente dcrire nombre objets de taille taille, octet par octet depuis le
tableau de caractres tampon, vers le fichier f et renvoie le nombre dobjets effectivement
transfrs.

7. Instructions de contrle.
a) Test de fin fichier.

88

int feof(FILE * f)
Renvoie 1 si fin de fichier, 0 sinon.
b) Erreur dE/S.
int ferror(FILE * f)
Renvoie 0 si pas derreur, 0 sinon.
Lerreur concerne la dernire opration dentre/sortie effectue.
c) Positionnement direct sur un octet.
A chaque fichier est associ un point de dplacement qui indique sur quel octet on est
positionn.
A louverture en lecture ou criture, on est positionn sur le premier octet. En append on
est positionn en fin de fichier.
En accs squentiel, la gestion du point de dplacement est automatique
En accs direct, ou lorsquon mlange les lectures et les critures, cest au programmeur
de se repositionner.
int fseek(FILE * f, long dep,int mode)
dep est un entier long indiquant un dplacement en octets partir dune certaine origine
dfinie par lentier mode, dont les valeurs possibles sont :
0 dbut du fichier
2 fin du fichier
1 position actuelle
Pour les valeurs 0 et 2, les dplacements sont positifs, alors que pour 1 le dplacement
peut tre sign.
N.B.
fseek renvoie 0 en cas de russite, 0 en cas dchec
d) Repositionnement en dbut de fichier.
void rewind(FILE * f)

89

quivaut

fseek(f,0L,0)

e) Position courante.
long ftell(FILE * f)
renvoie la valeur actuelle du point de dplacement .

90

Você também pode gostar