Vous êtes sur la page 1sur 138

Le Langage C

Licence Professionnelle
Qualit Logiciel

Pr. Mouad BEN MAMOUN


ben_mamoun@fsr.ac.ma

Anne universitaire 2011/2012

2011/2012 Pr. Ben Mamoun 1


Plan du cours (1)

1. Introduction

2. Types, oprateurs et expressions

3. Les entres-sorties (printf, scanf, )

4. Les structures de contrle

5. Les tableaux
2011/2012 Pr. Ben Mamoun 2
Plan du cours (2)

6. Les pointeurs

7. Les fonctions

8. Les chanes de caractres

9. Les structures

2011/2012 Pr. Ben Mamoun 3


Langages informatiques
Un langage informatique est un outil permettant de
donner des ordres (instructions) la machine

A chaque instruction correspond une action du processeur

Intrt : crire des programmes (suite conscutive


dinstructions) dstins effectuer une tache donne

Exemple: un programme de gestion de comptes bancaires

Contrainte: tre comprhensible par la machine

2011/2012 Pr. Ben Mamoun 4


Langage machine
Langage binaire: linformation est exprime et manipule sous
forme dune suite de bits

Un bit (binary digit) = 0 ou 1 (2 tats lectriques)

Une combinaison de 8 bits= 1 Octet 28 256 possibilits qui permettent


de coder tous les caractres alphabtiques, numriques, et symboles tels que ?,*,&,

Le code ASCII (American Standard Code for Information Interchange) donne les
correspondances entre les caractres alphanumriques et leurs
reprsentation binaire, Ex. A= 01000001, ?=00111111

Les oprations logiques et arithmtiques de base (addition,


multiplication, ) sont effectues en binaire

2011/2012 Pr. Ben Mamoun 5


L'assembleur
Problme: le langage machine est difficile comprendre par l'humain

Ide: trouver un langage comprhensible par l'homme qui sera


ensuite converti en langage machine
Assembleur : exprimer les instructions lmentaires de faon
symbolique
ADD A, 4
traducteur langage machine
LOAD B
MOV A, OUT

+: dj plus accessible que le langage machine
-: dpend du type de la machine (nest pas portable
portable)
-: pas assez efficace pour dvelopper des applications complexes

Apparition des langages volus


2011/2012 Pr. Ben Mamoun 6
Langages haut niveau
Intrts multiples pour le haut niveau:
proche du langage humain anglais (comprhensible)
permet une plus grande portabilit (indpendant du matriel)
Manipulation de donnes et dexpressions complexes (rels,
objets, a*b/c, )
Ncessit dun traducteur (compilateur/interprteur),
excution plus ou moins lente selon le traducteur

Code source Compilateur ou


Langage machine
en langage volu interprteur

2011/2012 Pr. Ben Mamoun 7


Compilateur/interprteur
Compilateur: traduire le programme entier une fois pour toutes
Compilateur excution
exemple.c exemple
fichier source fichier excutable
+ plus rapide lexcution
+ scurit du code source
- il faut recompiler chaque modification

Interprteur: traduire au fur et mesure les instructions du


programme chaque excution
Interprtation+excution
exemple.bas
fichier source
+ excution instantane apprciable pour les dbutants
- excution lente par rapport la compilation
2011/2012 Pr. Ben Mamoun 8
Langages de programmation:

Deux types de langages:


Langages procduraux
Langages orients objets

Exemples de langages:
Fortran, Cobol, Pascal, C,
C++, Java,

2011/2012 Pr. Ben Mamoun 9


Historique du C
Le langage C a t conu en 1972 dans Bell Laboratories par
Dennis Ritchie avec lobjectif dcrire un systme d'exploitation
(UNIX).

En 1978, une premire dfinition rigoureuse du langage C (standard


K&R-C) a t ralise par Kernighan et Ritchie en publiant le livre
The C Programming Language .

Le succs du C et lapparition de compilateurs avec des extensions


particulires ont conduit sa normalisation.

En 1983, lorganisme ANSI (American National Standards Institute)


chargeait une commission de mettre au point une dfinition explicite
et portable pour le langage C. Le rsultat est le standard ANSI-C.

2011/2012 Pr. Ben Mamoun 10


Caractristiques du C
Universel : n'est pas orient vers un domaine d'application particulier
(applications scientifiques, de gestion, )

Prs de la machine : offre des oprateurs qui sont proches de ceux du


langage machine (manipulations de bits, dadresses, ) efficace

Modulaire: peut tre dcoup en modules qui peuvent tre compils


sparment

Portable: en respectant le standard ANSI-C, il est possible d'utiliser le


mme programme sur plusieurs systmes (hardware, systme
d'exploitation )

Remarque : Une programmation efficace et comprhensible en C n'est pas


facilement accessible des dbutants

2011/2012 Pr. Ben Mamoun 11


Programme source, objet et excutable
Un programme crit en langage C forme un texte quon nomme
programme ou code source,
source, qui peut tre form de plusieurs fichiers
sources

Chaque fichier source est traduit par le compilateur pour obtenir un


fichier ou module objet (form dinstructions machine)

Ce fichier objet nest pas excutable tel quel car il lui manque les
instructions excutables des fonctions standards appeles dans le fichier
source (printf, scanf, ) et ventuellement dautres fichiers objets

Lditeur de liens runit les diffrents modules objets et les fonctions de


la bibliothque standard afin de former un programme excutable

Remarque : la compilation est prcde par une phase de prtraitement


(inclusion de fichiers en-tte) ralis par le prprocesseur
2011/2012 Pr. Ben Mamoun 12
Compilateurs C
Pour pouvoir crire des programmes en C, vous avez
besoin dun compilateur C sur votre machine

Il existe plusieurs compilateurs respectant le standard


ANSI-C. Une bonne liste est disponible sur :
c.developpez.com/compilateurs/

Nous allons utiliser l'environnement de dveloppement


Dev-C++ avec le systme dexploitation Windows

Vous pouvez tlcharger Dev-C++ librement, par exemple


sur le site www.bloodshed.net

2011/2012 Pr. Ben Mamoun 13


Exemple dune fentre Dev-C++

2011/2012 Pr. Ben Mamoun 14


Composantes dun programme C
Directives du prprocesseur
inclusion des fichiers d'en-tte (fichiers avec extension .h)
dfinitions des constantes avec #define

dclaration des variables globales


dfinition des fonctions (En C, le programme principal et les sous-
programmes sont dfinis comme fonctions )

Les commentaires : texte ignor par le compilateur, destin


amliorer la comprhension du code
exemple : #include<stdio.h>
main()
{
printf( "notre premier programme C \n");
/*ceci est un commentaire*/
}

2011/2012 Pr. Ben Mamoun 15


Remarques sur ce premier programme
#include<stdio.h> informe le compilateur dinclure le fichier stdio.h qui
contient les fonctions dentres-sorties dont la fonction printf

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.

Lappel de printf avec largument "notre premier programme C\n" permet


dafficher : notre premier programme C et \n ordonne le passage la
ligne suivante

En C, toute instruction simple est termine par un point-virgule ;

Un commentaire en C est compris entre // et la fin de la ligne ou bien


entre /* et */

2011/2012 Pr. Ben Mamoun 16


Chapitre 2

Variables, types, oprateurs et


expressions
Les variables
Les variables servent stocker les valeurs des donnes
utilises pendant lexcution dun programme

Les variables doivent tre dclares avant dtre


utilises, elles doivent tre caractrises par :

un nom (Identificateur
Identificateur)
un type (entier, rel, )
(Les types de variables en C seront discuts par la suite)

2011/2012 Pr. Ben Mamoun 18


Les identificateurs
Le choix dun identificateur (nom dune variable ou dune fonction) est
soumis quelques rgles :

doit tre constitu uniquement de lettres, de chiffres et du caractre


soulign _ (Eviter les caractres de ponctuation et les espaces)
correct: PRIX_HT, prixHT incorrect: PRIX-
PRIX-HT, prix HT, prix.HT

doit commencer par une lettre (y compris le caractre soulign)


correct : A1, _A1 incorrect: 1A

doit tre diffrent des mots rservs du langage : auto break case char
const continue default do double else enum extern float for
goto if int long register return short signed sizeof static
struct switch typedef union unsigned void volatile while

Remarque : C distingue les majuscules et les minuscules. NOMBRE et nombre


sont des identificateurs diffrents

2011/2012 Pr. Ben Mamoun 19


Les types de base
Le type dune variable dtermine lensemble des valeurs quelle peut prendre
et le nombre d'octets lui rserver en mmoire

En langage C, il ny a que deux types de base les entiers et les rels avec
diffrentes variantes pour chaque type
Remarques:
Un type de base est un type pour lequel une variable peut prendre une seule
valeur un instant donn contrairement aux types agrgs

Le type caractre apparat en C comme cas particulier du type entier (un


caractre est un nombre entier, il sidentifie son code ASCII)

En C il n'existe pas de type spcial pour chanes de caractres. Les moyens


de traiter les chanes de caractres seront prsents aux chapitres suivants

Le type boolen nexiste pas. Un boolen est reprsent par un entier (un
entier non nul quivaut vrai et la valeur zero quivaut faux)

2011/2012 Pr. Ben Mamoun 20


Types Entier
4 variantes dentiers :
char : caractres (entier sur 1 octet : - 128 127)
short ou short int : entier court (entier sur 2 octets : - 32768 32767)
int : entier standard (entier sur 2 ou 4 octets )
long ou long int : entier long (4 octets : - 2147483648 2147483648)

Si on ajoute le prfixe unsigned la dfinition d'un type de variables


entires, alors la plage des valeurs change:
unsigned char : 0 255
unsigned short : 0 65535
unsigned int : dpend du codage (sur 2 ou 4 octets)
unsigned long : 0 4294967295

Remarque : Une variable du type char peut subir les mmes oprations que les
variables du type short, int ou long

2011/2012 Pr. Ben Mamoun 21


Types Rel
3 variantes de rels :

float : rel simple prcision cod sur 4 octets de


-3.4*1038 3.4*1038
double : rel double prcision cod sur 8 octets de
-1.7*10308 1.7*10308
long double : rel trs grande prcision cod sur 10
octets de -3.4*104932 3.4*104932

2011/2012 Pr. Ben Mamoun 22


Dclaration des variables
Les dclarations introduisent les variables qui seront utilises,
fixent leur type et parfois aussi leur valeur de dpart (initialisation)

Syntaxe de dclaration en C

<Type> <NomVar1>,<NomVar2>,...,<NomVarN>;
Exemple:
int i, j,k;
float x, y ;
double z=1.5; // dclaration et initialisation
short compteur;
char c=`A`;

2011/2012 Pr. Ben Mamoun 23


Dclaration des constantes
Une constante conserve sa valeur pendant toute lexcution dun programme

En C, on associe une valeur une constante en utilisant :


la directive #define :
#define nom_constante valeur
Ici la constante ne possde pas de type.
exemple: #define Pi 3.141592

le mot cl const :
const type nom = expression ;
Dans cette instruction la constante est type
exemple : const float Pi =3.141592

(Rq: Lintrt des constantes est de donner un nom parlant une valeur, par exemple
NB_LIGNES, aussi a facilite la modification du code)

2011/2012 Pr. Ben Mamoun 24


Constantes entires
On distingue 3 formes de constantes entires :

forme dcimale : cest lcriture usuelle. Ex : 372, 200

forme octale (base 8) : on commence par un 0 suivi de chiffres


octaux. Ex : 0477

forme hexadcimale (base 16) : on commence par 0x (ou 0X) suivis


de chiffres hexadcimaux (0-9 a-f). Ex : 0x5a2b, 0Xa9f

2011/2012 Pr. Ben Mamoun 25


Remarques sur les constantes entires
Le compilateur attribue automatiquement un type aux constantes
entires. Il attribue en gnral le type le plus conomique parmi (int,
unsigned int, long int, unsigned long int)

On peut forcer la machine utiliser un type de notre choix en


ajoutant les suffixes suivants:

u ou U pour unsigned int, Ex : 100U, 0xAu


l ou L pour long, Ex : 15l, 0127L
ul ou UL pour unsigned long, Ex : 1236UL, 035ul

2011/2012 Pr. Ben Mamoun 26


Constantes relles
On distingue 2 notations :
notation dcimale Ex : 123.4, .27, 5.

notation exponentielle Ex : 1234e-1 ou 1234E-1

Remarques :
Les constantes relles sont par dfaut de type double

On peut forcer la machine utiliser un type de notre choix en ajoutant


les suffixes suivants:

f ou F pour le type float, Ex: 1.25f

l ou L pour le type long double, EX: 1.0L

2011/2012 Pr. Ben Mamoun 27


Les constantes caractres
Se sont des constantes qui dsignent un seul caractre,
elles sont toujours indiques entre des apostrophes, Ex :
b, A, ?

La valeur dune constante caractre est le code ASCII du


caractre

Les caractres constants peuvent apparatre dans des


oprations arithmtiques ou logiques

Les constantes caractres sont de type int

2011/2012 Pr. Ben Mamoun 28


Expressions et oprateurs
Une expression peut tre une valeur, une variable ou une opration
constitue par des valeurs, des constantes et des variables relies
entre eux par des oprateurs
exemples: 1, b, a*2, a+ 3*b-
3*b-c,
Un oprateur est un symbole qui permet de manipuler une ou
plusieurs variables pour produire un rsultat. On distingue :

les oprateurs binaires qui ncessitent deux oprandes (ex : a + b)


les oprateurs unaires qui ncessitent un seul oprande ( ex: a++)
l'oprateur conditionnel ?: , le seul qui ncessite trois oprandes

Une expression fournit une seule valeur, elle est value en


respectant des rgles de priorit et dassociativit

2011/2012 Pr. Ben Mamoun 29


Oprateurs en C
Le langage C est riche en oprateurs. Outre les oprateurs
standards, il comporte des oprateurs originaux daffectation,
dincrmentation et de manipulation de bits

On distingue les oprateurs suivants en C :

les oprateurs arithmtiques : +, -, *, /, %


les oprateurs daffectation : =, +=, -=,*=,/=,
les oprateurs logiques : &&, ||, !
les oprateurs de comparaison : ==, !=, <, >, <=, >=
les oprateurs dincrmentation et de dcrmentation : ++, --
les oprateurs sur les bits : <<, >>, &, |, ~, ^
dautres oprateurs particuliers : ?:, sizeof, cast

2011/2012 Pr. Ben Mamoun 30


Oprateurs arithmtiques
binaires : + - * / et % (modulo) et unaire : -

Les oprandes peuvent tre des entiers ou des rels sauf pour % qui
agit uniquement sur des entiers

Lorsque les types des deux oprandes sont diffrents il ya conversion


implicite dans le type le plus fort

Loprateur / retourne un quotient entier si les deux oprandes sont des


entiers (5 / 2 2). Il retourne un quotient rel si lun au moins des
oprandes est un rel (5.0 / 2 2.5)

2011/2012 Pr. Ben Mamoun 31


Conversions implicites
Les types short et char sont systmatiquement convertis en int
indpendemment des autres oprandes

La conversion se fait en gnral selon une hirarchie qui


n'altre pas les valeurs int long float double long double

Exemple1 : n * x + p (int n,p; float x)


excution prioritaire de n * x : conversion de n en float
excution de l'addition : conversion de p en float

Exemple2 : p1 * p2 + p3 * x (char p1, short p2, p3 ; float x)


p1, p2 et p3 d'abord convertis en int
p3 converti en float avant multiplication

2011/2012 Pr. Ben Mamoun 32


Exemple de conversion
Exemple : n * p + x (int n ; long p ; float x)

n * p + x

long conversion de n en long

* multiplication par p

long n * p de type long

float conversion de n * p en float

+ addition

float rsultat de type float

2011/2012 Pr. Ben Mamoun 33


Oprateur daffectation simple =
Loprateur = affecte une valeur ou une expression une variable
Exemple: double x,y,z; x=2.5; y=0.7; z=x*y-3;
Le terme gauche de laffectation est appel lvalue (left value)

L'affectation est interprte comme une expression. La valeur de


l'expression est la valeur affecte

On peut enchainer des affectations, lvaluation se fait de droite gauche


exemple : i = j = k= 5 (est quivalente k = 5, j=k et ensuite i=j)
La valeur affecte est toujours convertie dans le type de la lvalue, mme si
ce type est plus faible (ex : conversion de float en int, avec perte
d'information)

2011/2012 Pr. Ben Mamoun 34


Oprateurs relationnels
Oprateurs
< : infrieur <= : infrieur ou gal
> : suprieur >= : suprieur ou gal
== : gal != : diffrent de

Le rsultat de la comparaison nest pas une valeur boolenne,


mais 0 si le rsultat est faux et 1 si le rsultat est vrai

Les expressions relationnelles peuvent donc intervenir dans


des expressions arithmtiques

Exemple: a=2, b=7, c=4


b==3 0 (faux)
a!=b 1(vrai)
4*(a<b) + 2*(c>=b) 4

2011/2012 Pr. Ben Mamoun 35


Oprateurs logiques
&& : ET logique || : OU logique ! : ngation logique

&& retourne vrai si les deux oprandes sont vrais (valent 1) et 0 sinon

|| retourne vrai si lune des oprandes est vrai (vaut 1) et 0 sinon

Les valeurs numriques sont acceptes : toute valeur non nulle


correspond vraie et 0 correspond faux

Exemple : 5 && 11 1
!13.7 0

2011/2012 Pr. Ben Mamoun 36


valuation de && et ||
Le 2me oprande est valu uniquement en cas de ncessit
a && b : b valu uniquement si a vaut vrai (si a vaut faux,
valuation de b inutile car a && b vaut faux)
a b : b valu uniquement si a vaut faux (si a vaut vrai,
valuation de b inutile car a b vaut vrai)

Exemples
if ((d != 0) && (n / d == 2)) : pas de division si d vaut 0
if ((n >=0) && (sqrt(n) < p)) : racine non calcule si n < 0
Lintrt est dacclrer lvaluation et dviter les traitements
inappropris

2011/2012 Pr. Ben Mamoun 37


Incrmentation et dcrmentation
Les oprateurs ++ et -- sont des oprateurs unaires permettant respectivement d'ajouter
et de retrancher 1 au contenu de leur oprande
Cette opration est effectue aprs ou avant l'valuation de l'expression suivant que
l'oprateur suit ou prcde son oprande
k = i++ (post
(post--incrmentation) affecte d'abord la valeur de i k et incrmente aprs (k
= i++ ; k = i ; i = i+1 ; )

k = ++i (pr
pr--incrmentation
incrmentation) incrmente d'abord et aprs affecte la valeur incrmente
k (k = ++i ; i = i+1 ; k = i ; )

Exemple : i = 5 ; n = ++i - 5 ;
i vaut 6 et n vaut 1
i = 5 ; n = i++ - 5 ;
i vaut 6 et n vaut 0

Remarque : idem pour loprateur de dcrmentation --

2011/2012 Pr. Ben Mamoun 38


Oprateurs de manipulations de bits
oprateurs arithmtiques bit bit :
& : ET logique | : OU logique ^ : OU exclusif ~ : ngation

Les oprandes sont de type entier. Les oprations s'effectuent bit bit
suivant la logique binaire

b1 b2 ~b1 b1&b2 b1 | b2 b1^b2


1 1 0 1 1 0
1 0 0 0 1 1
0 1 1 0 1 1
0 0 1 0 0 0

Ex : 14= 1110 , 9=1001 14 & 9= 1000=8, 14 | 9 =1111=15

2011/2012 Pr. Ben Mamoun 39


Oprateurs de dcalage de bits
Il existe deux oprateurs de dcalage :
>> : dcalage droite << : dcalage gauche

Loprande gauche constitue lobjet dcaler et loprande droit le


nombre de bits de dcalage

Dans le cas d'un dcalage gauche les bits les plus gauche sont
perdus. Les positions binaires rendues vacantes sont remplies par
des 0
Ex : char x=14; (14=00001110) 14<<2 = 00111000 = 56
char y=-7; (-7=11111001) -7<<2= 11100100= -28

Rq : un dcalage gauche de k bits correspond (sauf


dbordement) la multiplication par 2k

2011/2012 Pr. Ben Mamoun 40


Oprateurs de dcalage de bits
Lors d'un dcalage droite les bits les plus droite sont perdus.
si l'entier dcaler est non sign, les positions binaires rendues
vacantes sont remplies par des 0
s'il est sign le remplissage dpend de limplmentation (en gnral le
remplissage se fait par le bit du signe)

Ex : char x=14; (14=00001110) 14>>2 = 00000011 = 3

Remarque : un dcalage droite (n >> k) correspond la division


entire par 2k si n est non sign

2011/2012 Pr. Ben Mamoun 41


Oprateurs daffectation combins
Soit un oprateur de calcul op et deux expressions exp1 et exp2.
Lexpression exp1= exp1 op exp2 peut scrire en gnral de
faon quivalente sous la forme exp1 op= exp2

Oprateurs utilisables :
+= -= *= /= %=
<<= >>= &= ^= |=

Exemples :
a=a+b scrit : a+=b
n=n%2 scrit : n%=2
x=x*i scrit : x*=i
p=p>>3 scrit : p>>=3
2011/2012 Pr. Ben Mamoun 42
Oprateur de forage de type (cast)
Il est possible deffectuer des conversions explicites ou de
forcer le type dune expression
Syntaxe : (<type>) <expression>
Exemple : int n, p ;
(double) (n / p); convertit lentier n / p en double

Remarque : la conversion (ou casting) se fait aprs calcul


(double) (n/p) (double) n / p (double) (n) / (double) (p)

float n = 4.6, p = 1.5 ;


(int) n / (int) p = 4 / 1 = 4
(int) n / p = 4 / 1.5 = 2.66
n / (int) p = 4.6 / 1 = 4.6
n / p = 4.6 / 1.5 = 3.06
2011/2012 Pr. Ben Mamoun 43
Oprateur conditionnel ? :
Syntaxe: exp1 ? exp2 : exp3
exp1 est value, si sa valeur est non nulle cest exp2
qui est excute, sinon exp3

Exemple1 : max = a > b ? a : b


Si a>b alors on affecte max le contenu de exp2 cd a sinon
on lui affecte b

Exemple2 : a>b ? i++ : i--;


Si a>b on incrmente i sinon on dcrmente i

2011/2012 Pr. Ben Mamoun 44


Oprateur squentiel ,
Utilit : regrouper plusieurs sous-expressions ou calculs en une seule
expression

Les calculs sont valus en squence de gauche droite

La valeur de lexpression est celle de la dernire sous-expression

Exemples
i++ , i + j; // on value i++ ensuite i+j (on utilise la valeur de i incrmente)
i++ , j = i + k , a + b; // la valeur de lexpression est celle de a+b
for (i=1 , k=0 ; ; ) { }

2011/2012 Pr. Ben Mamoun 45


Oprateur SIZEOF
Syntaxe : sizeof (<type>) ou sizeof (<variable>)
fournit la taille en octets d'un type ou d'une variable

Exemples
int n;
printf ("%d \n",sizeof(int)); // affiche 4
printf ("%d \n",sizeof(n)); // affiche 4

2011/2012 Pr. Ben Mamoun 46


Priorit et associativit des oprateurs
Une expression est value en respectant des rgles de priorit et
dassociativit des oprateurs
Ex: * est plus prioritaire que +, ainsi 2 + 3 * 7 vaut 23 et non 35

Le tableau de la page suivante donne la priorit de tous les oprateurs.


La priorit est dcroissante de haut en bas dans le tableau.

Les oprateurs dans une mme ligne ont le mme niveau de priorit.
Dans ce cas on applique les rgles dassociativit selon le sens de la
flche. Par exemple: 13%3*4 vaut 4 et non 1

Remarque: en cas de doute il vaut mieux utiliser les parenthses pour


indiquer les oprations effectuer en priorit. Ex:: (2
( + 3) * 7 vaut 35

2011/2012 Pr. Ben Mamoun 47


Priorits de tous les oprateurs
Catgorie Oprateurs Associativit
rfrence () [] -> .
unaire + - ++ -- ! * & (cast) sizeof
arithmtique * / %
arithmtique + -
dcalage << >>
relationnel < <= > >=
relationnel == !=
manip. de bits &
manip. de bits ^
manip. de bits
logique &&
logique
conditionnel ?:
affectation = += -= *= /= %=
&= ^= = <<= >>=
squentiel ,
2011/2012 Pr. Ben Mamoun 48
Chapitre 3

Entres-sorties
Les instructions de lecture et dcriture
Il sagit des instructions permettant la machine de dialoguer avec lutilisateur

Dans un sens la lecture permet lutilisateur dentrer des valeurs au


clavier pour quelles soient utilises par le programme

Dans lautre sens, lcriture permet au programme de communiquer des


valeurs lutilisateur en les affichant lcran (ou en les crivant dans un
fichier)

La bibliothque standard <stdio> contient un ensemble de fonctions qui


assurent la lecture et lcriture des donnes. Dans ce chapitre, nous allons en
discuter les plus importantes:
printf() criture formate de donnes
scanf() lecture formate de donnes

2011/2012 Pr. Ben Mamoun 50


Ecriture formate de donnes: printf ()
la fonction printf est utilise pour afficher lcran du texte, des
valeurs de variables ou des rsultats dexpressions.

Syntaxe : printf("format", expr1, expr2, );


expr1, : sont les variables et les expressions dont les valeurs sont
reprsenter
Format : est une chane de caractres qui peut contenir
du texte
des squences dchappement (\n, \t, )
des spcificateurs de format : un ou deux caractres prcds du
symbole %, indiquant le format daffichage

Rq : Le nombre de spcificateurs de format doit tre gale au


nombre dexpressions!

2011/2012 Pr. Ben Mamoun 51


Spcificateurs de format
SYMBOLE TYPE AFFICHAGE COMME
%d ou %i int entier relatif

%u unsinged int entier naturel non sign

%c char caractre

%o int entier sous forme octale

%x ou %X int entier sous forme hexadcimale

%f float, double rel en notation dcimale

%e ou %E float, double rel en notation exponentielle

%s char* chane de caractres

2011/2012 Pr. Ben Mamoun 52


Squences dchappement
l'affichage du texte peut tre contrl l'aide des squences
d'chappement :

\n : nouvelle ligne
\t : tabulation horizontale
\a : signal sonore
\b : retour arrire
\r : retour chariot
\v : tabulation verticale
\f : saut de page
\\ : back slash ( \ )
\ : apostrophe
\" : guillemet

2011/2012 Pr. Ben Mamoun 53


Exemples de printf()
#include<stdio.h>
main()
{ int i=1 , j=2, N=15;
printf("la somme de %d et %d est %d \n", i, j, i+j);
printf( N= %x \n" , N);
char c='A' ;
printf(" le code Ascii de %c est %d \n", c, c);
}
Ce programme va afficher : la somme de 1 et 2 est 3
N=f
le code Ascii de A est 65

Remarque : Pour pouvoir traiter correctement les arguments du type long,


il faut utiliser les spcificateurs %ld, %li, %lu, %lo, %lx

2011/2012 Pr. Ben Mamoun 54


Exemples de printf()
#include<stdio.h>
main()
{ double x=10.5, y=2.5;
printf("%f divis par %f gal %f \n", x, y, x/y);
printf("%e divis par %e gal %e\n", x, y, x/y);
}
Ce programme va afficher :
10.500000 divis par 2.500000 gal 4.200000
1.050000e+001 divis par 2.500000e+000 gal 4.200000e+000

Remarque : Pour pouvoir traiter correctement les arguments du type


long double, il faut utiliser les spcificateurs %lf et %le

2011/2012 Pr. Ben Mamoun 55


Remarques sur laffichage
Par dfaut, les entiers sont affichs sans espaces avant ou aprs

Pour agir sur laffichage un nombre est plac aprs % et prcise


le nombre de caractres minimum utiliser

Exemples : printf("%4d" , n );
n = 20 ~~20 (~ : espace)
n=56123 56123
printf("%4X", 123); ~~7B

printf("%4x", 123); ~~7b

2011/2012 Pr. Ben Mamoun 56


Remarques sur laffichage
Pour les rels, on peut prciser la largeur minimale de la valeur afficher et
le nombre de chiffres aprs le point dcimal.
La prcision par dfaut est fixe six dcimales. Les positions dcimales
sont arrondies la valeur la plus proche.
Exemples :
printf("%f", 100.123); 100.123000
printf("%12f", 100.123); ~~100.123000
printf("%.2f", 100.123); 100.12
printf("%5.0f", 100.123); ~~100
printf("%10.3f", 100.123); ~~~100.123
printf("%.4f", 1.23456); 1.2346

2011/2012 Pr. Ben Mamoun 57


Lecture formate de donnes: scanf ()
la fonction scanf permet de lire des donnes partir du clavier

Syntaxe : scanf("format", AdrVar1, AdrVar2, );


Format : le format de lecture de donnes, est le mme que pour
printf

adrVar1, adrVar2, : adresses des variables auxquelles les


donnes seront attribues. Ladresse dune variable est
indique par le nom de la variable prcd du signe &

2011/2012 Pr. Ben Mamoun 58


Exemples de scanf()
#include<stdio.h>
main()
{ int i , j;
scanf("%d%d", &i, &j);
printf("i=%d et j=%d", i, j);
}

ce programme permet de lire deux entiers entrs au clavier et les


afficher lcran.

Remarque : pour lire une donne du type long, il faut utiliser les spcificateurs
%ld, %li, %lu, %lo, %lx.

2011/2012 Pr. Ben Mamoun 59


Exemples de scanf()
#include<stdio.h>
main()
{ float x;
double y;
scanf("%f %lf", &x, &y);
printf("x=%f et y=%f", x,y);
}

ce programme permet de lire un rel simple et un autre double du


clavier et les afficher lcran

Remarque : pour lire une donne du type double, il faut utiliser %le ou %lf et pour
lire une donne du type long double, il faut utiliser %Le ou %Lf
2011/2012 Pr. Ben Mamoun 60
Chapitre 4

Structures de contrle
Structures de contrle
Les structures de contrle dfinissent la faon avec laquelle les
instructions sont effectues. Elles conditionnent l'excution
d'instructions la valeur d'une expression

On distingue :
Les structures alternatives (tests) : permettent deffectuer des choix
cd de se comporter diffremment suivant les circonstances (valeur
d'une expression). En C, on dispose des instructions : ifelse et
switch.

Les structures rptitives (boucles) : permettent de rpter


plusieurs fois un ensemble donn dinstructions. Cette famille dispose
des instructions : while, dowhile et for.

2011/2012 Pr. Ben Mamoun 62


Linstruction ifelse
Syntaxe : If (expression)
bloc-instruction1
else
bloc-instruction2

bloc-instruction peut tre une seule instruction termine par un point-


virgule ou une suite dinstructions dlimites par des accolades { }

expression est value, si elle est vraie (valeur diffrente de 0), alors
bloc-instruction1 est excut. Si elle est fausse (valeur 0) alors bloc-
instruction2 est excut

La partie else est facultative. Sil ny a pas de traitement raliser


quand la condition est fausse, on utilisera simplement la forme :
If (expression) bloc-instruction1

2011/2012 Pr. Ben Mamoun 63


ifelse : exemples
float a, b, max;
if (a > b)
max = a;
else
max = b;

int a;
if ((a%2)==0)
printf(" %d est paire" ,a);
else
printf(" a est impaire ",a);

2011/2012 Pr. Ben Mamoun 64


Imbrication des instructions if
On peut imbriquer plusieurs instructions ifelse

Ceci peut conduire des confusions, par exemple :


if (N>0)
if (A>B)
MAX=A;
else MAX=B; (interprtation 1 : si N=0 alors MAX prend la valeur B)

if (N>0)
if (A>B)
MAX=A;
else MAX=B; (interprtation 2 : si N=0 MAX ne change pas)

En C un else est toujours associ au dernier if qui ne possde pas


une partie else (cest linterprtation 2 qui est juste)

2011/2012 Pr. Ben Mamoun 65


Imbrication des instructions if
Conseil : pour viter toute ambigut ou pour forcer une certaine
interprtation dans limbrication des if, il vaut mieux utiliser les
accolades

if(a<=0)
{if(a==0)
printf("a est nul ");
else
printf(" a est strictement ngatif ");}
else
printf(" a est strictement positif " );

Pour forcer linterprtation 1: if (N>0)


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

2011/2012 Pr. Ben Mamoun 66


Linstruction daiguillage switch :
Permet de choisir des instructions excuter selon la valeur dune
expression qui doit tre de type entier

la syntaxe est :
switch (expression) {
case expression_constante1 : instructions_1; break;
case expression_constante2 : instructions_2; break;

case expression_constante n : instructions_n; break;
default : instructions;
}
expression_constantei doit tre une expression constante entire
Instructions i peut tre une instruction simple ou compose
break et default sont optionnels et peuvent ne pas figurer

2011/2012 Pr. Ben Mamoun 67


Fonctionnement de switch
expression est value

si sa valeur est gale une expression_constante i, on se branche


ce cas et on excute les instructions_i qui lui correspondent

On excute aussi les instructions des cas suivants jusqu la fin du bloc
ou jusqu une instruction break (qui fait sortir de la structure switch)

si la valeur de l'expression n'est gale aucune des expressions


constantes
Si default existe, alors on excute les instructions qui le suivent
Sinon aucune instruction nest excute

2011/2012 Pr. Ben Mamoun 68


Switch : exemple
main( )
{ char c;
switch (c) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'y': printf("voyelle\n"); break ;
default : printf("consonne\n");
}
}

2011/2012 Pr. Ben Mamoun 69


Les boucles while et do .. while
while (condition) do
{ {
instructions instructions

} } while (condition);

la condition (dite condition de contrle de la boucle) est value chaque


itration. Les instructions (corps de la boucle) sont excuts tant que la
condition est vraie, on sort de la boucle ds que la condition devient fausse

dans la boucle while le test de continuation s'effectue avant d'entamer le corps


de boucle qui, de ce fait, peut ne jamais s'excuter

par contre, dans la boucle do-while ce test est effectu aprs le corps de
boucle, lequel sera alors excut au moins une fois

2011/2012 Pr. Ben Mamoun 70


Boucle while : exemple
Un programme qui dtermine le premier nombre entier N
tel que la somme de 1 N dpasse strictement 100

main( )
{ int i, som;
i =0; som= 0;
while (som <=100)
{ i++;
som+=i;
}
printf (" La valeur cherche est N= %d\n ", i);
}

2011/2012 Pr. Ben Mamoun 71


Boucle do .. while : exemple
Contrle de saisie d'une note saisie au clavier jusqu ce
que la valeur entre soit valable

main()
{ int N;
do {
printf (" Entrez une note comprise entre 0 et 20 \n");
scanf("%d",&N);
} while (N < 0 || N > 20);
}

2011/2012 Pr. Ben Mamoun 72


La boucle for
for (expr1 ; expr2 ; expr3)
{
instructions
}
L'expression expr1 est value une seule fois au dbut de
l'excution de la boucle. Elle effectue linitialisation des donnes de
la boucle

L'expression expr2 est value et teste avant chaque passage dans


la boucle. Elle constitue le test de continuation de la boucle.

L'expression expr3 est value aprs chaque passage. Elle est


utilise pour rinitialiser les donnes de la boucle

2011/2012 Pr. Ben Mamoun 73


Boucle for : remarques
for (expr1 ; expr2 ; expr3) quivaut :
{ expr1;
instructions while(expr2)
} { instructions
expr3;
}

En pratique, expr1 et expr3 contiennent souvent plusieurs


initialisations ou rinitialisations, spares par des virgules

2011/2012 Pr. Ben Mamoun 74


Boucle for : exemple
Calcul de x la puissance n o x est un rel non nul et n
un entier positif ou nul
main ( )
{ float x, puiss;
int n, i;
{ printf (" Entrez respectivement les valeurs de x et n \n");
scanf ("%f %d" , &x, &n);
for (puiss =1, i=1; i<=n; i++)
puiss*=x;
printf (" %f la puissance %d est gal : %f", x,n,puiss);
}
}

2011/2012 Pr. Ben Mamoun 75


Linstruction break
Linstruction break peut tre utilise dans une boucle (for, while, ou do .. while).
Elle permet darrter le droulement de la boucle et le passage la premire
instruction qui la suit

En cas de boucles imbriques, break ne met fin qu la boucle la plus interne


{int i,j;
for(i=0;i<4;i++)
for (j=0;j<4;j++)
{ if(j==1) break;
printf("i=%d,j=%d\n ",i,j);
}
} rsultat: i=0,j=0
i=1,j=0
i=2,j=0
i=3,j=0

2011/2012 Pr. Ben Mamoun 76


Linstruction continue
Linstruction continue peut tre utilise dans une boucle (for, while, ou
do .. while). Elle permet labandon de litration courante et le passage
litration suivante

{int i;
for(i=1;i<5;i++)
{printf("dbut itration %d\n " ,i);
if(i<3) continue;
printf(" fin itration %d\n " ,i);
}
} rsultat: dbut itration 1
dbut itration 2
dbut itration 3
fin itration 3
dbut itration 4
fin itration 4

2011/2012 Pr. Ben Mamoun 77


Chapitre 5

Les tableaux
Tableaux
Un tableau est une variable structure compose dun nombre de
variables simples de mme type dsignes par un seul identificateur

Ces variables simples sont appeles lments ou composantes du


tableau, elles sont stockes en mmoire des emplacements
contigus (lun aprs lautre)

Le type des lments du tableau peut tre :


simple : char, int, float, double,
pointeur ou structure (chapitres suivants)

On peut dfinir des tableaux :


une dimension (tableau unidimensionnel ou vecteur)
plusieurs dimensions (tableau multidimensionnel )

2011/2012 Pr. Ben Mamoun 79


Dclaration des tableaux
La dclaration d'un tableau une dimension s'effectue en prcisant le
type de ses lments et sa dimension (le nombre de ses lments) :

Syntaxe en C : Type identificateur[dimension];


[dimension];
Exemple : float notes[30];

La dclaration dun tableau permet de lui rserver un espace mmoire


dont la taille (en octets) est gal : dimension * taille du type

ainsi pour :
short A[100]; // on rserve 200 octets (100* 2octets)
char mot[10]; // on rserve 10 octets (10* 1octet)

2011/2012 Pr. Ben Mamoun 80


Initialisation la dclaration
On peut initialiser les lments dun tableau lors de la dclaration, en
indiquant la liste des valeurs respectives entre accolades. Ex:
int A[5] = {1, 2, 3, 4, 5};
float B[4] = {-1.5, 3.3, 7e-2, -2.5E3};
Si la liste ne contient pas assez de valeurs pour toutes les
composantes, les composantes restantes sont initialises par zro
Ex: short T[10] = {1, 2, 3, 4, 5};
la liste ne doit pas contenir plus de valeurs que la dimension du
tableau. Ex: short T[3] = {1, 2, 3, 4, 5}; Erreur

Il est possible de ne pas indiquer la dimension explicitement lors de


l'initialisation. Dans ce cas elle est gale au nombre de valeurs de la
liste. Ex: short T[ ] = {1, 2, 3, 4, 5}; tableau de 5 lments

2011/2012 Pr. Ben Mamoun 81


Accs aux composantes dun tableau
L'accs un lment du tableau se fait au moyen de l'indice. Par
exemple, T[i] donne la valeur de l'lment i du tableau T

En langage C lindice du premier lment du tableau est 0. Lindice


du dernier lment est gal la dimension-1

Ex: int T[ 5] = {9, 8, 7, 6, 5};


T[0]=9, T[1]=8, T[2]=7, T[3]=6, T[4]=5
Remarques:
on ne peut pas saisir, afficher ou traiter un tableau en entier, ainsi on ne peut
pas crire printf(" %d",T) ou scanf(" %d",&T)

On traite les tableaux lment par lment de faon rptitive en utilisant


des boucles

2011/2012 Pr. Ben Mamoun 82


Tableaux : saisie et affichage
Saisie des lments dun tableau T dentiers de taille n :

for(i=0;i<n
for(i=0;i<n;i++)
{ printf ("Entrez l'lment %d \n ",i + 1);
scanf(" %d" , &T[i]);
}

Affichage des lments dun tableau T de taille n :

for(i=0;i<n
for(i=0;i<n;i++)
printf (" %d \t",T[i]);

2011/2012 Pr. Ben Mamoun 83


Tableaux : exemple
Calcul du nombre d'tudiants ayant une note suprieure 10 :

main ( )
{ float notes[30];
int nbre,i;
for(i=0;i<30;i++)
for(i=0;i<30
{ printf ("Entrez notes[%d] \n ",i);
scanf(" %f" , &notes[i]);
}
nbre=0;
for (i=0; i<30; i++)
if (notes[i]>10) nbre+=1;
printf (" le nombre de notes > 10 est gal : %d", nbre);

}
2011/2012 Pr. Ben Mamoun 84
Tableaux plusieurs dimensions
On peut dfinir un tableau n dimensions de la faon suivante:

Type Nom_du_Tableau[D1][D2][Dn];
[D1][D2][Dn]; o Di est le nombre
dlments dans la dimension i

Exemple : pour stocker les notes de 20 tudiants en 5 modules


dans deux examens, on peut dclarer un tableau :

float notes[20][5][2];

(notes[i][j][k] est la note de lexamen k dans le module j pour


ltudiant i)

2011/2012 Pr. Ben Mamoun 85


Tableaux deux dimensions (Matrices)
Syntaxe : Type nom_du_Tableau[nombre_ligne][nombre_colonne];
[nombre_ligne][nombre_colonne];
Ex: short A[2][3]; On peut reprsenter le tableau A de la manire
suivante :
A[0][0] A[0][1] A[0][2]
A[1][0] A[1][1] A[1][2]

Un tableau deux dimensions A[n][m] est interprter comme un


tableau unidimensionnel de dimension n dont chaque composante
A[i] est un tableau unidimensionnel de dimension m.

Un tableau deux dimensions A[n][m] contient n* m composantes.


Ainsi lors de la dclaration, on lui rserve un espace mmoire dont la
taille (en octets) est gal : n*m* taille du type

2011/2012 Pr. Ben Mamoun 86


Initialisation la dclaration dune Matrice
Linitialisation lors de la dclaration se fait en indiquant la liste des
valeurs respectives entre accolades ligne par ligne

Exemple :
float A[3][4] = {{-1.5, 2.1, 3.4, 0}, {8e-3, 7e-5,1, 2.7 }, {3.1, 0, 2.5E4, -1.3E2}};

A[0][0]=-1.5 , A[0][1]=2.1, A[0][2]=3.4, A[0][3]=0


A[1][0]=8e-3 , A[1][1]=7e-5, A[1][2]=1, A[1][3]=2.7
A[2][0]=3.1 , A[2][1]=0, A[2][2]=2.5E4, A[2][3]=-1.3E2

On peut ne pas indiquer toutes les valeurs: Les composantes


manquantes seront initialises par zro

Comme pour les tableaux unidimensionnels, Il est dfendu d'indiquer


trop de valeurs pour une matrice

2011/2012 Pr. Ben Mamoun 87


Matrices : saisie et affichage
Saisie des lments dune matrice dentiers A[n][m] :

for(i=0;i<n
for(i=0;i<n;i++)
for(j=0;j<m;j++)
for(j=0;j<m
{ printf ("Entrez la valeur de A[%d][%d] \n ",i,j);
scanf(" %d" , &A[i][j]);
}

Affichage des lments dune matrice dentiers A[n][m] :

for(i=0;i<n
for(i=0;i<n;i++)
{ for(j=0;j<m
for(j=0;j<m;j++)
printf (" %d \t",A[i][j]);
printf("\n");
}

2011/2012 Pr. Ben Mamoun 88


Reprsentation dun tableau en mmoire
La dclaration dun tableau provoque la rservation automatique par le
compilateur dune zone contigu de la mmoire.

La mmoire est une succession de cases mmoires. Chaque case est


une suite de 8 bits (1 octet), identifie par un numro appel adresse.
(on peut voir la mmoire comme une armoire constitue de tiroirs numrots. Un numro
de tiroir correspond une adresse)

Les adresses sont souvent exprimes en hexadcimal pour une criture


plus compacte et proche de la reprsentation binaire de ladresse. Le
nombre de bits dadressage dpend des machines.

En C, loprateur & dsigne adresse de. de. Ainsi, printf("


printf( adresse de a=
%x ", &a) affiche ladresse de la variable a en hexadcimal

2011/2012 Pr. Ben Mamoun 89


Reprsentation dun tableau une
dimension en mmoire
En C, le nom d'un tableau est le reprsentant de
l'adresse du premier lment du tableau (pour un 1E05
tableau T: T=&T[0] ) T1E06 100

Les composantes du tableau tant stockes en 1E08 200


mmoire des emplacements contigus, leses
adresses des autres composantes sont calcules
(automatiquement) relativement cette adresse : 1E0A 300
&T[i]= &T[0]+sizeof(type)*i
1E0C 400
Exemple : short T[5] = {100, 200, 300, 400, 500};
1E0E 500
et supposons que T=&T[0] =1E06
1E0F
On peut afficher et vrifier les adresses du tableau:
for(i=0;i<5;i++)
printf("adresse de T[%d]= %x\
%x\n",i,&T[i]);
2011/2012 Pr. Ben Mamoun 90
Reprsentation dun tableau deux
dimensions en mmoire
Les lments dun tableau sont stockes en mmoire
des emplacements contigus ligne aprs ligne A[0]0118 A[0][0]
A[0][1]
Comme pour les tableaux unidimensionnels, le nom d'un A[0][2]
tableau A deux dimensions est le reprsentant de A[0][3]
l'adresse du premier lment : A=&A[0][0]
A[1]011C A[1][0]
A[1][1]
Rappelons quune matrice A[n][m] est interprter comme
A[1][2]
un tableau de dimension n dont chaque composante A[i]
est un tableau de dimension m. A[1][3]
A[2] 0120 A[2][0]
A[i] et &A[i][0] reprsentent ladresse du 1erlment de la A[2][1]
ligne i (pour i de 0 n-
n-1)
A[2][2]
A[2][3]
Exemple : char A[3][4]; A=&A[0][0] =0118

2011/2012 Pr. Ben Mamoun 91


Chapitre 6

Les pointeurs
Pointeurs : dfinition
Un pointeur est une variable spciale qui peut
contenir ladresse dune autre variable. .
.
.

Exemple : Soit A une variable contenant la valeur P 3F02 1C50


10 et P un pointeur qui contient l'adresse de A
.
(on dit que P pointe sur A) . .
.

Remarques :
A 10 3F02
Le nom dune variable permet d'accder directement
sa valeur (adressage direct). mmoire
Un pointeur qui contient l'adresse de la variable, permet
d'accder indirectement sa valeur (adressage
indirect).

Le nom d'une variable est li la mme adresse, alors


quun pointeur peut pointer sur diffrentes adresses

2011/2012 Pr. Ben Mamoun 93


Intrts des pointeurs
Les pointeurs prsentent de nombreux avantages :

Ils sont indispensables pour permettre le passage par rfrence


pour les paramtres des fonctions

Ils permettent de crer des structures de donnes (listes et


arbres) dont le nombre dlments peut voluer dynamiquement.
Ces structures sont trs utilises en programmation.

Ils permettent d'crire des programmes plus compacts et


efficaces

2011/2012 Pr. Ben Mamoun 94


Dclaration dun pointeur
En C, chaque pointeur est limit un type de donne (mme si la
valeur dun pointeur, qui est une adresse, est toujours un entier).

Le type dun pointeur dpend du type de la variable pointe. Ceci


est important pour connatre la taille de la valeur pointe.

On dclare un pointeur par linstruction : type *nom-du-pointeur ;


type est le type de la variable pointe
* est loprateur qui indiquera au compilateur que cest un pointeur
Exemple :
int *pi; //pi est un pointeur vers une variable de type int
float *pf; //pf est un pointeur vers une variable de type float

Rq: la valeur dun pointeur donne ladresse du premier octet parmi


les n octets o la variable est stocke

2011/2012 Pr. Ben Mamoun 95


Oprateurs de manipulation des pointeurs
Lors du travail avec des pointeurs, nous utilisons :
un oprateur 'adresse de': & pour obtenir l'adresse d'une variable
un oprateur 'contenu de': * pour accder au contenu d'une adresse

Exemple1 :

int * p; //on dclare un pointeur vers une variable de type int


int i=10, j=30; // deux variables de type int
p=&i; // on met dans p, ladresse de i (p pointe sur i)
printf("*p = %d \n",*p); //affiche : *p = 10
*p=20; // met la valeur 20 dans la case mmoire pointe par p (i vaut 20
aprs cette instruction)
p=&j; // p pointe sur j
i=*p; // on affecte le contenu de p i (i vaut 30 aprs cette instruction)

2011/2012 Pr. Ben Mamoun 96


Oprateurs de manipulation des pointeurs
Exemple2 : float a, *p;
p=&a;
printf("Entrez une valeur : \n");
scanf("%f ",p); //supposons quon saisit la valeur 1.5
printf("Adresse de a= %x, contenu de a= %f\n" , p,*p);
*p+=0.5;
printf ("a= %f\n" , a); //affiche a=2.0

Remarque : si un pointeur P pointe sur une variable X, alors *P


peut tre utilis partout o on peut crire X
X+=2 quivaut *P+=2
++X quivaut ++ *P
X++ quivaut (*P)++ // les parenthses ici sont obligatoires car
lassociativit des oprateurs unaires * et ++ est de droite gauche

2011/2012 Pr. Ben Mamoun 97


Initialisation dun pointeur
A la dclaration dun pointeur p, on ne sait pas sur quel zone mmoire il
pointe. Ceci peut gnrer des problmes :
int *p;
*p = 10; //provoque un problme mmoire car le pointeur p na pas t initialis

Conseil : Toute utilisation dun pointeur doit tre prcde par une
initialisation.
On peut initialiser un pointeur en lui affectant :

ladresse dune variable (Ex: int a, *p1; p1=&a; )


un autre pointeur dj initialis (Ex: int *p2; p2=p1;)
la valeur 0 dsigne par le symbole NULL, dfini dans <stddef.h>.
Ex: int *p; p=0;ou p=NULL; (on dit que p pointe nulle part: aucune
adresse mmoire ne lui est associ)
Rq: un pointeur peut aussi tre initialis par une allocation dynamique (voir
fin du chapitre)

2011/2012 Pr. Ben Mamoun 98


Pointeurs : exercice
main()
{ int A = 1, B = 2, C = 3, *P1, *P2;
P1=&A;
P2=&C;
*P1=(*P2)++;
P1=P2;
P2=&B;
*P1-=*P2;
++*P2;
*P1*=*P2;
A=++*P2**P1;
P1=&A;
*P2=*P1/=*P2;
}
Donnez les valeurs de A, B,C,P1 et P2 aprs chaque instruction

2011/2012 Pr. Ben Mamoun 99


Oprations arithmtiques avec les pointeurs
La valeur dun pointeur tant un entier, certaines oprations
arithmtiques sont possibles : ajouter ou soustraire un entier un
pointeur ou faire la diffrence de deux pointeurs

Pour un entier i et des pointeurs p, p1 et p2 sur une variable de type T


p+i (resp p-i) : dsigne un pointeur sur une variable de type T. Sa valeur
est gale celle de p incrmente (resp dcrmente) de i*sizeof(T).

p1-p2 : Le rsultat est un entier dont la valeur est gale (diffrence des
adresses)/sizeof(T).
Remarque:
on peut galement utiliser les oprateurs ++ et -- avec les pointeurs
la somme de deux pointeurs nest pas autorise

2011/2012 Pr. Ben Mamoun 100


Oprations arithmtiques avec les pointeurs
Exemple :
float *p1, *p2;
float z =1.5;
p1=&z;
printf("Adresse p1 = %x \n",p1);
p1++;
p2=p1+1;
printf("Adresse p1 = %x \t Adresse p2 = %x\n",p1,p2);
printf("p2-p1 = %d \n",p2-p1);
Affichage :
Adresse p1 = 22ff44
Adresse p1 = 22ff48 Adresse p2 = 22ff4c
p2-p1=1

2011/2012 Pr. Ben Mamoun 101


Pointeurs et tableaux
Comme on la dj vu au chapitre 5, le nom d'un tableau T reprsente
l'adresse de son premier lment (T=&T[0]). Avec le formalisme pointeur, on
peut dire que T est un pointeur constant sur le premier lment du tableau.

En dclarant un tableau T et un pointeur P du mme type, linstruction P=T fait


pointer P sur le premier lment de T (P=&T[0]) et cre une liaison entre P et
le tableau T.

A partir de l, on peut manipuler le tableau T en utilisant P, en effet :

P pointe sur T[0] et *P dsigne T[0]


P+1 pointe sur T[1] et *(P+1) dsigne T[1]
.
P+i pointe sur T[i] et *(P+i) dsigne T[i]

2011/2012 Pr. Ben Mamoun 102


Pointeurs et tableaux : exemple
Exemple: short x, A[7]={5,0,9,2,1,3,8};
short *P;
P=A;
x=*(P+5);

Le compilateur obtient l'adresse P+5 en ajoutant 5*sizeof(short) = 10


octets l'adresse dans P

Dautre part, les composantes du tableau sont stockes des


emplacements contigus et &A[5]= &A[0]+sizeof(short)*5=A+10

Ainsi, x est gale la valeur de A[5] (x= A[5])

2011/2012 Pr. Ben Mamoun 103


Pointeurs : saisie et affichage dun
tableau
Version 1: Version 2: sans utiliser i
main() main()
{ float T[100] , *pt; { float T[100] , *pt;
int i,n; int n;
do {printf("Entrez n \n " ); do {printf("Entrez n \n " );
scanf(" %d" ,&n); scanf(" %d" ,&n);
}while(n<0 ||n>100); }while(n<0 ||n>100);

pt=T;
for(i=0;i<n;i++)
for(i=0;i<n for(pt=T;pt<T+n
for(pt=T;pt<T+n;pt++)
{ printf ("Entrez T[%d] \n ",i ); { printf ("Entrez T[%d] \n ",pt-T );
scanf(" %f" , pt+i); scanf(" %f" , pt);
} }

for(i=0;i<n
for(i=0;i<n;i++) for(pt=T;pt<T+n
for(pt=T;pt<T+n;pt++)
printf (" %f \t",*(pt+i)); printf (" %f \t",*pt);
} }
2011/2012 Pr. Ben Mamoun 104
Pointeurs et tableaux deux dimensions
Le nom d'un tableau A deux dimensions est un pointeur constant sur le
premier lment du tableau cd A[0][0].

En dclarant un tableau A[n][m] et un pointeur P du mme type, on peut


manipuler le tableau A en utilisant le pointeur P en faisant pointer P sur le
premier lment de A (P=&A[0][0]), Ainsi :

P pointe sur A[0][0] et *P dsigne A[0][0]


P+1 pointe sur A[0][1] et *(P+1) dsigne A[0][1]
.
P+M pointe sur A[1][0] et *(P+M) dsigne A[1][0]
.
P+i*M pointe sur A[ i][0] et *(P+i*M) dsigne A[i][0]
.
P+i*M+j pointe sur A[ i][ j] et *(P+i*M+j) dsigne A[i][j]

2011/2012 Pr. Ben Mamoun 105


Pointeurs : saisie et affichage dune
matrice
#define N 10
#define M 20
main( )
{ int i, j, A[N][M], *pt;
pt=&A[0][0];
for(i=0;i<N;i++)
for(i=0;i<N
for(j=0;j<M;j++)
for(j=0;j<M
{ printf ("Entrez A[%d][%d]\n ",i,j );
scanf(" %d" , pt+i*M+j);
}

for(i=0;i<N
for(i=0;i<N;i++)
{ for(j=0;j<M
for(j=0;j<M;j++)
printf (" %d \t",*(pt+i*M+j));
printf ("\n");
}
}
2011/2012 Pr. Ben Mamoun 106
Pointeurs et tableaux : remarques
En C, on peut dfinir :

Un tableau de pointeurs :
Ex : int *T[10]; //dclaration dun tableau de 10 pointeurs dentiers

Un pointeur de tableaux :
Ex : int (*pt)[20]; //dclaration dun pointeur sur des tableaux de 20
lments

Un pointeur de pointeurs :
Ex : int **pt; //dclaration dun pointeur pt qui pointe sur des pointeurs
dentiers

2011/2012 Pr. Ben Mamoun 107


Allocation dynamique de mmoire
Quand on dclare une variable dans un programme, on lui rserve
implicitement un certain nombre doctets en mmoire. Ce nombre est
connu avant lexcution du programme

Or, il arrive souvent quon ne connat pas la taille des donnes au


moment de la programmation. On rserve alors l'espace maximal
prvisible, ce qui conduit un gaspillage de la mmoire

Il serait souhaitable dallouer la mmoire en fonction des donnes


saisir (par exemple la dimension dun tableau)

Il faut donc un moyen pour allouer la mmoire lors de l'excution du


programme : cest lallocation dynamique de mmoire
2011/2012 Pr. Ben Mamoun 108
La fonction malloc
La fonction malloc de la bibliothque <stdlib> permet de localiser et de
rserver de la mmoire, sa syntaxe est : malloc(N)
Cette fonction retourne un pointeur de type char * pointant vers le
premier octet dune zone mmoire libre de N octets ou le pointeur
NULL sil ny a pas assez de mmoire libre allouer.

Exemple : Si on veut rserver la mmoire pour un texte de 1000


caractres, on peut dclarer un pointeur pt sur char (char *pt).
L'instruction: T = malloc(1000); fournit l'adresse d'un bloc de 1000 octets
libres et l'affecte T. S'il n'y a pas assez de mmoire, T obtient la valeur
zro (NULL).

Remarque : Il existe dautres fonctions dallocation dynamique de


mmoire dans la bibliothque <stdlib>

2011/2012 Pr. Ben Mamoun 109


La fonction malloc et free
Si on veut rserver de la mmoire pour des donnes qui ne sont pas
de type char, il faut convertir le type de la sortie de la fonction malloc
laide dun cast.

Exemple : on peut rserver la mmoire pour 2 variables contigus de


type int avec linstruction : p = (int*)malloc(2 * sizeof(int)); o p est un
pointeur sur int (int *p).

Si on n'a plus besoin d'un bloc de mmoire rserv par malloc, alors
on peut le librer l'aide de la fonction free , dont la synatxe est :
free(pointeur);

Si on ne libre pas explicitement la mmoire l'aide de free, alors elle


est libre automatiquement la fin du programme.

2011/2012 Pr. Ben Mamoun 110


malloc et free : exemple
Saisie et affichage dun tableau
printf(" Saisie du tableau \n " );
#include<stdio.h>
for(i=0;i<n;i++)
for(i=0;i<n
#include<stdlib.h>
{ printf ("lment %d ? \n ",i+1);
main()
scanf(" %f" , pt+i);
{ float *pt;
}
int i,n;
printf("Entrez la taille du tableau \n" );
printf(" Affichage du tableau \n " );
scanf(" %d" ,&n);
for(i=0;i<n;i++)
for(i=0;i<n
pt=(float*) malloc(n*sizeof(float)); printf (" %f \t",*(pt+i));
if (pt==Null) free(pt);
{ }
printf( " pas assez de mmoire \n" );
system(" pause " );
}

2011/2012 Pr. Ben Mamoun 111


Chapitre 7

Les fonctions
La programmation modulaire
Certains problmes conduisent des programmes longs, difficiles crire et
comprendre. On les dcoupe en des parties appeles sous
sous--programmes ou
modules
Les modules sont des groupes d'instructions qui fournissent une solution des
parties bien dfinies d'un problme plus complexe. Ils ont plusieurs intrts :

permettent de "factoriser" les programmes,


programmes cd de mettre en commun
les parties qui se rptent
permettent une structuration et une meilleure lisibilit des programmes
facilitent la maintenance du code (il suffit de modifier une seule fois)
peuvent ventuellement tre rutilises dans d'autres programmes

La structuration de programmes en sous-programmes se fait en C l'aide des


fonctions

2011/2012 Pr. Ben Mamoun 113


Fonctions
On dfinit une fonction en dehors de la fonction principale main ( ) par :
type nom_fonction (type1 arg1,, typeN argN)
{
instructions constituant le corps de la fonction
return (expression)
}
Dans la premire ligne (appele en-tte de la fonction) :
type est le type du rsultat retourn. Si la fonction na pas de rsultat
retourner, elle est de type void.
le choix d'un nom de fonction doit respecter les mmes rgles que celles
adoptes pour les noms de variables.
entre parenthses, on spcifie les arguments de la fonction et leurs
types. Si une fonction n'a pas de paramtres, on peut dclarer la liste
des paramtres comme (void) ou simplement comme ()

Pour fournir un rsultat en quittant une fonction, on dispose de la commande


return.
2011/2012 Pr. Ben Mamoun 114
Fonctions : exemples
Une fonction qui calcule la somme Une fonction qui renvoie un
de deux rels x et y : entier saisi au clavier
double Som(double x, double y ) int RenvoieEntier( void )
{
{ int n;
return (x+y); printf (" Entrez n \n");
} scanf (" %d ", &n);
return n;
Une fonction qui affiche la somme de }
Une fonction qui affiche les
deux rels x et y : lments dun tableau dentiers
void AfficheSom(double x, double y) void AfficheTab(int T[ ], int n)
{ { int i;
printf (" %lf", x+y ); for(i=0;i<n;i++)
} printf (" %d \t", T[i]);
}

2011/2012 Pr. Ben Mamoun 115


Appel dune fonction
Lappel d'une fonction se fait par simple criture de son nom avec la liste
des paramtres : nom_fonction (para1,, paraN)
Lors de l'appel d'une fonction, les paramtres sont appels paramtres
effectifs : ils contiennent les valeurs pour effectuer le traitement. Lors de la
dfinition, les paramtres sont appels paramtres formels.
formels
L'ordre et les types des paramtres effectifs doivent correspondre ceux
des paramtres formels

Exemple dappels:
main( )
{ double z;
int A[5] = {1, 2, 3, 4, 5};
z=Som(2.5, 7.3);
AfficheTab(A,5);
}

2011/2012 Pr. Ben Mamoun 116


Dclaration des fonctions
Il est ncessaire pour le compilateur de connatre la dfinition d'une
fonction au moment o elle est appele. Si une fonction est dfinie
aprs son premier appel (en particulier si elle dfinie aprs main ),
elle doit tre dclare auparavant.

La dclaration d'une fonction se fait par son prototype qui indique


les types de ses paramtres et celui de la fonction :
type nom_fonction (type1,, typeN)

Il est interdit en C de dfinir des fonctions l'intrieur d'autres


fonctions. En particulier, on doit dfinir les fonctions soit avant, soit
aprs la fonction principale main.

2011/2012 Pr. Ben Mamoun 117


Dclaration des fonctions : exemple
#include<stdio.h>
float ValeurAbsolue(float); //prototype de la fonction ValeurAbsolue
main( )
{ float x=-5.7,y;
y= ValeurAbsolue(x);
printf("La valeur absolue de %f est : %f \n " , x,y);
}
//Dfinition de la fonction ValeurAbsolue
float ValeurAbsolue(float a)
{
if (a<0) a=-a;
return a;
}

2011/2012 Pr. Ben Mamoun 118


Variables locales et globales
On peut manipuler 2 types de variables dans un programme C : des
variables locales et des variables globales.
globales Elles se distinguent
par ce qu'on appelle leur porte (leur "espace de visibilit", leur
"dure de vie")

Une variable dfinie l'intrieur dune fonction est une variable


locale, elle nest connue qu' l'intrieur de cette fonction. Elle est
locale
cre l'appel de la fonction et dtruite la fin de son excution

Une variable dfinie lextrieur des fonctions est une variable


globale. Elle est dfinie durant toute lapplication et peut tre utilise
globale
et modifie par les diffrentes fonctions du programme.

2011/2012 Pr. Ben Mamoun 119


Variables locales et globales : remarques
Les variables dclares au dbut de la fonction principale main ne
sont pas des variables globales, mais elles sont locales main

Une variable locale cache la variable globale qui a le mme nom

Il faut utiliser autant que possible des variables locales. Ceci permet
d'conomiser la mmoire et d'assurer l'indpendance de la fonction

En C, une variable dclare dans un bloc d'instructions est


uniquement visible l'intrieur de ce bloc. Cest une variable locale
ce bloc, elle cache toutes les variables du mme nom des blocs qui
l'entourent

2011/2012 Pr. Ben Mamoun 120


Variables locales et globales : exemple
#include<stdio.h>
int x = 7;
int f(int);
int g(int);
main( )
{ printf("x = %d\t", x);
{ int x = 6; printf("x = %d\t", x); }
printf("f(%d) = %d\t", x, f(x));
printf("g(%d) = %d\t", x, g(x));
}
int f(int a) { int x = 9; return (a + x); }
int g(int a) { return (a * x); }
Quaffiche ce programme?
x=7 x=6 f(7)=16 g(7) = 49

2011/2012 Pr. Ben Mamoun 121


Variables locales et globales : exemple
#include<stdio.h>
void f(void);
int i;
main( )
{ int k = 5;
i=3; f(); f();
printf("i = %d et k=%d \n", i,k); }
void f(void) { int k = 1;
printf("i = %d et k=%d \n", i,k);
i++;k++;}
Quaffiche ce programme?
i=3 et k=1
i=4 et k=1
i=5 et k=5

2011/2012 Pr. Ben Mamoun 122


Paramtres d'une fonction
Les paramtres servent changer des informations entre la
fonction appelante et la fonction appele. Ils peuvent recevoir des
donnes et stocker des rsultats

Il existe deux modes de transmission de paramtres dans les


langages de programmation :
La transmission par valeur : les valeurs des paramtres effectifs sont
affectes aux paramtres formels correspondants au moment de l'appel
de la fonction ou procdure. Dans ce mode le paramtre effectif ne
subit aucune modification
La transmission par adresse (ou par rfrence) : les adresses des
paramtres effectifs sont transmises la fonction appelante. Dans ce
mode, le paramtre effectif subit les mmes modifications que le
paramtre formel

2011/2012 Pr. Ben Mamoun 123


Transmission des paramtres en C
La transmission des paramtres en C se fait toujours par valeur
Pour effectuer une transmission par adresse en C, on dclare le
paramtre formel de type pointeur et lors d'un appel de la fonction, on
envoie l'adresse et non la valeur du paramtre effectif
Exemple : void Increment (int x, int *y
y)
{ x=x+1;
*y =*y+1; }
main( )
{ int n = 3, m=3;
Increment (n,, &m);
printf(n = %d et m=%d \n", n,m); }
Rsultat :
n=3 et m= 4

2011/2012 Pr. Ben Mamoun 124


Exemples
Une fonction qui change le contenu de deux variables :
void Echange (float *x,
x, float *yy)
{ float z;
z = *x;
*x = *y;
*y = z;
}
main()
{ float a=2,b=5;
Echange(&a,&b);
printf("a=%f,b=%f\\n ",a,b);
printf("a=%f,b=%f
}
2011/2012 Pr. Ben Mamoun 125
Rcursivit
Une fonction qui fait appel elle-mme est une fonction rcursive

Toute fonction rcursive doit possder un cas limite (cas trivial) qui
arrte la rcursivit

Exemple : Calcul du factorielle


int fact (int n )
{ if (n==0) /*cas trivial*/
return (1
1);
else
return (n*
n* fact(n
fact(n--1) );
}
Remarque : lordre de calcul est lordre inverse de lappel de la fonction
2011/2012 Pr. Ben Mamoun 126
Fonctions rcursives : exercice
Ecrivez une fonction rcursive (puis itrative) qui calcule le terme n
de la suite de Fibonacci dfinie par : U(0)=U(1)=1
U(n)=U(n-1)+U(n-2)

int Fib (int n)


{
if (n==0 || n==1)
return (1);
else
return ( Fib(n-1)+Fib(n-2));

2011/2012 Pr. Ben Mamoun 127


Fonctions rcursives : exercice (suite)
Une fonction itrative pour le calcul de la suite de Fibonacci :
int Fib (int n)
{ int i, AvantDernier, Dernier, Nouveau;
if (n==0 || n==1) return (1);
AvantDernier=1; Dernier =1;
for (i=2; i<=n; i++)
{ Nouveau= Dernier+ AvantDernier;
AvantDernier = Dernier;
Dernier = Nouveau;
}
return (Nouveau);
}
Remarque: la solution rcursive est plus facile crire

2011/2012 Pr. Ben Mamoun 128


Chapitre 8

Les Chanes de caractres


Chanes de caractres
Il n'existe pas de type spcial chane ou string en C. Une chane de
caractres est traite comme un tableau de caractres

Une chane de caractres en C est caractrise par le fait que le


dernier lment vaut le caractre \0, ceci permet de dtecter la fin de
la chane

Il existe plusieurs fonctions prdfinies pour le traitement des chanes


de caractres (ou tableaux de caractres )

2011/2012 Pr. Ben Mamoun 130


Dclaration
Syntaxe : char <NomVariable> [<Longueur>]; //tableau de caractres

Exemple : char NOM [15];

Pour une chane de N caractres, on a besoin de N+1 octets en


mmoire (le dernier octet est rserv pour le caractre \0)

Le nom dune chane de caractres est le reprsentant de ladresse


du 1er caractre de la chane

On peut aussi manipuler les chanes de caractres en utilisant des


pointeurs (de la mme faon qu'un pointeur sur int peut contenir l'adresse
d'un lment d'un tableau dentiers, un pointeur sur char peut pointer sur les
lments d'un tableau de caractres)

2011/2012 Pr. Ben Mamoun 131


Initialisation
On peut initialiser une chane de caractres la dfinition :

comme un tableau, par exemple : char ch[ ] = {e,c,o,l,e,\0}


par une chane constante, par exemple : char ch[ ] = "cole
en attribuant l'adresse d'une chane de caractres constante un pointeur
sur char, par exemple : char *ch = "cole

On peut prciser le nombre d'octets rserver condition que celui-


celui-ci
soit suprieur ou gal la longueur de la chane d'initialisation

char ch[ 6] = "cole est valide


char ch[ 4] = "cole ou char ch[ 5] = "cole provoque une erreur

2011/2012 Pr. Ben Mamoun 132


Traitement des chanes de caractres
Le langage C dispose dun ensemble de bibliothques qui contiennent
des fonctions spciales pour le traitement de chanes de caractres

Les principales bibliothques sont :

La bibliothque <stdio.h>

La bibliothque <string.h>

La bibliothque <stdlib.h>

Nous verrons les fonctions les plus utilises de ces bibliothques

2011/2012 Pr. Ben Mamoun 133


Fonctions de la bibliothque <stdio.h>
printf( ) : permet dafficher une chane de caractres en utilisant le
spcificateur de format %s.

Exemple : char ch[ ]= " Bonsoir " ;


printf(" %s ", ch);

puts( <chaine>) : affiche la chane de caractres dsigne par


<Chane> et provoque un retour la ligne.

Exemple : char *ch= " Bonsoir " ;


puts(ch); /*quivalente printf("%s\
printf("%s\n ", ch);*/

2011/2012 Pr. Ben Mamoun 134


Fonctions de la bibliothque <stdio.h>
scanf( ) : permet de saisir une chane de caractres en utilisant le
spcificateur de format %s.

Exemple : char Nom[15];


printf("entrez
"entrez votre nom");
scanf("" %s ", Nom);
Remarque : 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 &

gets( <chaine>) : lit la chane de caractres dsigne par <Chane>

Exemple : char phrase[100];


printf(""entrez une phrase");
");
gets(phrase); );

2011/2012 Pr. Ben Mamoun 135


Fonctions de la bibliothque <string.h>
strlen(ch): fournit la longueur de la chane sans compter le '\0' final
Exemple : char s[ ]= " Test";
Test"
printf(%d,strlen(s));
%d,strlen(s)); //affiche 4

strcat(ch1, ch2) : ajoute ch2 la fin de ch1. Le caractre \\0 de ch1


est cras par le 1er caractre de ch2

Exemple : char ch1[20]="" Bonne ", *ch2="


* " chance ";
strcat(ch1, ch2) ;
printf("" %s", ch1);
ch1); // affiche Bonne chance

2011/2012 Pr. Ben Mamoun 136


Fonctions de la bibliothque <string.h>
strcmp(ch1, ch2): compare ch1 et ch2 lexicographiquement et
retourne une valeur : - nul si ch1 et ch2 sont identiques
- ngative si ch1 prcde ch2
- positive si ch1 suit ch2

strcpy(ch1, ch2) : copie ch2 dans ch1 y compris le caractre \\0

Exemple : char ch[10];;


strcpy(ch, " Bonjour ");
puts(ch
ch);
); // affiche Bonjour
strchr(char *s, char c) : recherche la 1re occurrence du caractre c
dans la chane s et retourne un pointeur sur cette 1re occurrence si
cest un caractre de s, sinon le pointeur NULL

2011/2012 Pr. Ben Mamoun 137


Fonctions de la bibliothque <stdlib.h>
<stdlib> contient des fonctions pour la conversion de nombres en
chanes de caractres et vice-
vice-versa.

atoi(ch): retourne la valeur numrique reprsente par ch comme int


atof(ch): retourne la valeur numrique reprsente par ch comme float
(si aucun caractre nest valide, ces fonctions retournent 0)
Exemple : int x, float y;
char *s= " 123 ", ch[]= " 4.56 ";
x=atoi(s); y=atof(ch); // x=123 et y=4.56

itoa(int n, char * ch, int b) : convertit lentier n en une chane de


caractres qui sera attribu ch. La conversion se fait en base b
Exemple : char ch[30];; int p=18;
itoa(p, ch, 2); // ch= " 10010 ";

2011/2012 Pr. Ben Mamoun 138