Sie sind auf Seite 1von 61

Cours du Langage C

Professeur : NAMEZ

Langage de Programmation
Structure C

BTS SRI - 1re Anne

Cours du Langage C

Professeur : NAMEZ

SOMMAIRE

Chapitre 1 :

NOTIONS DE BASE
Chapitre 2 :

TYPES DE BASE, OPRATEURS ET EXPRESSIONS


Chapitre 3 :

18

LIRE ET CRIRE DES DONNES


Chapitre 4 :

24

LA STRUCTURE ALTERNATIVE
Chapitre 5 :

29

LA STRUCTURE REPETITIVE
Chapitre 6 :

32

LES TABLEAUX
Chapitre 7 :

40

LES CHANES DE CARACTRES


Chapitre 8 :

47

LES POINTEURS
Chapitre 9 :

59

LES FONCTIONS

Cours du Langage C

Professeur : NAMEZ

Chapitre 1 :

NOTIONS DE BASE
1. Hello C !
Suivons la tradition et commenons la dcouverte de C par l'invitable programme 'hello world'. Ce
programme ne fait rien d'autre qu'imprimer les mots suivants sur l'cran:

Hello world
Comparons d'abord la dfinition du programme en C avec celle en langage algorithmique.
HELLO_WORLD en langage algorithmique

Algorithme HELLO_WORLD
Dbut
|
(* Notre premier programme en C *)
|
crire "hello, world"
Fin
HELLO_WORLD en C

#include <stdio.h>
|main()
|/* Notre premier programme en C */
|{
|
printf("hello, world\n");
|
return 0;
|}

2. Les composantes d'un programme en C


Les programmes en C sont composs essentiellement de fonctions et de variables. Pour la pratique, il
est donc indispensable de se familiariser avec les caractristiques fondamentales de ces lments.

2.1. La fonction main


La fonction main est la fonction principale des programmes en C : Elle se trouve obligatoirement dans
tous les programmes. L'excution d'un programme entrane automatiquement l'appel de la fonction
main.
Dans les premiers chapitres, nous allons simplement 'traduire' la structure Dbut -- Fin du
langage algorithmique par une dfinition quivalente de la fonction main :
Dfinition du programme principal en langage algorithmique

Algorithme <NomProgramme>
<Dclarations>
Dbut
|
<Instructions>
Fin
Dfinition de la fonction main en C

|main()
|{
|
<dclarations> ;
|
<instructions> ;
|
return 0;
|}

Cours du Langage C

Professeur : NAMEZ

Rsultat de main
- En principe tout programme devrait retourner une valeur comme code d'erreur son environnement.
Par consquent, le type rsultat de main est toujours int. En gnral, le type de main n'est pas
dclar explicitement, puisque c'est le type par dfaut. Nous allons terminer nos programmes par
l'instruction :

return 0;
Qui indique l'environnement que le programme s'est termin avec succs, sans anomalies ou
erreurs fatales.
- Si nous utilisons des fonctions prdfinies (par exemple: printf), il faut faire prcder la dfinition de
main par les instructions #include correspondantes.

2.2. Les variables


Les variables contiennent les valeurs qui sont utilises pendant l'excution du programme. Les noms
des variables sont des identificateurs quelconques.

2.3. Les identificateurs


Les noms des fonctions et des variables en C sont composs d'une suite de lettres et de chiffres. Le
premier caractre doit tre une lettre. Le symbole '_' est aussi considr comme une lettre.
* L'ensemble des symboles utilisables est donc :

{0,1,2,...,9,A,B,...,Z,_,a,b,...,z}
* Le premier caractre doit tre une lettre (ou le symbole '_')
* C distingue les majuscules et les minuscules, ainsi :
'Nom_de_variable' est diffrent de 'nom_de_variable'
* La longueur des identificateurs n'est pas limite, mais C distingue 'seulement' les 31 premiers
caractres.
Remarques :
- Il est dconseill d'utiliser le symbole '_' comme premier caractre pour un identificateur, car il est
souvent employ pour dfinir les variables globales de l'environnement C.
Exemples :
Identificateurs corrects:

Identificateurs incorrects:

nom1
nom_2
_nom_3
Nom_de_variable
deuxieme_choix
mot_francais

1nom
nom.2
-nom-3
Nom de variable
deuxime_choix
mot_franais

2.4. Les commentaires


Un commentaire commence toujours par les deux symboles '/*' et se termine par les symboles '*/'. Il
est interdit d'utiliser des commentaires imbriqus.
Exemples

/* Ceci est un commentaire correct */


/* Ceci est /* videmment */ dfendu */

Cours du Langage C

Professeur : NAMEZ

Chapitre 2 :

TYPES DE BASE, OPRATEURS ET EXPRESSIONS


Les variables et les constantes sont les donnes principales qui peuvent tre manipules par un
programme. Les dclarations introduisent les variables qui sont utilises, fixent leur type et parfois
aussi leur valeur de dpart. Les oprateurs contrlent les actions que subissent les valeurs des
donnes. Pour produire de nouvelles valeurs, les variables et les constantes peuvent tre combines
l'aide des oprateurs dans des expressions. Le type d'une donne dtermine l'ensemble des valeurs
admissibles, le nombre d'octets rserver en mmoire et l'ensemble des oprateurs qui peuvent y
tre appliqus.

1. Les types simples


Les charges du programmeur
Mme un programmeur utilisant C ne doit pas connatre tous les dtails des mthodes de codage et
de calcul, il doit quand mme tre capable de:
- choisir un type numrique appropri un problme donn ;
c--d.: trouver un optimum de prcision, de temps de calcul et d'espace rserver en mmoire
- choisir un type appropri pour la reprsentation sur l'cran
- prvoir le type rsultant d'une opration entre diffrents types numriques ;
c--d.: connatre les transformations automatiques de type que C accomplit lors des calculs (voir
3.7.1).
- prvoir et optimiser la prcision des rsultats intermdiaires au cours d'un calcul complexe ;
c--d.: changer si ncessaire l'ordre des oprations ou forcer l'ordinateur utiliser un type numrique
mieux adapt.

1.1. Les types entiers


Avant de pouvoir utiliser une variable, nous devons nous intresser deux caractristiques de son
type numrique:
(1) le domaine des valeurs admissibles
(2) le nombre d'octets qui est rserv pour une variable
Le tableau suivant rsume les caractristiques des types numriques entiers de C :
dfinition

description

domaine min

domaine max

nombre d'octets

char
short
int
long

caractre
entier court
entier standard
entier long

-128
-32768
-32768
-2147483648

127
32767
32767
2147483647

1
2
2
4

- char : caractre

Cours du Langage C

Professeur : NAMEZ

Une variable du type char peut contenir une valeur entre -128 et 127 et elle peut subir les mmes
oprations que les variables du type short, int ou long.
- int : entier standard
Sur chaque machine, le type int est le type de base pour les calculs avec les entiers. Le codage des
variables du type int est donc dpendant de la machine. Sur les IBM-PC sous MS-DOS, une variable
du type int est code dans deux octets.
- short : entier court
Le type short est en gnral cod dans 2 octets. Comme une variable int occupe aussi 2 octets sur
notre systme, le type short devient seulement ncessaire, si on veut utiliser le mme programme sur
d'autres machines, sur lesquelles le type standard des entiers n'est pas forcment 2 octets.
Remarques
1. Les valeurs limites des diffrents types sont indiques dans le fichier header <limits.h>.
2. En principe, on peut dire que

sizeof(short) <= sizeof(int) <= sizeof(long)


Ainsi sur certaine architecture on peut avoir :

short = 2 octets, int = 2 octets, long = 4 octets

1.2. Les types rationnels


En informatique, les rationnels sont souvent appels des 'flottants'. Ce terme vient de 'en virgule
flottante' et trouve sa racine dans la notation traditionnelle des rationnels:
<exposant>

<+|->
<mantisse>
<exposant>

<+|-> <mantisse> * 10
est le signe positif ou ngatif du nombre
est un dcimal positif avec un seul chiffre devant la virgule
est un entier relatif

Exemples

3.14159*100
4.3001*10321

1.25003*10-12
-1.5*103

En C, nous avons le choix entre trois types de rationnels: float, double et long double. Dans le
tableau ci-dessous, vous trouverez leurs caractristiques :

min et max

reprsentent les valeurs minimales et maximales positives. Les valeurs ngatives


peuvent varier dans les mmes domaines.

mantisse

indique le nombre de chiffres significatifs de la mantisse.

dfinition

prcision

float
simple
double
double
long double suppl.

mantisse

6
15
19

domaine min

domaine max

nombre d'octets

3.4 * 10-38
3.4 * 1038
4
1.7 * 10-308 1.7 * 10308 8
3.4 * 10-4932 1.1 * 104932 10

Cours du Langage C

Professeur : NAMEZ

2. La dclaration des variables simples


Dclaration de variables en langage algorithmique

<NomVar1>, <NomVar2>,..., <NomVarN> : <Type>


Dclaration de variables en C

<Type> <NomVar1>,<NomVar2>,...,<NomVarN>;
Prenons quelques dclarations du langage descriptif,

entier
COMPTEUR,X,Y
rel
HAUTEUR,LARGEUR,MASSE_ATOMIQUE
caractre
TOUCHE
boolen
T_PRESSEE
Et traduisons-les en des dclarations du langage C :

int
compteur,X,Y;
float
hauteur,largeur;
double
masse_atomique;
char
touche;
int
t_pressee;
Langage algorithmique --> C
En gnral, nous avons le choix entre plusieurs types et nous devons trouver celui qui correspond le
mieux au domaine et aux valeurs traiter. Voici quelques rgles gnrales qui concernent la
traduction des dclarations de variables numriques du langage algorithmique en C :
- La syntaxe des dclarations en C ressemble celle du langage algorithmique. Remarquez quand
mme les points-virgules la fin des dclarations en C.
Entier : Nous avons le choix entre tous les types entiers (inclusivement char) dans leurs formes
signe. Si les nombres deviennent trop grands, il faut utiliser un type rationnel (p.ex: double)
Rel : Nous pouvons choisir entre les trois types rationnels en observant non seulement la grandeur
maximale de l'exposant, mais plus encore le nombre de chiffres significatifs de la mantisse.
Caractre : Toute variable du type char peut contenir un (seul) caractre. En C, il faut toujours tre
conscient que ce 'caractre' n'est autre chose qu'un nombre correspondant un code (ici: code
ASCII). Ce nombre peut tre intgr dans toute sorte d'oprations algbriques ou logiques ...
Chane : En C il n'existe pas de type spcial pour chanes de caractres. Les moyens de traiter les
chanes de caractres seront dcrits au chapitre 8.
Boolen : En C il n'existe pas de type spcial pour variables boolennes. Tous les types de variables
numriques peuvent tre utiliss pour exprimer des oprations logiques:
valeur logique faux
valeur logique vrai

<=>
<=>

valeur numrique zro


toute valeur diffrente de zro

Cours du Langage C

Professeur : NAMEZ

Si l'utilisation d'une variable boolenne est indispensable, le plus naturel sera d'utiliser une variable du
type int.
Les oprations logiques en C retournent toujours des rsultats du type int :
0 pour faux
1 pour vrai

2.1. Les constantes numriques


En pratique, nous utilisons souvent des valeurs constantes pour calculer, pour initialiser des variables,
pour les comparer aux variables, etc. Dans ces cas, l'ordinateur doit attribuer un type numrique aux
valeurs constantes. Pour pouvoir prvoir le rsultat et le type exact des calculs, il est important pour le
programmeur de connatre les rgles selon lesquelles l'ordinateur choisit les types pour les
constantes.

- Les constantes entires


Type automatique
Lors de l'attribution d'un type une constante entire, C choisit en gnral la solution la plus
conomique :
Le type des constantes entires :
* Si possible, les constantes entires obtiennent le type int.
* Si le nombre est trop grand pour int (p.ex: -40000 ou +40000) il aura automatiquement le type long.
* Si le nombre est trop grand pour long, la raction du programme est imprvisible.
Base octale et hexadcimale
Il est possible de dclarer des constantes entires en utilisant la base octale ou hexadcimale :
* Si une constante entire commence par 0 (zro), alors elle est interprte en base octale.
* Si une constante entire commence par 0x ou 0X , alors elle est interprte en base hexadcimale.
Exemples
base dcimale

base octale

base hexadcimale

reprs. binaire

100
255
65536
12
4040

0144
0377
0200000
014
07710

0X64
0xff
0X10000
0XC
0xFC8

1100100
11111111
10000000000000000
1100
111111001000

- Les constantes rationnelles


Les constantes rationnelles peuvent tre indiques :
* en notation dcimale, c.--d. l'aide d'un point dcimal
Exemples

Cours du Langage C

123.4

-0.001

Professeur : NAMEZ

1.0

* en notation exponentielle, c.--d. l'aide d'un exposant spar du nombre dcimal par les
caractres 'e' ou 'E':
Exemples

1234e-1

-1E-3

0.01E2

L'ordinateur reconnat les constantes rationnelles au point dcimal ou au sparateur de l'exposant ('e'
ou 'E'). Par dfaut, les constantes rationnelles sont du type double.

- Les caractres constants


Les constantes qui dsignent un (seul) caractre sont toujours indiques entre des apostrophes, par
exemple 'x'. La valeur d'un caractre constant est le code interne de ce caractre. Ce code (ici : le
code ASCII) est dpendant de la machine.
Les caractres constants peuvent apparatre dans des oprations arithmtiques ou logiques, mais en
gnral ils sont utiliss pour tre compars des variables.
Squences d'chappement
Comme nous l'avons vu au chapitre 2, l'impression et l'affichage de texte peut tre contrl l'aide de
squences d'chappement. Une squence d'chappement est un couple de symboles dont le
premier est le signe d'chappement '\'. Au moment de la compilation, chaque squence
d'chappement est traduite en un caractre de contrle dans le code de la machine. Comme les
squences d'chappement sont identiques sur toutes les machines, elles nous permettent d'crire des
programmes portables, c--d. des programmes qui ont le mme effet sur toutes les machines,
indpendamment du code de caractres utilis.

\a
\b
\t
\n
\r
\0

sonnerie
curseur arrire
tabulation
nouvelle ligne
retour au dbut de ligne
NUL

\\
\?
\'
\"
\f
\v

trait oblique
point d'interrogation
apostrophe
guillemets
saut de page (imprimante)
tabulateur vertical

Le caractre NUL
La constante '\0' qui a la valeur numrique zro (ne pas confondre avec le caractre '0' !!) a une
signification spciale dans le traitement et la mmorisation des chanes de caractres: En C le
caractre '\0' dfinit la fin d'une chane de caractres.

2.2. Initialisation des variables


Initialisation
En C, il est possible d'initialiser les variables lors de leur dclaration :

int
MAX = 1023;
char
TAB = '\t';
float
X = 1.05e-4;

Cours du Langage C

Professeur : NAMEZ

En utilisant l'attribut const, nous pouvons indiquer que la valeur d'une variable ne change pas au
cours d'un programme:

const int
MAX = 767;
const double
e = 2.71828182845905;
const char
NEWLINE = '\n';

3. Les oprateurs standard


Affectation en langage algorithmique

<NomVariable> <Expression>
Affectation en C

<NomVariable> = <Expression>;
Exemples d'affectations
- L'affectation avec des valeurs constantes
Langage algorithmique

LONG 141
PI 3.1415926

LONG = 141;
(const. entire)
PI = 3.1415926; (const. relle)

Type de la constante

- L'affectation avec des valeurs de variables


Langage algorithmique

VALEUR X1A

VALEUR = X1A;

- L'affectation avec des valeurs d'expressions


Langage algorithmique

AIRE = PI*pow(R,2);
AIRE PI*R2
CORRECT ('a'='a') CORRECT = ('a' == 'a');
Observations
* il n'existe pas de fonction standard en C pour calculer le carr d'une valeur ; on peut se rfrer la
y
fonction plus gnrale pow(x,y) qui calcule x
* le test d'galit en C se formule avec deux signes d'galit ==, l'affectation avec un seul = .

3.1. Les oprateurs connus


Oprateurs arithmtiques

+
*
/
%

addition
soustraction
multiplication
division (entire et rationnelle!)
modulo (reste d'une div. entire)

10

Cours du Langage C

Professeur : NAMEZ

Oprateurs logiques

&& et logique (and)


|| ou logique (or)
!
ngation logique (not)
Oprateurs de comparaison

==
gal
!=
diffrent de
<, <=, >, >= plus petit que, ...
Oprations logiques
Les rsultats des oprations de comparaison et des oprateurs logiques sont du type int :
- la valeur 1 correspond la valeur boolenne vrai
- la valeur 0 correspond la valeur boolenne faux
Les oprateurs logiques considrent toute valeur diffrente de zro comme vrai et zro comme faux :

32 && 2.3
!65.34
0||!(32 > 12)

1
0
0

3.2. Les oprateurs particuliers de C


- Les oprateurs d'affectation
En pratique, nous retrouvons souvent des affectations comme : i = i + 2
En C, nous utiliserons plutt la formulation plus compacte : i += 2
L'oprateur += est un oprateur d'affectation.
Pour la plupart des expressions de la forme :
expr1 = (expr1) op (expr2)
Il existe une formulation quivalente qui utilise un oprateur d'affectation :
expr1 op= expr2
Oprateurs d'affectation

+=
-=
*=
/=
%=

ajouter
diminuer de
multiplier par
diviser par
modulo

Avantages

11

Cours du Langage C

Professeur : NAMEZ

La formulation avec un oprateur d'affectation est souvent plus prs de la logique humaine : Un
homme dirait <<Ajoute 2 I>> plutt que <<Ajoute 2 I et cris le rsultat dans I>>
Les oprateurs d'affectation peuvent aider le compilateur gnrer un code plus efficient parce que
expr1 n'est valu qu'une seule fois.
- Les oprateurs d'incrmentation et de dcrmentation
Les affectations les plus frquentes sont du type :

I = I + 1

et

I = I - 1

En C, nous disposons de deux oprateurs inhabituels pour ces affectations :

I++ ou ++I pour l'incrmentation


(augmentation d'une unit)
I-- ou --I pour la dcrmentation (diminution d'une unit)
Les oprateurs ++ et -- sont employs dans les cas suivants :
- Incrmenter/dcrmenter une variable (p.ex: dans une boucle). Dans ce cas il n'y a pas de
diffrence entre la notation prfixe (++I --I) et la notation postfixe (I++ I--).
- Incrmenter/dcrmenter une variable et en mme temps affecter sa valeur une autre variable.
Dans ce cas, nous devons choisir entre la notation prfixe et postfixe :

X
X
X
X

=
=
=
=

I++
I-++I
--I

passe d'abord la valeur de I X et incrmente aprs


passe d'abord la valeur de I X et dcrmente aprs
incrmente d'abord et passe la valeur incrmente X
dcrmente d'abord et passe la valeur dcrmente X

Exemple
Supposons que la valeur de N est gale 5:
Incrm. postfixe
Incrm. prfixe

X = N++; Rsultat: N=6 et X=5


X = ++N; Rsultat: N=6 et X=6

4. Les expressions et les instructions


Expressions
Les constantes et les variables sont des expressions.
Les expressions peuvent tre combines entre elles par des oprateurs et former ainsi des
expressions plus complexes.
Une expression comme I=0 ou I++ ou printf(...) devient une instruction, si elle est suivie
d'un point-virgule.
Exemples

i=0;
i++;
X=pow(A,4);
printf(" Bonjour !\n");

12

Cours du Langage C

Professeur : NAMEZ

a=(5*x+10*y)*2;
valuation et rsultats
En C toutes les expressions sont values et retournent une valeur comme rsultat :

(3+2==5) retourne la valeur 1 (vrai)

5. Les priorits des oprateurs


Exemple
Supposons pour l'instruction suivante : A=5 ; B=10 ; C=1 ; X = 2*A+3*B+4*C ;
L'ordinateur value d'abord les multiplications : 2*A ==> 10, 3*B ==> 30, 4*C ==> 4
Ensuite, il fait l'addition des trois rsultats obtenus : 10+30+4 ==> 44
A la fin, il affecte le rsultat gnral la variable : X = 44
Priorit d'un oprateur
On dit alors que la multiplication a la priorit sur l'addition et que la multiplication et l'addition ont la
priorit sur l'affectation.
Si nous voulons forcer l'ordinateur commencer par un oprateur avec une priorit plus faible, nous
devons (comme en mathmatiques) entourer le terme en question par des parenthses.
Classes de priorits
Priorit 1 (la plus forte):
Priorit 2:
Priorit 3:
Priorit 4:
Priorit 5:
Priorit 6:
Priorit 7:
Priorit 8:
Priorit 9 (la plus faible):

()
! ++ -* / %
+ < <= > >=
== !=
&&
||
= += -= *= /= %=

Evaluation d'oprateurs de la mme classe


* Dans chaque classe de priorit, les oprateurs ont la mme priorit. Si nous avons une suite
d'oprateurs binaires de la mme classe, l'valuation se fait en passant de la gauche vers la droite
dans l'expression.
* Pour les oprateurs unaires (!,++,--) et pour les oprateurs d'affectation ( =,+=,=,*=,/=,%=), l'valuation se fait de droite gauche dans l'expression.
Exemples
L'expression 10+20+30-40+50-60 sera value comme suit :

13

Cours du Langage C

10+20

==>

30
30+30

Professeur : NAMEZ

==>

60
60-40

==>

20
20+50

==>

70
70-60

==>

10

Pour A=3 et B=4, l'expression A *= B += 5 sera value comme suit :

Pour A=1 et B=4, l'expression !--A==++!B sera value comme suit :

Exemple
Observez la priorit des oprateurs d'affectation :

X *= Y + 1
X *= Y + 1

<=>
n'quivaut PAS

X = X * (Y + 1)
X = X * Y + 1

6. Les fonctions arithmtiques standard


Les fonctions suivantes sont prdfinies dans la bibliothque standard <math>. Pour pouvoir les
utiliser, le programme doit contenir la ligne :
#include <math.h>
Type des donnes
Les arguments et les rsultats des fonctions arithmtiques sont du type double.
Fonctions arithmtiques
COMMANDE C

exp(X)
log(X)
log10(X)
pow(X,Y)

EXPLICATION
fonction exponentielle
logarithme naturel
logarithme base 10
X exposant Y

LANG. ALGORITHMIQUE

eX
ln(X), X>0
log10(X), X>0
XY

14

Cours du Langage C

sqrt(X)
fabs(X)
floor(X)
ceil(X)
fmod(X,Y)

Professeur : NAMEZ

racine carre de X
valeur absolue de X
arrondir en moins
arrondir en plus
reste rationnel de X/Y (mme signe que X)

|X|
int(X)

sin(X) cos(X) tan(X)


sinus, cosinus, tangente de X
asin(X) acos(X) atan(X) arcsin(X), arccos(X), arctan(X)
sinh(X) cosh(X) tanh(X) sinus, cosinus, tangente hyperboliques de X

7. Les conversions de type


La grande souplesse du langage C permet de mlanger des donnes de diffrents types dans une
expression. Avant de pouvoir calculer, les donnes doivent tre converties dans un mme type. La
plupart de ces conversions se passent automatiquement, sans l'intervention du programmeur, qui doit
quand mme prvoir leur effet. Parfois il est ncessaire de convertir une donne dans un type
diffrent de celui que choisirait la conversion automatique; dans ce cas, nous devons forcer la
conversion l'aide d'un oprateur spcial ("cast").

7.1. Les conversions de type automatiques


- Calculs et affectations
Si un oprateur a des oprandes de diffrents types, les valeurs des oprandes sont converties
automatiquement dans un type commun.
Ces manipulations implicites convertissent en gnral des types plus 'petits' en des types plus
'larges'; de cette faon on ne perd pas en prcision.
Lors d'une affectation, la donne droite du signe d'galit est convertie dans le type gauche du
signe d'galit. Dans ce cas, il peut y avoir perte de prcision si le type de la destination est plus faible
que celui de la source.
Exemple
Considrons le calcul suivant :

int I = 8;
float X = 12.5;
double Y;
Y = I * X;
Pour pouvoir tre multipli avec X, la valeur de I est convertie en float (le type le plus large des deux).
Le rsultat de la multiplication est du type float, mais avant d'tre affect a Y, il est converti en
double. Nous obtenons comme rsultat :

Y = 100.00
- Appels de fonctions
Lors de l'appel d'une fonction, les paramtres sont automatiquement convertis dans les types dclars
dans la dfinition de la fonction.
Exemple

15

Cours du Langage C

Professeur : NAMEZ

Au cours des expressions suivantes, nous assistons trois conversions automatiques :

int A = 200;
int RES;
RES = pow(A, 2);
A l'appel de la fonction pow, la valeur de A et la constante 2 sont converties en double, parce que
pow est dfinie pour des donnes de ce type. Le rsultat (type double) retourn par pow doit tre
converti en int avant d'tre affect RES.
- Rgles de conversion automatique
Conversions automatiques lors d'une opration avec,
(1) deux entiers:
D'abord, les types char et short sont convertis en int. Ensuite, l'ordinateur choisit le plus large des
deux types dans l'chelle suivante : int, long
(2) un entier et un rationnel:
Le type entier est converti dans le type du rationnel.
(3) deux rationnels:
L'ordinateur choisit le plus large des deux types selon l'chelle suivante : float, double, long double
(4) affectations et oprateurs d'affectation:
Lors d'une affectation, le rsultat est toujours converti dans le type de la destination. Si ce type est
plus faible, il peut y avoir une perte de prcision.
Exemple
Observons les conversions ncessaires lors d'une simple division :

int X;
float A=12.48;
char B=4;
X=A/B;
B est converti en float (rgle 2). Le rsultat de la division est du type float (valeur 3.12) et sera
converti en int avant d'tre affect X (rgle 4), ce qui conduit au rsultat X=3.
Exemple
Dans cet exemple, nous divisons 3 par 4 trois reprises et nous observons que le rsultat ne dpend
pas seulement du type de la destination, mais aussi du type des oprandes.

char A=3;
int B=4;
float C=4;
float D,E;

16

Cours du Langage C

Professeur : NAMEZ

char F;
D = A/C;
E = A/B;
F = A/C;
* Pour le calcul de D, A est converti en float (rgle 2) et divis par C. Le rsultat (0.75) est affect D
qui est aussi du type float. On obtient donc: D=0.75
* Pour le calcul de E, A est converti en int (rgle 1) et divis par B. Le rsultat de la division (type int,
valeur 0) est converti en float (rgle 4). On obtient donc: E=0.000
* Pour le calcul de F, A est converti en float (rgle 2) et divis par C. Le rsultat (0.75) est retraduit en
char (rgle 4). On obtient donc: F=0
- Perte de prcision
Lorsque nous convertissons une valeur en un type qui n'est pas assez prcis ou pas assez grand, la
valeur est coupe sans arrondir et sans nous avertir ...

7.2. Les conversions de type forces (casting)


Il est possible de convertir explicitement une valeur en un type quelconque en forant la
transformation l'aide de la syntaxe :

(<Type>) <Expression>
Exemple
Nous divisons deux variables du type entier. Pour avoir plus de prcision, nous voulons avoir un
rsultat de type rationnel. Pour ce faire, nous convertissons l'une des deux oprandes en float.
Automatiquement C convertira l'autre oprande en float et effectuera une division rationnelle :

char A=3;
int B=4;
float C;
C = (float)A/B;
La valeur de A est explicitement convertie en float. La valeur de B est automatiquement convertie en
float (rgle 2). Le rsultat de la division (type rationnel, valeur 0.75) est affect C.
Rsultat : C=0.75
Attention !
Les contenus de A et de B restent inchangs; seulement les valeurs utilises dans les calculs sont
converties !

17

Cours du Langage C

Professeur : NAMEZ

Chapitre 3 :

LIRE ET CRIRE DES DONNES


1. criture formate de donnes
La fonction printf est utilise pour transfrer du texte, des valeurs de variables ou des rsultats
d'expressions vers le fichier de sortie standard stdout (par dfaut l'cran).
Ecriture formate en langage algorithmique

crire <Expression1>, <Expression2>, ...


Ecriture formate en C

printf("<format>",<Expr1>,<Expr2>, ... )
"<format>"
<Expr1>,...

format de reprsentation
variables et expressions dont les valeurs sont reprsenter

La partie "<format>" est en fait une chane de caractres qui peut contenir :
* du texte
* des squences d'chappement
* des spcificateurs de format
* Les spcificateurs de format indiquent la manire dont les valeurs des expressions <Expr1N>
sont imprimes.
* La partie "<format>" contient exactement un spcificateur de format pour chaque expression
<Expr1...N>.
* Les spcificateurs de format commencent toujours par le symbole % et se terminent par un ou deux
caractres qui indiquent le format d'impression.
* Les spcificateurs de format impliquent une conversion d'un nombre en chane de caractres. Ils
sont encore appels symboles de conversion.
Exemple 1

int A = 1234;
int B = 567;
printf("%i fois %i est %li\n", A, B, (long)A*B);
La suite d'instructions va afficher sur l'cran :

1234 fois 567 est 699678


Les arguments de printf sont :
-

la partie format

"%i fois %i est %li"

18

Cours du Langage C

la variable
la variable
l'expression
er

Le 1

Le 2

Le 3

Professeur : NAMEZ

A
B
(long)A*B

spcificateur (%i) indique que la valeur de A


sera imprime comme entier relatif

==>1234

spcificateur (%i) indique que la valeur de B


sera imprime comme entier relatif

==> 567

spcificateur (%li) indique que la valeur de (long)A*B sera imprime


comme entier relatif long

==> 699678

Exemple 2

char B = 'A';
printf("Le caractre %c a le code %i !\n", B, B);
La suite d'instructions va afficher sur l'cran :

Le caractre A a le code 65 !
La valeur de B est donc affiche sous deux formats diffrents :

%c comme caractre
A
%i comme entier relatif 65
Spcificateurs de format pour printf

SYMBOLE
%d ou %i
%o
%x
%c
%f
%e
%s

TYPE
int
int
int
int
double
double
char*

IMPRESSION COMME
entier relatif
entier exprim en octal
entier exprim en hexadcimal
caractre
rationnel en notation dcimale
rationnel en notation scientifique
chane de caractres

1. Arguments du type long


Les spcificateurs %d, %i, %o, %x peuvent seulement reprsenter des valeurs du type int. Une
valeur trop grande pour tre code dans deux octets est coupe sans avertissement si nous utilisons
%d.
Pour pouvoir traiter correctement les arguments du type long, il faut utiliser les spcificateurs %ld,
%li, %lo, %lx.
2. Arguments rationnels
Les spcificateurs %f et %e peuvent tre utiliss pour reprsenter des arguments du type float ou
double. La mantisse des nombres reprsents par %e contient exactement un chiffre (non nul) devant
le point dcimal. Cette reprsentation s'appelle la notation scientifique des rationnels.
Pour pouvoir traiter correctement les arguments du type long double, il faut utiliser les spcificateurs
%Lf et %Le.

19

Cours du Langage C

Professeur : NAMEZ

3. Largeur minimale pour les entiers


Pour les entiers, nous pouvons indiquer la largeur minimale de la valeur afficher. Dans le champ
ainsi rserv, les nombres sont justifis droite.
Exemples
( _ <=> position libre)

printf("%4d",
printf("%4d",
printf("%4d",
printf("%4u",
printf("%4X",
printf("%4x",

123);
1234);
12345);
0);
123);
123);

==>
==>
==>
==>
==>
==>

_123
1234
12345
___0
__7B
__7b

4. Largeur minimale et prcision pour les rationnels


Pour les rationnels, nous pouvons indiquer la largeur minimale de la valeur afficher et la prcision du
nombre afficher. La prcision par dfaut est fixe six dcimales. Les positions dcimales sont
arrondies la valeur la plus proche.
Exemples

printf("%f", 100.123);
printf("%12f", 100.123);
printf("%.2f", 100.123);
printf("%5.0f", 100.123);
printf("%10.3f", 100.123);
printf("%.4f", 1.23456);

==>
==>
==>
==>
==>
==>

100.123000
__100.123000
100.12
__100
___100.123
1.2346

2. Lecture formate de donnes


La fonction scanf est la fonction symtrique printf; elle nous offre pratiquement les mmes
conversions que printf, mais en sens inverse.
Lecture formate en langage algorithmique

lire <NomVariable1>,<NomVariable2>, ...


Lecture formate en C

scanf("<format>",<AdrVar1>,<AdrVar2>, ...)
"<format>"
<AdrVar1>,...

:
:

format de lecture des donnes


adresses des variables auxquelles les donnes seront attribues

* La fonction scanf reoit ses donnes partir du fichier d'entre standard stdin (par dfaut le clavier).
* La chane de format dtermine comment les donnes reues doivent tre interprtes.
* Les donnes reues correctement sont mmorises successivement aux adresses indiques par
<AdrVar1>,... .

20

Cours du Langage C

Professeur : NAMEZ

* L'adresse d'une variable est indique par le nom de la variable prcd du signe &.
Exemple
La suite d'instructions :

int JOUR, MOIS, ANNEE;


scanf("%i %i %i", &JOUR, &MOIS, &ANNEE);
lit trois entiers relatifs, spars par des espaces, tabulations ou interlignes. Les valeurs sont attribues
respectivement aux trois variables JOUR, MOIS et ANNEE.
* scanf retourne comme rsultat le nombre de donnes correctement reues (type int).
Spcificateurs de format pour scanf

SYMBOLE
%d ou %i
%c
%s
%f ou %e

LECTURE D'UN
entier relatif
caractre
chane de caractres
rationnel en notation dcimale ou exponentielle (scientifique)

1. Le type long
Si nous voulons lire une donne du type long, nous devons utiliser les spcificateurs %ld, %li, %lu,
%lo, %lx. (Sinon, le nombre est simplement coup la taille de int).
2. Le type double
Si nous voulons lire une donne du type double, nous devons utiliser les spcificateurs %le ou %lf.
3. Le type long double
Si nous voulons lire une donne du type long double, nous devons utiliser les spcificateurs %Le ou
%Lf.
4. Les signes d'espacement
Lors de l'entre des donnes, une suite de signes d'espacement (espaces, tabulateurs, interlignes)
est value comme un seul espace. Dans la chane de format, les symboles \t, \n, \r ont le mme
effet qu'un simple espace.
Exemple
Pour la suite d'instructions

int JOUR, MOIS, ANNEE;


scanf("%i %i %i", &JOUR, &MOIS, &ANNEE);
Les entres suivantes sont correctes et quivalentes :

12 4 1980
ou
12
004
ou

1980

21

Cours du Langage C

Professeur : NAMEZ

12
4
1980
5. Formats 'spciaux'
Si la chane de format contient aussi d'autres caractres que des signes d'espacement, alors ces
symboles doivent tre introduits exactement dans l'ordre indiqu.
Exemple : La suite d'instructions

int JOUR, MOIS, ANNEE;


scanf("%i/%i/%i", &JOUR, &MOIS, &ANNEE);
accepte les entres :

rejette les entres :

12/4/1980
12/04/01980

12 4 1980
12 /4 /1980

3. criture d'un caractre


La commande :

putchar('a');
Transfre le caractre a vers le fichier standard de sortie stdout. Les arguments de la fonction
putchar sont ou bien des caractres (c.--d. des nombres entiers entre 0 et 255).
Type de l'argument
Ainsi, les arguments de putchar sont par dfinition du type int et toutes les valeurs traites par
putchar (mme celles du type char) sont d'abord converties en int.
Exemples

char A = 225;
char B = '\a';
int C = '\a';
putchar('x');
putchar('?');
putchar('\n');
putchar(65);
putchar(A);
putchar(B);
putchar(C);
putchar(EOF);

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

afficher la lettre x
afficher le symbole ?
retour la ligne
afficher le symbole avec
le code 65 (ASCII: 'A')
afficher la lettre avec
le code 225 (ASCII: '')
beep sonore
beep sonore
marquer la fin du fichier

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

4. Lecture d'un caractre


Une fonction plus souvent utilise que putchar est la fonction getchar, qui lit le prochain caractre du
fichier d'entre standard stdin.

22

Cours du Langage C

Professeur : NAMEZ

Type du rsultat
Les valeurs retournes par getchar sont ou bien des caractres (0 - 255), le type rsultat de getchar
est int. En gnral, getchar est utilis dans une affectation :

int C;
C = getchar();
Remarque :
getchar lit les donnes de la zone tampon de stdin et fournit les donnes seulement aprs
confirmation par 'Enter'. La bibliothque <conio> contient une fonction du nom getch qui fournit
immdiatement le prochain caractre entr au clavier.

23

Cours du Langage C

Professeur : NAMEZ

Chapitre 4 :

LA STRUCTURE ALTERNATIVE
Les structures de contrle dfinissent la suite dans laquelle les instructions sont effectues.
Constatons dj que la particularit la plus importante des instructions de contrle en C est le fait que
les 'conditions' en C peuvent tre des expressions quelconques qui fournissent un rsultat numrique.
La valeur zro correspond la valeur logique faux et toute valeur diffrente de zro est considre
comme vrai.

1. if - else
if ( <expression> )
<bloc d'instructions 1>
else
<bloc d'instructions 2>
* Si l'<expression> fournit une valeur diffrente de zro, alors le <bloc d'instructions 1> est excut.
* Si l'<expression> fournit la valeur zro, alors le <bloc d'instructions 2> est excut.
La partie <expression> peut dsigner :
Une variable d'un type numrique,
Une expression fournissant un rsultat numrique.
La partie <bloc d'instructions> peut dsigner :
Un (vrai) bloc d'instructions compris entre accolades,
Une seule instruction termine par un point-virgule.
Exemple 1

if (a > b)
max = a;
else
max = b;
Exemple 2

if (EGAL)
printf("A est gal B\n");
else
printf("A est diffrent de B\n");
Exemple 3

if (A-B) printf("A est diffrent de B\n");


else printf("A est gal B\n");

24

Cours du Langage C

Professeur : NAMEZ

2. if sans else
La partie else est facultative. On peut donc utiliser if de la faon suivante :
if sans else

if ( <expression> )
<bloc d'instructions>
Attention !
Comme la partie else est optionnelle, les expressions contenant plusieurs structures if et if - else
peuvent mener des confusions.
Exemple
L'expression suivante peut tre interprte de deux faons :

if (N>0)
if (A>B)
MAX=A;
else
MAX=B;

if (N>0)
if (A>B)
MAX=A;
else
MAX=B;

Pour N=0, A=1 et B=2,


* dans la premire interprtation, MAX reste inchang,
* dans la deuxime interprtation, MAX obtiendrait la valeur de B.
Sans rgle supplmentaire, le rsultat de cette expression serait donc imprvisible.
Convention
En C une partie else est toujours lie au dernier if qui ne possde pas de partie else.
Dans notre exemple, C utiliserait donc la premire interprtation.
Solution
Pour viter des confusions et pour forcer une certaine interprtation d'une expression, il est
recommand d'utiliser des accolades { }.
Exemple
Pour forcer la deuxime interprtation de l'expression ci-dessus, nous pouvons crire :

if (N>0)
{
if (A>B)
MAX=A;
}
else
MAX=B;

25

Cours du Langage C

Professeur : NAMEZ

3. if - else if - ... - else


En combinant plusieurs structures if - else en une expression nous obtenons une structure qui est
trs courante pour prendre des dcisions entre plusieurs alternatives :
if - else - ... - else

if ( <expr1> )
<bloc1>
else if (<expr2>)
<bloc2>
else if (<expr3>)
<bloc3>
else if (<exprN>)
<blocN>
else <blocN+1>
Les expressions <expr1> ... <exprN> sont values du haut vers le bas jusqu' ce que l'une d'elles
soit diffrente de zro. Le bloc d'instructions y li est alors excut et le traitement de la commande
est termin.
Exemple

#include <stdio.h>
main()
{
int A,B;
printf("Entrez deux nombres entiers :");
scanf("%i %i", &A, &B);
if (A > B)
printf("%i est plus grand que %i\n", A, B);
else if (A < B)
printf("%i est plus petit que %i\n", A, B);
else
printf("%i est gal %i\n", A, B);
return 0;
}
La dernire partie else traite le cas o aucune des conditions n'a t remplie. Elle est optionnelle,
mais elle peut tre utilise trs confortablement pour dtecter des erreurs.

4. switch case - break default


Linstruction switch compare une valeur une srie de constantes et permet dexcuter des
instructions dans les cas o la valeur est gale une de ces constantes :
Syntaxe de lnstruction switch case - break default

Switch (expression) {
Case constante_1 :
<Bloc dinstructions_1> ;
Break ;
Case constante_2 :
<Bloc dinstructions_2> ;

26

Cours du Langage C

Professeur : NAMEZ

Break ;

Case constante_N :
<Bloc dinstructions_N> ;
Break ;
Default :
<Bloc dinstructions_N+1> ;
}
* Expression : expression entire quelconque.
* Constante_1 Constante_2 Constante_N : expressions constantes dun type entier quelconque
(le type char est accept car il sera converti en int).
* <Bloc dinstructions_1> <Bloc dinstructions_N> : squences dinstructions quelconques.
Ceci est quivalent :

if (expression==constante_1)
<Block dinstuctions_1> ;
else if (valeur==constante_2)
<Block dinstuctions_2> ;

else if (valeur==constante_N)
<Block dinstuctions_N> ;
else
<Block dinstuctions_N+1> ;
Attention !
Linstruction break sert interrompre le flux dexcution. Si on lomet, les instructions suivant les
case sont excutes en squence :

Switch (valeur) {
Case constante1 :
Instructions1 ;
Case constante2 :
Instructions2 ;
Default :
Instructions3 ;
}
Est quivalent :

if (valeur==constante1) {
instuctions1 ;
instuctions2 ;
instuctions3 ;
}
else if (valeur==constante2) {
instuctions2 ;

27

Cours du Langage C

Professeur : NAMEZ

instuctions3 ;
}
else
instuctions3 ;

5. Les oprateurs conditionnels


Le langage C possde une paire d'oprateurs un peu exotiques qui peut tre utilise comme
alternative if - else et qui a l'avantage de pouvoir tre intgre dans une expression :
Les oprateurs conditionnels

<expr1> ? <expr2> : <expr3>


* Si <expr1> fournit une valeur diffrente de zro, alors la valeur de <expr2> est fournie comme
rsultat.
* Si <expr1> fournit la valeur zro, alors la valeur de <expr3> est fournie comme rsultat.
Exemple
La suite d'instructions :

if (A>B)
MAX=A;
else
MAX=B;
Peut tre remplace par :

MAX = (A > B) ? A : B;
Employs de faon irrflchis, les oprateurs conditionnels peuvent nuire la lisibilit d'un
programme, mais si on les utilise avec prcaution, ils fournissent des solutions trs lgantes :
Exemple

printf("Vous avez %i carte%c \n", N, (N==1) ? ' ' : 's');


Remarque
Les rgles de conversion de types s'appliquent aussi aux oprateurs conditionnels ? : Ainsi, pour
un entier N du type int et un rationnel F du type float, l'expression

(N>0) ? N : F
Va toujours fournir un rsultat du type float, n'importe si N est plus grand ou plus petit que zro !

28

Cours du Langage C

Professeur : NAMEZ

Chapitre 5 :

LA STRUCTURE REPETITIVE
En C, nous disposons de trois structures qui nous permettent la dfinition de boucles conditionnelles:
1) la structure while
2) la structure do - while
3) la structure for

1. while
while ( <expression> )
<bloc d'instructions>
* Tant que l'<expression> fournit une valeur diffrente de zro, le <bloc d'instructions> est excut.
* Si l'<expression> fournit la valeur zro, l'excution continue avec l'instruction qui suit le bloc
d'instructions.
* Le <bloc d'instructions> est excut zro ou plusieurs fois.
La partie <bloc d'instructions> peut dsigner : Un (vrai) bloc d'instructions compris entre accolades ou
Une seule instruction termine par un point-virgule.
Exemple 1

/* Afficher les nombres de 0 9 */


int I = 0;
while (I<10)
{
printf("%d \n", I);
I++;
}
Exemple 2

int I;
/* Afficher les nombres de 0 9 */
I = 0;
while (I<10)
printf("%i \n", I++);
Exemple 3

/* Afficher les nombres de 10 1 */


int I=10;
while (I>0)
{
printf("%i \n", I);
I-- ;
}

29

Cours du Langage C

Professeur : NAMEZ

2. do - while
La structure do - while est semblable la structure while, avec la diffrence suivante :
* while value la condition avant d'excuter le bloc d'instructions,
* do - while value la condition aprs avoir excut le bloc d'instructions. Ainsi le bloc d'instructions
est excut au moins une fois.
La structure do - while en C

do
<bloc d'instructions>
while ( <expression> );
* Le <bloc d'instructions> est excut au moins une fois et aussi longtemps que l'<expression> fournit
une valeur diffrente de zro.
En pratique, la structure do - while n'est pas si frquente que while ; mais dans certains cas, elle
fournit une solution plus lgante. Une application typique de do - while est la saisie de donnes qui
doivent remplir une certaine condition : Le contrle de saisie
Exemple 1

float N;
do
{
printf("Introduisez un nombre entre 1 et 10 :");
scanf("%f", &N);
}
while (N<1 || N>10);
Exemple 2

int n, div;
printf("Entrez le nombre diviser : ");
scanf("%i", &n);
do
{
printf("Entrez le diviseur (diffrent de 0) : ");
scanf("%i", &div);
}
while (div==0);
printf("%i / %i = %f\n", n, div, (float)n/div);
Remarque
do - while est comparable la structure rpter du langage algorithmique (repeat until en Pascal) si
la condition finale est inverse logiquement.

3. for
30

Cours du Langage C

Professeur : NAMEZ

for ( <expr1> ; <expr2> ; <expr3> )


<bloc d'instructions>
Est quivalent :

<expr1>;
while ( <expr2> )
{
<bloc d'instructions>
<expr3>;
}
<expr1> est value une fois avant le passage de la boucle. Elle est utilise pour initialiser les
donnes de la boucle.
<expr2> est value avant chaque passage de la boucle. Elle est utilise pour dcider si la boucle est
rpte ou non.
<expr3> est value la fin de chaque passage de la boucle. Elle est utilise pour rinitialiser les
donnes de la boucle.
Le plus souvent, for est utilis comme boucle de comptage :

for ( <init.> ; <cond. rptition> ; <compteur> )


<bloc d'instructions>
Exemple 1

int I;
for (I=0 ; I<=20 ; I++)
printf("Le carr de %d est %d \n", I, I*I);
En pratique, les parties <expr1> et <expr2> contiennent souvent plusieurs initialisations ou
rinitialisations, spares par des virgules.
Exemple 2

int n, S=0;
for (n=1 ; n<=100 ; n++)
S+=n;
printf("La somme des nombres de 1 100 est %d\n", S);

31

Cours du Langage C

Professeur : NAMEZ

Chapitre 5 :

LES TABLEAUX
1. Les tableaux une dimension
Un tableau (uni-dimensionnel) A est une variable structure forme d'un nombre entier N de variables
simples du mme type, qui sont appeles les composantes du tableau. Le nombre de composantes
N est alors la dimension du tableau.

1.1. Dclaration et mmorisation


Dclaration

<TypeSimple> <NomTableau>[<Dimension>];
Exemples

int A[25];
ou bien
float B[100]; ou bien
int C[10];
char D[30];

long A[25];
ou bien
double B[100]; ou bien

...
...

Mmorisation
En C, le nom d'un tableau est le reprsentant de l'adresse du premier lment du tableau. Les
adresses des autres composantes sont calcules (automatiquement) relativement cette adresse.
Exemple

short A[5] = {1200, 2300, 3400, 4500, 5600};

Si un tableau est form de N composantes et si une composante a besoin de M octets en mmoire,


alors le tableau occupera de N*M octets.
Exemple
En supposant qu'une variable du type long occupe 4 octets (c.--d: sizeof(long)=4), pour le
tableau T dclar par :

long T[15];
C rservera N*M = 15*4 = 60 octets en mmoire.

32

Cours du Langage C

Professeur : NAMEZ

1.2. Initialisation et rservation automatique


Initialisation
Lors de la dclaration d'un tableau, on peut initialiser les composantes du tableau, en indiquant la liste
Exemples

int A[5]
= {10, 20, 30, 40, 50};
float B[4] = {-1.05, 3.33, 87e-5, -12.3E4};
int C[10] = {1, 0, 0, 1, 1, 1, 0, 1, 0, 1};
Il faut videmment veiller ce que le nombre de valeurs dans la liste corresponde la dimension du
tableau. Si la liste ne contient pas assez de valeurs pour toutes les composantes, les composantes
restantes sont initialises par zro.
Rservation automatique
Si la dimension n'est pas indique explicitement lors de l'initialisation, alors l'ordinateur rserve
automatiquement le nombre d'octets ncessaires.
Exemples

int A[] = {10, 20, 30, 40, 50};


==> Rservation de 5*sizeof(int) octets (dans notre cas : 10 octets)
float B[] = {-1.05, 3.33, 87e-5, -12.3E4};
==> Rservation de 4*sizeof(float) octets (dans notre cas : 16 octets)
int C[] = {1, 0, 0, 1, 1, 1, 0, 1, 0, 1};
==> Rservation de 10*sizeof(int) octets (dans notre cas : 20 octets)
Exemples

33

Cours du Langage C

Professeur : NAMEZ

1.3. Accs aux composantes


En dclarant un tableau par :

int A[5];
nous avons dfini un tableau A avec cinq composantes, auxquelles on peut accder par :

A[0], A[1], ... , A[4]


Exemple

Attention !
Considrons un tableau T de dimension N
- l'accs au premier lment du tableau se fait par T[0]
- l'accs au dernier lment du tableau se fait par T[N-1]

1.4. Affichage et affectation


La structure for se prte particulirement bien au travail avec les tableaux. La plupart des applications
se laissent implmenter par simple modification des exemples-types de l'affichage et de l'affectation.

main()
{
int A[10];
int I,N; /* Compteur et Nombre des elements du tableau */
printf(Donnez le nombre des elements du tableau : ) ;
scanf("%d ",&N);
/* Lecture */
for (I=0; I<N; I++)
{
printf(Donnez la composante %d : ,I+1);
scanf("%d", &A[I]);
}
/* Affichage */
for (I=0; I<N; I++)
printf("%d ", A[I]);
return 0;
}
Remarque
* Pour tre sr que les valeurs sont bien spares lors de l'affichage, il faut inclure au moins un
espace dans la chane de format. Autres possibilits:

printf("%d\t", A[I]); /* tabulateur */


printf("%7d", A[I]); /* format d'affichage */

34

Cours du Langage C

Professeur : NAMEZ

* Comme scanf a besoin des adresses des diffrentes composantes du tableau, il faut faire prcder
le terme A[I] par l'oprateur adresse '&'.
* La commande de lecture scanf doit tre informe du type exact des donnes lire. (Ici : %d ou %i
pour lire des valeurs du type int)

2. Les tableaux deux dimensions


Dfinitions
En C, un tableau deux dimensions A est interprter comme un tableau (uni-dimensionnel) de
dimension L dont chaque composante est un tableau (uni-dimensionnel) de dimension C.
On appelle L le nombre de lignes du tableau et C le nombre de colonnes du tableau. L et C sont
alors les deux dimensions du tableau. Un tableau deux dimensions contient donc L*C
composantes.

On dit qu'un tableau deux dimensions est carr, si L est gal C.

2.1. Dclaration et mmorisation


Dclarations

<TypeSimple> <NomTabl>[<DimLigne>][<DimCol>];
Exemples

int A[10][10];
ou bien long A[10][10];
ou bien ...
float B[2][20]; ou bien double B[2][20]; ou bien ...
int C[3][3];
char D[15][40];
Mmorisation
Comme pour les tableaux une dimension, le nom d'un tableau est le reprsentant de l'adresse du
premier lment du tableau (c.--d. l'adresse de la premire ligne du tableau). Les composantes
d'un tableau deux dimensions sont stockes ligne par ligne dans la mmoire.
Exemple

short A[3][2] = {{1,


2 },
{10, 20 },
{100, 200}};

35

Cours du Langage C

Professeur : NAMEZ

Un tableau de dimensions L et C, form de composantes dont chacune a besoin de M octets,


occupera L*C*M octets en mmoire.
Exemple
En supposant qu'une variable du type double occupe 8 octets (c.--d: sizeof(double)=8), pour
le tableau T dclar par :

double T[10][15];
C rservera L*C*M = 10*15*8 = 1200 octets en mmoire.

2.2. Accs aux composantes


Accs un tableau deux dimensions en C

<NomTableau>[<NLigne>][<NColonne>]
Les lments d'un tableau de dimensions L et C se prsentent de la faon suivante :

A[0][0]
A[1][0]
A[2][0]
. . .
A[L-1][0]

A[0][1]
A[1][1]
A[2][1]
. . .
A[L-1][1]

A[0][2]
.
A[1][2]
.
A[2][2]
.
. . .
. .
A[L-1][2]
.

.
.
.
.
.

.
.
.
.

A[0][C-1]
A[1][C-1]
A[2][C-1]
. . .
A[L-1][C-1]

2.4. Affichage et affectation


Lors du travail avec les tableaux deux dimensions, nous utiliserons deux indices (par exp : I et J), et
la structure for, souvent imbrique, pour parcourir les lignes et les colonnes des tableaux.

main()
{
int A[5][10];
int I,J;
/* Nombre de lignes et de colonnes du tableau*/
int L,C;
printf(Donnez le nombre de lignes du tableau : ) ;
scanf("%d ",&L);
printf(Donnez le nombre de colonnes du tableau : ) ;
scanf("%d ",&C);
/* Lecture */
/* Pour chaque ligne ... */
for (I=0; I<L; I++)
/* ... considrer chaque composante */
for (J=0; J<C; J++)
{
printf(Donnez lelement A[%d][%d]: ,I,J);

36

Cours du Langage C

Professeur : NAMEZ

scanf("%d", &A[I][J]);
}
/* Affichage */
/* Pour chaque ligne ... */
for (I=0; I<L; I++)
{
/* ... considrer chaque composante */
for (J=0; J<C; J++)
printf("%7d", A[I][J]);
/* Retour la ligne */
printf("\n");
}
return 0;
}
Remarques
* Pour obtenir des colonnes bien alignes lors de l'affichage, il est pratique d'indiquer la largeur
minimale de l'affichage dans la chane de format. Pour afficher des matrices du type int (valeur la plus
'longue': -32768), nous pouvons utiliser la chane de format "%7d" :

37

Cours du Langage C

Professeur : NAMEZ

Chapitre 6 :

LES CHANES DE CARACTRES


Il n'existe pas de type spcial chane ou string en C. Une chane de caractres est traite comme un
tableau une dimension de caractres. Il existe quand mme des notations particulires et une bonne
quantit de fonctions spciales pour le traitement de tableaux de caractres.

1. Dclaration et mmorisation
Dclaration

char <NomVariable> [<Longueur>];


Exemples

char NOM [20];


char PHRASE [300];
Espace rserver
Lors de la dclaration, nous devons indiquer l'espace rserver en mmoire pour le stockage de la
chane. La reprsentation interne d'une chane de caractres est termine par le symbole '\0' (NUL).
Ainsi, pour un texte de n caractres, nous devons prvoir n+1 octets.
Mmorisation
Le nom d'une chane est le reprsentant de l'adresse du premier caractre de la chane. Pour
mmoriser une variable qui doit tre capable de contenir un texte de N caractres, nous avons besoin
de N+1 octets en mmoire :
Exemple

char TXT[10] = "BONJOUR !";

2. Les chanes de caractres constantes


* Les chanes de caractres constantes sont indiques entre guillemets. La chane de caractres vide
est alors : ""
Observation
Pour la mmorisation de la chane de caractres "Hello", C a besoin de six (!!) octets.
'x'
"x"

est un caractre constant, qui a une valeur numrique : P.ex: 'x' a la valeur 120 dans le code
ASCII.
est un tableau de caractres qui contient deux caractres : la lettre 'x' et le caractre NUL: '\0'

38

Cours du Langage C

Professeur : NAMEZ

3. Initialisation de chanes de caractres


Pour le cas spcial des tableaux de caractres, nous pouvons utiliser une initialisation plus confortable
en indiquant simplement une chane de caractre constante :

char CHAINE[] = "Hello";


Lors de l'initialisation par [], l'ordinateur rserve automatiquement le nombre d'octets ncessaires
pour la chane, c.--d.: le nombre de caractres + 1 (ici: 6 octets). Nous pouvons aussi indiquer
explicitement le nombre d'octets rserver, si celui-ci est suprieur ou gal la longueur de la chane
d'initialisation.

4. Accs aux lments d'une chane


L'accs un lment d'une chane de caractres peut se faire de la mme faon que l'accs un
lment d'un tableau. En dclarant une chane par :

char A[6];
Nous avons dfini un tableau A avec six lments, auxquels on peut accder par :

A[0], A[1], ... , A[5]


Exemple

5. Prcdence alphabtique et lexicographique


Prcdence alphabtique des caractres
La prcdence des caractres dans l'alphabet d'une machine est dpendante du code de caractres
utilis. Pour le code ASCII, nous pouvons constater l'ordre suivant:
. . . ,0,1,2, ... ,9, . . . ,A,B,C, ... ,Z, . . . ,a,b,c, ... ,z, . . .
Les symboles spciaux (' ,+ ,- ,/ ,{ ,] , ...) et les lettres accentues ( , , , , ...) se trouvent rpartis
autour des trois grands groupes de caractres (chiffres, majuscules, minuscules). Leur prcdence ne
correspond aucune rgle d'ordre spcifique.
Prcdence lexicographique des chanes de caractres
En nous basant sur cette relation de prcdence alphabtique des caractres, nous pouvons dfinir
une prcdence lexicographique pour les chanes de caractres. Cette relation de prcdence suit
l'<<ordre du dictionnaire>> .
Exemples

"ABC" prcde "BCD"


"ABC" prcde "B"
"Abc" prcde "abc"

car 'A'<'B'
car 'A'<'B'
car 'A'<'a'

39

Cours du Langage C

"ab" prcde "abcd"

Professeur : NAMEZ

car "" prcde "cd"

6. Fonctions spciales des chanes de caractres


6.1. Les fonctions de <stdio.h>
- Affichage de chanes de caractres
printf avec le spcificateur de format %s permet d'intgrer une chane de caractres dans une
phrase.
Exemples

char NOM[] = "hello, world";


printf(":%s:", NOM);

->

:hello, world:

puts est idale pour crire une chane constante ou le contenu d'une variable dans une ligne isole.
Syntaxe :

puts( <Chane> )

Effet :

puts crit la chane de caractres dsigne par <Chane> sur stdout et provoque
un retour la ligne. En pratique,

puts(TXT); est quivalent printf("%s\n",TXT);


Exemples

char TEXTE[] = "Voici une premire ligne.";


puts(TEXTE);
puts("Voici une deuxime ligne.");
- Lecture de chanes de caractres
scanf avec le spcificateur %s permet de lire un mot isol l'intrieur d'une suite de donnes du
mme ou d'un autre type.
Effet :

scanf avec le spcificateur %s lit un mot du fichier d'entre standard stdin et le


mmorise l'adresse qui est associe %s.

Exemple

char LIEU[25];
int JOUR, MOIS, ANNEE;
printf("Entrez lieu et date de naissance : \n");
scanf("%s %d %d %d", LIEU, &JOUR, &MOIS, &ANNEE);
Remarques importantes
- La fonction scanf a besoin des adresses de ses arguments : Comme le nom d'une chane de
caractres est le reprsentant de l'adresse du premier caractre de la chane, il ne doit pas tre
prcd de l'oprateur adresse '&' !

40

Cours du Langage C

Professeur : NAMEZ

- La fonction scanf avec plusieurs arguments prsuppose que l'utilisateur connaisse exactement le
nombre et l'ordre des donnes introduire! Ainsi, l'utilisation de scanf pour la lecture de chanes de
caractres est seulement conseille si on est forc de lire un nombre fix de mots en une fois.
gets est idal pour lire une ou plusieurs lignes de texte (p.ex. des phrases) termines par un retour
la ligne.
Syntaxe :

gets( <Chane> )

Effet :

gets lit une ligne de de caractres de stdin et la copie l'adresse indique par
<Chane>. Le retour la ligne final est remplac par le symbole de fin de chane '\0'.

Exemple

int MAXI = 1000;


char LIGNE[MAXI];
gets(LIGNE);

6.2. Les fonctions de <string.h>


La bibliothque <string> fournit une multitude de fonctions pratiques pour le traitement de chanes de
caractres. Voici une brve description des fonctions les plus frquemment utilises.
Dans le tableau suivant, Les symboles <s> et <t> peuvent tre remplacs par :
* une chane de caractres constante
* le nom d'une variable dclare comme tableau de char
Fonctions pour le traitement de chanes de caractres
strlen(<s>)
strcpy(<s>, <t>)
strcat(<s>, <t>)
strcmp(<s>, <t>)

fournit la longueur de la chane sans compter le '\0' final


copie <t> vers <s>
ajoute <t> la fin de <s>
compare <s> et <t> lexicographiquement et fournit un rsultat :
ngatif
si <s> prcde <t>
zro
si <s> est gal <t>
positif
si <s> suit <t>

Remarques
- Comme le nom d'une chane de caractres reprsente une adresse fixe en mmoire, on ne peut pas
'affecter' une autre chane au nom d'un tableau:

Il faut bien copier la chane caractre par caractre ou utiliser la fonction strcpy :

strcpy(A, "Hello");
- La concatnation de chanes de caractres en C ne se fait pas par le symbole '+' comme en langage
algorithmique ou en Pascal. Il faut ou bien copier la deuxime chane caractre par caractre ou bien
utiliser la fonction strcat.

41

Cours du Langage C

Professeur : NAMEZ

- La fonction strcmp est dpendante du code de caractres et peut fournir diffrents rsultats sur
diffrentes machines.

7. Tableaux de chanes de caractres


7.1. Dclaration, initialisation et mmorisation
Un tableau de chanes de caractres correspond un tableau deux dimensions du type char, o
chaque ligne contient une chane de caractres.
Dclaration

char JOUR[7][9];
Initialisation
Lors de la dclaration il est possible d'initialiser toutes les composantes du tableau par des chanes de
caractres constantes :

char JOUR[7][9]= {"lundi", "mardi", "mercredi", "jeudi", "vendredi",


"samedi", "dimanche"};

Mmorisation
Les tableaux de chanes sont mmoriss ligne par ligne. La variable JOUR aura donc besoin de
7*9*1 = 63 octets en mmoire.

7.2. Accs aux diffrentes composantes


Accs aux chanes
Il est possible d'accder aux diffrentes chanes de caractres d'un tableau, en indiquant simplement
la ligne correspondante.
Exemple : L'excution des trois instructions suivantes :

char JOUR[7][9]= {"lundi", "mardi", "mercredi","jeudi", "vendredi",


"samedi", "dimanche"};
int I = 2;
printf("Aujourd'hui, c'est %s !\n", JOUR[I]);
Affichera la phrase :

Aujourd'hui, c'est mercredi !


Affectation

42

Cours du Langage C

Professeur : NAMEZ

Des expressions comme JOUR[I] reprsentent l'adresse du premier lment d'une chane de
caractres. N'essayez donc pas de 'modifier' une telle adresse par une affectation directe !

L'attribution d'une chane de caractres une composante d'un tableau de chanes se fait en gnral
l'aide de la fonction strcpy :
Exemple : La commande :

strcpy(JOUR[4], "Friday");
e

Changera le contenu de la 5 composante du tableau JOUR de "vendredi" en "Friday".


Accs aux caractres
Evidemment, il existe toujours la possibilit d'accder directement aux diffrents caractres qui
composent les mots du tableau.
Exemple
L'instruction :

for(I=0; I<7; I++)


printf("%c ", JOUR[I][0]);
Va afficher les premires lettres des jours de la semaine :

43

Cours du Langage C

Professeur : NAMEZ

Chapitre 8 :

LES POINTEURS
1. Adressage de variables
1.1. Adressage direct
Accs au contenu d'une variable par le nom de la variable.
Exemple

1.2. Adressage indirect


Accs au contenu d'une variable, en passant par un pointeur qui contient l'adresse de la variable.
Exemple
Soit A une variable contenant la valeur 10 et P un pointeur qui contient l'adresse de A. En mmoire, A
et P peuvent se prsenter comme suit :

2. Les pointeurs
Dfinition
Un pointeur est une variable spciale qui peut contenir l'adresse d'une autre variable.
En C, chaque pointeur est limit un type de donnes. Il peut contenir l'adresse d'une variable simple
de ce type ou l'adresse d'une composante d'un tableau de ce type.
Si un pointeur P contient l'adresse d'une variable A, on dit que 'P pointe sur A'.
Remarque
Les pointeurs et les noms de variables ont le mme rle : Ils donnent accs un emplacement dans
la mmoire interne de l'ordinateur. Il faut quand mme bien faire la diffrence :
* Un pointeur est une variable qui peut 'pointer' sur diffrentes adresses.
* Le nom d'une variable reste toujours li la mme adresse.

44

Cours du Langage C

Professeur : NAMEZ

2.1. Les oprateurs de base


Lors du travail avec des pointeurs, nous avons besoin
- d'un oprateur 'adresse de' : & pour obtenir l'adresse d'une variable.
- d'un oprateur 'contenu de' : * pour accder au contenu d'une adresse.
- d'une syntaxe de dclaration pour pouvoir dclarer un pointeur.

L'oprateur 'adresse de' : &

&<NomVariable>
fournit l'adresse de la variable <NomVariable>
Attention !
L'oprateur & peut seulement tre appliqu des objets qui se trouvent dans la mmoire interne, cd.
des variables et des tableaux. Il ne peut pas tre appliqu des constantes ou des expressions.
Reprsentation schmatique
Soit P un pointeur non initialis

Et A une variable (du mme type) contenant la valeur 10 :

Alors l'instruction

P = &A;
Affecte l'adresse de la variable A la variable P. En mmoire, A et P se prsentent comme dans le
graphique la fin du paragraphe 1.2. Dans notre reprsentation schmatique, nous pouvons illustrer
le fait que 'P pointe sur A' par une flche :

L'oprateur 'contenu de' : *

*<NomPointeur>
dsigne le contenu
<NomPointeur>

de

l'adresse

Exemple

45

rfrence

par

le

pointeur

Cours du Langage C

Professeur : NAMEZ

Soit A une variable contenant la valeur 10, B une variable contenant la valeur 50 et P un pointeur non
initialis :

Aprs les instructions,

P = &A;
B = *P;
*P = 20;
- P pointe sur A,
- le contenu de A (rfrenc par *P) est affect B,
- le contenu de A (rfrenc par *P) est mis 20.

Dclaration d'un pointeur

<Type> *<NomPointeur>
dclare un pointeur <NomPointeur> qui peut recevoir des adresses de
variables du type <Type>
Une dclaration comme :

int *PNUM;
Peut tre interprte comme suit :
-

"*PNUM est du type int"


"PNUM est un pointeur sur int"
"PNUM peut contenir l'adresse d'une variable du type int"

2.2. Les oprations lmentaires sur pointeurs


Aprs l'instruction

P = &X;
les expressions suivantes, sont quivalentes :

46

Cours du Langage C

*P = *P+10
*P += 2
(*P)++

Professeur : NAMEZ

X = X+10
X += 2
X++

Le pointeur NUL
Seule exception : La valeur numrique 0 (zro) est utilise pour indiquer qu'un pointeur ne pointe
'nulle part'.

int *P;
P = 0;
- Finalement, les pointeurs sont aussi des variables et peuvent tre utiliss comme telles. Soit P1 et
P2 deux pointeurs sur int, alors l'affectation :

P1 = P2;
Copie le contenu de P2 vers P1. P1 pointe alors sur le mme objet que P2.
Rsumons

Aprs les instructions :

int A;
int *P;
P = &A;
A
&A

dsigne le contenu de A
dsigne l'adresse de A

P
*P

dsigne l'adresse de A
dsigne le contenu de A

3. Pointeurs et tableaux
En C, il existe une relation trs troite entre tableaux et pointeurs. Ainsi, chaque opration avec des
indices de tableaux peut aussi tre exprime l'aide de pointeurs.

3.1. Adressage des composantes d'un tableau


&tableau[0] et tableau sont une seule et mme adresse.

47

Cours du Langage C

Professeur : NAMEZ

En simplifiant, nous pouvons retenir que le nom d'un tableau est un pointeur constant sur le premier
lment du tableau.
Exemple
En dclarant un tableau A de type int et un pointeur P sur int,

int A[10];
int *P;
Linstruction : P = A;

est quivalente P = &A[0];

Ainsi, aprs l'instruction :

P = A;
Le pointeur P pointe sur A[0], et

*(P+1)
*(P+2)
...
*(P+i)

dsigne le contenu de A[1]


dsigne le contenu de A[2]

...
dsigne le contenu de A[i]

Comme A reprsente l'adresse de A[0],

*(A+1)
*(A+2)

dsigne le contenu de A[1]


dsigne le contenu de A[2]

...

*(A+i)

dsigne le contenu de A[i]

Attention !
- Un pointeur est une variable, donc des oprations comme P = A ou P++ sont permises.
- Le nom d'un tableau est une constante, donc des oprations comme A = P ou A++ sont
impossibles.
Rsumons
Soit un tableau A d'un type quelconque et i un indice pour les composantes de A, alors :

A
A[0]
dsigne l'adresse de
A+i
A[i]
dsigne l'adresse de
*(A+i) dsigne le contenu de A[i]
Si P = A, alors :

pointe sur l'lment

A[0]

48

Cours du Langage C

Professeur : NAMEZ

P+i
A[i]
pointe sur l'lment
*(P+i) dsigne le contenu de A[i]
Formalisme tableau et formalisme pointeur
Les deux programmes suivants copient les lments positifs d'un tableau T dans un deuxime tableau
POS.
Formalisme tableau

main()
{
int T[10] = {-3, 4, 0, -7, 3, 8, 0, -1, 4, -9};
int POS[10];
int I,J; /* indices courants dans T et POS */
for (J=0,I=0 ; I<10 ; I++)
if (T[I]>0)
{
POS[J] = T[I];
J++;
}
return 0;
}
Nous pouvons remplacer systmatiquement la notation tableau[I] par *(tableau + I), ce
qui conduit ce programme:
Formalisme pointeur

main()
{
int T[10] = {-3, 4, 0, -7, 3, 8, 0, -1, 4, -9};
int POS[10];
int I,J; /* indices courants dans T et POS */
for (J=0,I=0 ; I<10 ; I++)
if (*(T+I)>0)
{
*(POS+J) = *(T+I);
J++;
}
return 0;
}
Les variables et leur utilisation

Int A;

dclare une variable simple du type int

A
&A

dsigne le contenu de A
dsigne l'adresse de A

Int B[10]; dclare un tableau d'lments du type int


B

dsigne l'adresse de la premire composante de B


(Cette adresse est toujours constante)

49

Cours du Langage C

B[i]
&B[i]

Professeur : NAMEZ

dsigne le contenu de la composante i du tableau


dsigne l'adresse de la composante i du tableau

En utilisant le formalisme pointeur :

B+i
dsigne l'adresse de la composante i du tableau
*(B+i) dsigne le contenu de la composante i du tableau
Int *P; dclare un pointeur sur des lments du type int
P

peut pointer

P
*P

sur des variables simples du type int ou


sur les composantes d'un tableau du type int.
dsigne l'adresse contenue dans P (Cette adresse est variable)
dsigne le contenu de l'adresse dans P

Si P pointe dans un tableau, alors :

P
P+i
*(P+i)

dsigne l'adresse de la premire composante


dsigne l'adresse de la i-ime composante derrire P
dsigne le contenu de la i-ime composante derrire P

3.2. Arithmtique des pointeurs


Toutes les oprations avec les pointeurs tiennent compte automatiquement du type et de la
grandeur des objets points.
- Affectation par un pointeur sur le mme type
Soient P1 et P2 deux pointeurs sur le mme type de donnes, alors l'instruction :

P1 = P2;
Fait pointer P1 sur le mme objet que P2.
- Soustraction de deux pointeurs
Soient P1 et P2 deux pointeurs qui pointent dans le mme tableau :

P1-P2

fournit le nombre de composantes comprises entre P1 et P2.

Le rsultat de la soustraction P1-P2 est :


- ngatif,
- zro,
- positif,
- indfini,

si P1 prcde P2
si P1 = P2
si P2 precde P1
si P1 et P2 ne pointent pas dans le mme tableau

Plus gnralement, la soustraction de deux pointeurs qui pointent dans le mme tableau est
quivalente la soustraction des indices correspondants.
- Comparaison de deux pointeurs
On peut comparer deux pointeurs par <, >, <=, >=, ==, !=.

50

Cours du Langage C

Professeur : NAMEZ

La comparaison de deux pointeurs qui pointent dans le mme tableau est quivalente la
comparaison des indices correspondants. (Si les pointeurs ne pointent pas dans le mme tableau,
alors le rsultat est donn par leurs positions relatives dans la mmoire).

3.3. Pointeurs et chanes de caractres


- Pointeurs sur char et chanes de caractres constantes
a) Affectation
On peut attribuer l'adresse d'une chane de caractres constante un pointeur sur char.
Exemple

char *C;
C = "Ceci est une chane de caractres constante";

b) Initialisation
Un pointeur sur char peut tre initialis lors de la dclaration si on lui affecte l'adresse d'une chane de
caractres constante :

char *B = "Bonjour !";


c) Modification
Si nous affectons une nouvelle valeur un pointeur sur une chane de caractres constante, nous
risquons de perdre la chane constante. D'autre part, un pointeur sur char a l'avantage de pouvoir
pointer sur des chanes de n'importe quelle longueur.
Exemple

char *A = "Petite chane";


char *B = "Deuxime chane un peu plus longue";
A = B;
Maintenant A et B pointent sur la mme chane ; la "Petite chane" est perdue.

51

Cours du Langage C

Professeur : NAMEZ

Chapitre 9 :

LES FONCTIONS
1. Modularisation de programmes
La plupart des langages de programmation nous permettent de subdiviser nos programmes en sousprogrammes, fonctions ou procdures plus simples et plus compacts. A l'aide de ces structures nous
pouvons modulariser nos programmes pour obtenir des solutions plus lgantes et plus efficientes.
Dans ce contexte, un module dsigne une entit de donnes et d'instructions qui fournissent une
solution une (petite) partie bien dfinie d'un problme plus complexe. Un module peut faire appel
d'autres modules, leur transmettre des donnes et recevoir des donnes en retour. L'ensemble des
modules ainsi relis doit alors tre capable de rsoudre le problme global.
Voici quelques avantages d'un programme modulaire :
* Meilleure lisibilit
* Diminution du risque d'erreurs
* Possibilit de tests slectifs
* Dissimulation des mthodes
* Rutilisation de modules dj existants
* Favorisation du travail en quipe
* Hirarchisation des modules

2. La notion de blocs et la porte des identificateurs


Blocs d'instructions en C

{
<dclarations locales>
<instructions>
}

2.1. Variables locales


Les variables dclares dans un bloc d'instructions sont uniquement visibles l'intrieur de ce bloc.
On dit que ce sont des variables locales ce bloc.
Exemple
La variable NOM est dfinie localement dans le bloc extrieur de la fonction HELLO. Ainsi, aucune
autre fonction n'a accs la variable NOM :

void HELLO(void);
{
char NOM[20];
printf("Introduisez votre nom : ");
gets(NOM);
printf("Bonjour %s !\n", NOM);
}

52

Cours du Langage C

Professeur : NAMEZ

2.2. Variables globales


Les variables dclares au dbut du fichier, l'extrieur de toutes les fonctions sont disponibles
toutes les fonctions du programme. Ce sont alors des variables globales. En gnral, les variables
globales sont dclares immdiatement derrire les instructions #include au dbut du programme.
Attention !
Les variables dclares au dbut de la fonction principale main ne sont pas des variables globales,
mais elles sont locales main !
Conseils
* Les variables globales sont utiliser avec prcaution, puisqu'elles crent des liens invisibles entre
les fonctions. La modularit d'un programme peut en souffrir et le programmeur risque de perdre la
vue d'ensemble.

3. Dclaration et dfinition de fonctions


En gnral, le nom d'une fonction apparat trois endroits dans un programme :
1) lors de la dclaration
2) lors de la dfinition
3) lors de l'appel
Exemple
Avant de parler des dtails, penchons-nous sur un exemple. Dans le programme suivant, la fonction
main utilise les deux fonctions :
- ENTREE qui lit un nombre entier au clavier et le fournit comme rsultat. La fonction ENTREE n'a pas
de paramtres.
- MAX qui renvoie comme rsultat le maximum de deux entiers fournis comme paramtres.

#include <stdio.h>
main()
{
/* Prototypes des fonctions appeles */
int ENTREE(void);
int MAX(int N1, int N2);
/* Dclaration des variables */
int A, B;
/* Traitement avec appel des fonctions */
A = ENTREE();
B = ENTREE();
printf("Le maximum est %d\n", MAX(A,B));
}
/* Dfinition de la fonction ENTREE */
int ENTREE(void)
{

53

Cours du Langage C

Professeur : NAMEZ

int NOMBRE;
printf("Entrez un nombre entier : ");
scanf("%d", &NOMBRE);
return NOMBRE;
}
/* Dfinition de la fonction MAX */
int MAX(int N1, int N2)
{
if (N1>N2)
return N1;
else
return N2;
}

3.1. Dfinition d'une fonction


Dans la dfinition d'une fonction, nous indiquons :
- le nom de la fonction
- le type, le nombre et les noms des paramtres de la fonction
- le type du rsultat fourni par la fonction
- les donnes locales la fonction
- les instructions excuter
Dfinition d'une fonction en C

<TypeRs> <NomFonct> (<TypePar1> <NomPar1>,


<TypePar2> <NomPar2>, ... )
{
<dclarations locales>
<instructions>
}
Remarquez qu'il n'y a pas de point-virgule derrire la dfinition des paramtres de la fonction.
Exemples
- La fonction MAX est du type int et elle a besoin de deux paramtres du type int. Le rsultat de la
fonction MAX peut tre intgr dans d'autres expressions.

int MAX(int N1, int N2)


{
if (N1>N2)
return N1;
else
return N2;
}
- La fonction PI fournit un rsultat rationnel du type float. La liste des paramtres de PI est dclare
comme void (vide), c.--d. PI n'a pas besoin de paramtres et il faut l'appeler par : PI()

float PI(void)

54

Cours du Langage C

Professeur : NAMEZ

{
return 3.1415927;
}
Remarques

Une fonction peut fournir comme rsultat :

un type arithmtique,
une structure (dfinie par struct ),
un pointeur,
void (la fonction correspond alors une 'procdure').

Une fonction ne peut pas fournir comme rsultat des tableaux, des chanes de caractres ou des
fonctions. (Attention : Il est cependant possible de renvoyer un pointeur sur le premier lment
d'un tableau ou d'une chane de caractres).

Si une fonction n'a pas de paramtres, on peut dclarer la liste des paramtres comme (void) ou
simplement comme ().
Le type par dfaut est int ; autrement dit : si le type d'une fonction n'est pas dclar explicitement,
elle est automatiquement du type int.
Il est interdit de dfinir des fonctions l'intrieur d'une autre fonction (comme en Pascal).
En principe, l'ordre des dfinitions dans le texte du programme ne joue pas de rle, mais chaque
fonction doit tre dclare ou dfinie avant d'tre appele.

Rappel : main
La fonction principale main est du type int. Elle est excute automatiquement lors de l'appel du
programme. A la place de la dfinition :

int main(void)
On peut crire simplement :

main()

3.2. Dclaration d'une fonction


En C, il faut dclarer chaque fonction avant de pouvoir l'utiliser. La dclaration informe le compilateur
du type des paramtres et du rsultat de la fonction. Si dans le texte du programme la fonction est
dfinie avant son premier appel, elle n'a pas besoin d'tre dclare.
Prototype d'une fonction
La dclaration d'une fonction se fait par un prototype de la fonction qui indique uniquement le type
des donnes transmises et reues par la fonction.
Dclaration

<TypeRs> <NomFonct> (<TypePar1>, <TypePar2>, ...);


Ou bien

<TypeRs> <NomFonct> (<TypePar1> <NomPar1>,


<TypePar2> <NomPar2>, ... );

55

Cours du Langage C

Professeur : NAMEZ

Rgles pour la dclaration des fonctions


De faon analogue aux dclarations de variables, nous pouvons dclarer une fonction localement ou
globalement. La dfinition des fonctions joue un rle spcial pour la dclaration. En rsum, nous
allons considrer les rgles suivantes :
Dclaration locale : Une fonction peut tre dclare localement dans la fonction qui l'appelle (avant
la dclaration des variables). Elle est alors disponible cette fonction.
Dclaration globale : Une fonction peut tre dclare globalement au dbut du programme (derrire
les instructions #include). Elle est alors disponible toutes les fonctions du programme.
Dclaration implicite par la dfinition : La fonction est automatiquement disponible toutes les
fonctions qui suivent sa dfinition.
main : La fonction principale main n'a pas besoin d'tre dclare.

4. Renvoyer un rsultat
Par dfinition, toutes les fonctions fournissent un rsultat d'un type que nous devons dclarer. Une
fonction peut renvoyer une valeur d'un type simple ou l'adresse d'une variable ou d'un tableau. Pour
fournir un rsultat en quittant une fonction, nous disposons de la commande return :

return <expression>;
Exemples
La fonction CARRE du type double calcule et fournit comme rsultat le carr d'un rel fourni comme
paramtre.

double CARRE(double X)
{
return X*X;
}
Nous pouvons dfinir nous-mmes une fonction TAN qui calcule la tangente d'un rel X l'aide des
fonctions sin et de cos de la bibliothque <math>.

#include <math.h>
double TAN(double X)
{
if (cos(X) != 0)
return sin(X)/cos(X);
else
printf("Erreur !\n");
}
Si nous supposons les dclarations suivantes

double X, COT;
Les appels des fonctions CARRE et TAN peuvent tre intgrs dans des calculs ou des expressions :

printf("Le carre de %f est %f \n", X, CARRE(X));


printf("La tangente de %f est %f \n", X, TAN(X));
COT = 1/TAN(X);

56

Cours du Langage C

Professeur : NAMEZ

Void
En C, il n'existe pas de structure spciale pour la dfinition de procdures comme en Pascal et en
langage algorithmique. Nous pouvons cependant employer une fonction du type void partout o nous
utiliserions une procdure en langage algorithmique ou en Pascal.
Exemple
La fonction du type void LIGNE affiche L toiles dans une ligne :

void LIGNE(int L)
{
/* Dclarations des variables locales */
int I;
/* Traitements */
for (I=0; I<L; I++)
printf("*");
printf("\n");
}
main
Dans nos exemples, la fonction main n'a pas de paramtres et est toujours du type int.
Typiquement, les programmes renvoient la valeur zro comme code d'erreur s'ils se terminent avec
succs. Des valeurs diffrentes de zro indiquent un arrt fautif ou anormal.

5. Paramtres d'une fonction


Les paramtres d'une fonction sont simplement des variables locales qui sont initialises par les
valeurs obtenues lors de l'appel.

5.1. Passage des paramtres par valeur


En C, le passage des paramtres se fait toujours par la valeur, c.--d. les fonctions n'obtiennent que
les valeurs de leurs paramtres et n'ont pas d'accs aux variables elles-mmes.
Les paramtres d'une fonction sont considrer comme des variables locales qui sont initialises
automatiquement par les valeurs indiques lors d'un appel.
A l'intrieur de la fonction, nous pouvons donc changer les valeurs des paramtres sans influencer les
valeurs originales dans les fonctions appelantes.
Exemple
La fonction ETOILES dessine une ligne de N toiles. Le paramtre N est modifi l'intrieur de la
fonction:

void ETOILES(int N)
{
while (N>0)
{
printf("*");
N--;
}

57

Cours du Langage C

Professeur : NAMEZ

printf("\n");
}
En utilisant N comme compteur, nous n'avons pas besoin de l'indice d'aide I comme dans la fonction
LIGNES dfinie plus haut.
La fonction TRIANGLE, appelle la fonction ETOILES en utilisant la variable L comme paramtre :

void TRIANGLE(void)
{
int L;
for (L=1; L<10; L++)
ETOILES(L);
}
Au moment de l'appel, la valeur de L est copie dans N. La variable N peut donc tre dcrmente
l'intrieur de ETOILES, sans influencer la valeur originale de L.
Schmatiquement, le passage des paramtres peut tre reprsent dans une 'grille' des valeurs :

Avantages
Le passage par valeur a l'avantage que nous pouvons utiliser les paramtres comme des variables
locales bien initialises. De cette faon, nous avons besoin de moins de variables d'aide.

5.2. Passage de l'adresse d'une variable


Comme nous l'avons constat ci-dessus, une fonction n'obtient que les valeurs de ses paramtres.
Pour changer la valeur d'une variable de la fonction appelante, nous allons procder comme suit :
- la fonction appelante doit fournir l'adresse de la variable et
- la fonction appele doit dclarer le paramtre comme pointeur.
On peut alors atteindre la variable l'aide du pointeur.

58

Cours du Langage C

Professeur : NAMEZ

Discussion d'un exemple


Nous voulons crire une fonction PERMUTER qui change le contenu de deux variables du type int.
En premire approche, nous crivons la fonction suivante :

void PERMUTER (int A, int B)


{
int AIDE;
AIDE = A;
A = B;
B = AIDE;
}
Nous appelons la fonction pour deux variables X et Y par :

PERMUTER(X, Y);
Rsultat : X et Y restent inchangs !
Lors de l'appel, les valeurs de X et de Y sont copies dans les paramtres A et B. PERMUTER
change bien contenu des variables locales A et B, mais les valeurs de X et Y restent les mmes.

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


Y. En utilisant des pointeurs, nous crivons une deuxime fonction :

void PERMUTER (int *A, int *B)


{
int AIDE;
AIDE = *A;
*A = *B;
*B = AIDE;
}
Nous appelons la fonction par :

PERMUTER(&X, &Y);
Rsultat : Le contenu des variables X et Y est chang !
Lors de l'appel, les adresses de X et de Y sont copies dans les pointeurs A et B. PERMUTER
change ensuite le contenu des adresses indiques par les pointeurs A et B.

59

Cours du Langage C

Professeur : NAMEZ

5.3. Passage de l'adresse d'un tableau une dimension


Mthode
Comme il est impossible de passer 'la valeur' de tout un tableau une fonction, on fournit l'adresse
d'un lment du tableau.
En gnral, on fournit l'adresse du premier lment du tableau, qui est donne par le nom du
tableau.
Dclaration
Dans la liste des paramtres d'une fonction, on peut dclarer un tableau par le nom suivi de crochets :

<type> <nom>[]
ou simplement par un pointeur sur le type des lments du tableau :

<type> *<nom>
Exemple
La fonction strlen calcule et retourne la longueur d'une chane de caractres fournie comme
paramtre :

int strlen(char *S)


{
int N;
for (N=0; *S != '\0'; S++)
N++;
return N;
}
A la place de la dclaration de la chane comme :

char *S
On aurait aussi pu indiquer :

char S[]
Appel
Lors d'un appel, l'adresse d'un tableau peut tre donne par le nom du tableau, par un pointeur ou par
l'adresse d'un lment quelconque du tableau.
Exemple
Aprs les instructions :

char CH[] = "Bonjour !";


char *P;
P = CH;

60

Cours du Langage C

Professeur : NAMEZ

nous pouvons appeler la fonction strlen dfinie ci-dessus par :

strlen(CH) /* rsultat: 9 */
strlen(P) /* rsultat: 9 */
Remarque pratique
Pour qu'une fonction puisse travailler correctement avec un tableau qui n'est pas du type char, il faut
aussi fournir la dimension du tableau ou le nombre d'lments traiter comme paramtre, sinon la
fonction risque de sortir du domaine du tableau.
Exemple
La fonction LIRETAB lit N donnes pour un tableau (unidimensionnel) du type int et les mmorise
partir de l'adresse indique par le pointeur PTAB. PTAB et N sont fournis comme paramtres.

void LIRE_TAB(int N, int *PTAB)


{
printf("Entrez %d valeurs : \n", N);
while(N)
{
scanf("%d", PTAB++);
N-}
}
Dans l'appel de la fonction nous utilisons en gnral le nom du tableau :

LIRE_TAB(4,T);
Nous obtenons alors les grilles suivantes :

61