Vous êtes sur la page 1sur 136

Rappel et complments de la

programmation en langage C

Qu'est-ce qu'un bon programme?


Un Bon Programme ? ? :
Il doit rsoudre le PROBLEME !
Efficacit Rapidit?

INSTANTANE !

DUREE DE VIE ?

- Lisible
- Structur

Objectifs

tre capable de bien programmer

Comprendre les diffrentes constructions de


la programmation en C

Savoir programmer de manire modulaire

Qualits attendues d'un


programme

Clart
Simplicit
Efficacit
Modularit
Extensibilit
4

Types de base
4 types de base, les autres types seront drivs de ceux-ci.
Type

char

Signification

Exemples de valeur

'a' 'A' 'z' 'Z' '\n' 'a' 'A'


Caractre unique 'z' 'Z' '\n'
Varie de 128 127

Codage en
mmoire

Peut tre

1 octet

signed,
unsigned

int

Nombre entier

0 1 -1 4589 32000
-231 231 +1

float

Nombre rel
simple

0.0 1.0 3.14 5.32


-1.23

4 octets

double

Nombre rel
double prcision

0.0 1.0E10 1.0


-1.34567896

8 octets

2 ou 4 octets

Short, long,
signed,
unsigned

long
5

TYPE de la valeur de retour


"main" : Cela signifie "principale",
ses instructions sont excutes.

int main(void)
{
/* corps du programme*/
begin
declaration des Cstes et Var ;
instruction1 ;
instruction2 ;
.
}
end

void main(void): La fonction main ne prend


aucun paramtre et ne retourne pas de valeur.
int main(void): La fonction main retourne une
valeur entire l'aide de l'instruction return (0
si pas derreur).
int main(int argc, char *argv[]): On obtient
alors des programmes auxquels on peut
adresser des arguments au moment o on lance
le programme.

Entre accolades "{" et "}" on


mettra la succession d'actions
raliser.(Bloc)

Structure d'un programme C


#include <stdio.h>
#define DEBUT -10
#define FIN 10
#define MSG "Programme de dmonstration\n"
int fonc1(int x);
int fonc2(int x);
void main()
{
int i;

Directives du prprocesseur :
accs avant la compilation
Dclaration des fonctions

/* dbut du bloc de la fonction main*/


/* dfinition des variables locales */

i=0;
fonc1(i) ;
fonc2(i) ;
}
int fonc1(int x) {
return x;
}

Programme
principal

/* fin du bloc de la fonction main */

Dfinitions des
fonctions

int fonc2(int x) {
return (x * x);
}
7

Indenter = lisibilt

#include <Lib1.h>
#include <Lib2.h>

Prenez l'habitude de respecter (au moins au dbut) les


rgles :
-

une accolade est seule sur sa ligne,

{ est aligne sur le caractre de gauche de la ligne


prcdente,
-

} est aligne avec l'accolade ouvrante correspondante,

#define X 0;
int fonc1(int x);
float fonc2(char a);
int main(void)
{ /*main*/
instruction;

aprs { , on commence crire deux caractres plus


droite.

instruction;
{

Fonctionnement :
-

instruction;
{

Taper et sauvegarder le programme,


Compiler le programme,
Excuter le programme.

instruction;
}
}
instruction;
} /* fin main*/

Prprocesseur
Le prprocesseur effectue un prtraitement du programme source avant qu'il soit compil.
Ce prprocesseur excute des instructions particulires appeles directives.
Ces directives sont identifies par le caractre # en tte.
Inclusion de fichiers
#include <nom-de-fichier>
#include "nom-de-fichier"
La gestion des fichiers (stdio.h)
Les fonctions mathmatiques (math.h)
Taille des type entiers (limits.h)
Limites des type rels (float.h)
Traitement de chanes de caractres (string.h)
Le traitement de caractres (ctype.h)
Utilitaires gnraux (stdlib.h)
Date et heure (time.h)

/* rpertoire standard */
/* rpertoire courant */

/* Entrees-sorties standard */

1er Programme
#include <stdio.h>
#include <conio.h>
int main(void)
{
printf(" BTS GI ");

getch() ;
return 0;

BTS GI

/* Attente d'une saisie clavier */


/* En principe un code d'erreur nul signifie "pas d'erreur". */

10

La fonction printf() :
Librairie

stdio.h.

#include <stdio.h>

Syntaxe

int printf( const char *format [, arg [, arg]...]);

Description : Permet l'criture formate (l'cran par dfaut).


Exemple :
printf("Qu'il est agreable dutiliser printf "
"en\t C,\nlorsqu'on l'utilise \"proprement\".\n");
Rsultat sur la sortie :
Qu'il est agreable dutiliser printf en
lorsqu'on l'utilise "proprement".

C,

Les caractres prcds de \ sont interprts comme suit :


\\ : caractre \
\n : retour la ligne
\t : tabulateur.
\" : caractre "
\r:retourchariot
11

Les constantes de type caractre ont une valeur entire dans la table ASCII
char c1 = 'A',
c2 = '\x41'; /* reprsentation hexadcimale */

caractres

nom

symbole code hexa

\n

newline

LF

10

\t

tabulation

HT

\b

backspace

BS

\r

return

CR

\f

form feed

FF

12

\\

backslash

5C

92

\'

single quote

27

39

\"

double quote

22

34

dcimal

13

12

La fonction scanf() :
Librairie

stdio.h.

#include <stdio.h>

Syntaxe

int scanf(const char *format [argument, ...]);

Description : Lit partir de stdin (clavier en principe), les diffrents


arguments en appliquant le format spcifi.
Exemple : scanf(" %d", &age); /* lecture de l'ge, on donne l'adresse de age */

Format des paramtres passs en lecture et criture.


"%c" : lecture d'un caractre.
"%d" ou "%i" : entier sign.
"%e" : rel avec un exposant.
"%f" : rel sans exposant.
"%g" : rel avec ou sans exposant suivant les besoins.
"%G" : identique g sauf un E la place de e.
"%o" : le nombre est crit en base 8.
"%s" : chane de caractre.
"%u" : entier non sign.
"%x" ou "%X" : entier base 16 avec respect
majuscule/minuscule.

13

1er Programme
#include <stdio.h>
#include <conio.h>
int main(void)
{

int age;

/*dclaration dune variable*/

printf("Je te souhaite le bon"


"jour aux TP\nEt je t"
"e souhaite bon trav"
"ail\n");

Lutilisation de & est indispensable avec


scanf (valeur lue et donc modifie), pas avec
printf (valeur crite et donc non modifie).

printf("Quel est ton ge? ");


scanf(" %d", &age);
/* lecture de l'ge, on donne l'adresse de age */
printf("\nAlors ton age est de %d ans!\n",age);
getch() ;
return 0;
}

/* Attente d'une saisie clavier */


/* En principe un code d'erreur nul signifie "pas d'erreur". */

Quel est ton ge ? 18


Alors ton age est de 18 ans!
14

Variables : dclarations
Syntaxe :

Type identificateur1, identificateur2, ,. ;

Exemple:

char c1, c2, c3;


int i, j, var_ent;

Variables : initialisations
Les variables doivent tre dclares avant leur utilisation dans un dbut de bloc (juste aprs{),
zone des dclarations:

void main(void)
{
char c;
int i,j, k;
c = 'A';
i = 50;
j =10;
K=10;

est quivalent

void main(void)
{
char c = 'A';
int i=50,j, k;

= oprateur daffectation

j=k=10;

Cette rgle s'applique tous : char, int, float ...

15

!
Exemples
char c1, c2, c3;
scanf(%c%c%c,&c1,&c2,&c3);

scanf
entres
abc

rsultats
c1=a c2=<espace> c3=b

c1=a

scanf( %c %c %c,&c1,&c2,&c3);

c2=b

c3=c

char c;
int i;
float x;
scanf(%2d %5f %c,&i,&x,&c);

12 123.567 r

i=12

x=123.5

c=6

16

Affichages et saisies
Librairie : stdio.h
Fonction

Syntaxe

Description

printf

printf( const char *format [, arg [,


arg]...]);

criture formate
sortie standard

scanf

scanf( const char *format [, arg [,


arg]...]);

Lecture formate
entre standard

putchar

putchar(int c);

crire le caractre c

getchar
getch
puts
gets
sprintf

getchar();
getch();

Lecture d'un caractre

sscanf

sscanf(char *s, char *format,


pointer ...);

<conio.h>

*puts(char *s);
*gets(char *s);
sprintf(char *s, char *format, arg ...);

Ecriture/Lecture d'une
chane de caractres,
termine par \n
Ecrit dans la chane
d'adresse s.
Lit la chane d'adresse s.

17

LES DECLARATIONS DE CONSTANTES


1eremthode:dfinitiond'unsymbolel'aidedeladirectivedecompilation#define.

Exemple:

Syntaxe :
texte(valeur)

#define PI 3.14159
void main()
{
float perimetre,rayon = 8.7;
perimetre = 2*rayon*PI;
....
}
#define identificateur

#define TAILLE
100
#define MAXI (3 * TAILLE + 5)
#define nom_macro(identif_p1 , ... ) texte
#define SOMME(X,Y) X+Y
#define MULTIP(A,B) (A)*(B)

Le compilateur ne rserve pas


de place en mmoire

!
Les identificateurs s'crivent
traditionnellement en
majuscules, mais ce n'est pas
une obligation.

18

LES DECLARATIONS DE CONSTANTES


2ememthode:dclarationd'unevariable,dontlavaleurseraconstantepourtoutleprogramme.

Exemple:
voidmain()
{
constfloatPI=3.14159;
constintJOURS=5;
floatperimetre,rayon=8.7;
perimetre=2*rayon*PI;
....
JOURS=3;
....
}

Le compilateur rservedela
placeenmmoire(ici4octets).

/*ERREUR !*/ Onnepeut


changerlavaleurduneconst.

19

Identificateurs
Les identificateurs nomment les objets C (fonctions, variables ... )
C'est une suite de lettres ou de chiffres.
Le premier caractre est obligatoirement une lettre.
Le caractre _ (soulign) est considr comme une lettre.
Reconnaissance suivant les 31 premiers caractres.

Le C distingue les minuscules des majuscules.


Exemples :
abc, Abc, ABC sont des identificateurs valides et tous diffrents.
Identificateurs valides :
xx
y1
somme_5 _position
Noms surface fin_de_fichier VECTEUR
Identificateurs invalides :
3eme
commence par un chiffre
x#y
caractre non autoris (#)
no-commande caractre non autoris (-)
taux change
caractre non autoris (espace)
20

Un identificateur ne peut pas tre un mot rserv 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

RQ : Les mots rservs du langage C


doivent tre crits en minuscules.
21

Les oprateurs arithmtiques

Le C propose les oprateurs suivants :


+
*
/
%

addition
soustraction
multiplication
division
modulo (reste de la division entire )
% ne peut tre utilis qu'avec des entiers
7/2
7.0/2
7/2.0
7.0/2.0

3
3.5

22

Utiliser des oprateurs arithmtiques


Le compilateur considre le type des oprandes
pour savoir comment effectuer les oprations
k= 5/4 = 1

h = 5.0/4.0 = 1.25

h = 5/4 = 1.0000

void main(void)
{
int
i = 5, j = 4, k;
double f = 5.0, g = 4.0, h;
k = i / j;
h = f / g;
h = i / j;
}
23

Les oprateurs de comparaison

<

plus petit

<=

plus petit ou gal

>
>=
==
!=

plus grand
plus grand ou gal
gal
diffrent

Les oprateurs logiques


&&

et

||

ou (non exclusif)

non

Le type boolen
n'existe pas. Le
rsultat d'une
expression logique
vaut 1 si elle est
vraie et 0 sinon.
Rciproquement,
toute valeur non
!
nulle est considre
comme vraie et la
valeur nulle
comme fausse.

24

Exemple

int i;
float f;
char c;
i = 7;

f = 5.5;

c = 'w';

f>5

====> vrai (1)

(i + f) <= 1
c == 'w
c != 'w'
c >= 10*(i + f)
(i >= 6) && (c == 'w')
(i >= 6) || (c == 119)

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

faux (0)
vrai (1)
faux (0)
faux (0)
vrai (1)
vrai (1)

!expr1 est vrai si expr1 est faux et faux si expr1 est vrai ;
expr1&&expr2 est vrai si les deux expressions expr1 et expr2 sont vraies
et faux sinon. L'expression expr2 n'est value que dans le cas o l'expression
expr1 est vraie ;
expr1 || expr2 = (1) si expr1=(1) ou expr2=(1) et faux sinon.
L'expression expr2 n'est value que dans le cas o l'expression expr1
est fausse.
25

Contractions d'oprateurs

Il y a une famille doprateurs


+= -=
*=
/=
%=
&= |=
^=
<<=>>=

Pour chacun dentre eux


expression1 op= expression2
est quivalent :
(expression1) = (expression1) op (expression2)

aa+=
+=32;
32;
aa==aa++32;
32;

ff/=
/=9.2;
9.2;
ff==ff//9.2;
9.2;

ii*=
*=jj++5;
5;
ii==ii**(j(j++5);
5);
26

Incrment et dcrement

C a deux oprateurs spciaux pour incrmenter (ajouter 1)


et dcrmenter (retirer 1) des variables entires
++
--

increment :
decrement

i++ ou ++i est quivalent i += 1 ou i = i + 1

Ces oprateurs peuvent tre prfixs (avant la variable) ou


postfixs (aprs)
int
int ii==5,5,jj==4;
4;
i vaudra 6
j vaudra 3
i vaudra 7

i++;
i++;
--j;
--j;
++i;
++i;
27

Prfixe et Postfixe
#include <stdio.h>
int main(void)
{
int
i, j = 5;
i = ++j;
printf("i=%d, j=%d\n", i, j);
j = 5;
i = j++;
printf("i=%d, j=%d\n", i, j);
return 0;
}

quivalent :
1. j++;
2. i = j;

quivalent :
1. i = j;
2. j++;

i=6,
i=6,j=6
j=6
i=5,
i=5,j=6
j=6
28

Les Conversions de types


Le langage C permet d'effectuer des oprations de conversion de type.
On utilise pour cela l'oprateur de "cast" ().
#include <stdio.h>
#include <conio.h>
void main()
Conversion float -> int: 89.67 -> 89
{
Conversion int -> float: 4660 -> 4660.00
int i=0x1234, j;
Conversion int -> char: 1234 -> 34
char d,e;
float r=89.67,s;
Conversion float -> char: 89.67 -> 89
j = (int)r;
Pour sortir frapper une touche
s = (float)i;
d = (char)i;
e = (char)r;
printf("Conversion float -> int: %5.2f -> %d\n",r,j);
printf("Conversion int -> float: %d -> %5.2f\n",i,s);
printf("Conversion int -> char: %x -> %x\n",i,d);
printf("Conversion float -> char: %5.2f -> %d\n",r,e);
printf("Pour sortir frapper une touche ");
getch();
// pas getchar
}
29

Les structures de contrle en C


Alternative:

ifelse

Choix Multiple:

switchcase

Itrations:

for,while,dowhile

Rupture de Contrle:
goto

break,continue,return

30

Les structures de contrle en C


Les dcisions - if then else
if (expression boolenne vraie)
{

Pas de then en C
Le bloc " else "
est optionnel.

if (a<b)
{

BLOC 1 D'INSTRUCTIONS

}
else
{

min=a;

}
else
{
BLOC 2 D'INSTRUCTIONS

min=b;

* Tout ce qui est 0 ( \0 0 0.0000 NULL ) est faux


* Tout ce qui est != de 0 ( 1 0 0.0001 1.34 ) est vrai
if(32)
printf("ceci sera toujours affiche\n");
if(0)
printf("ceci ne sera jamais affiche\n");
31

Exemples :
if (i < 10) i++;
La variable i ne sera incrmente que si elle a une valeur infrieure 10.
if (i == 10) i++;
== et pas =
La variable i ne sera incrmente que si elle est gale 10.
if (!recu) printf ("rien reu\n");
Le message "rien reu" est affich si recu vaut zro.
if ((!recu) && (i < 10)) i++;
i ne sera incrmente que si recu vaut zro et i<10.
Si plusieurs instructions, il faut les mettre entre accolades.
if ((!recu) && (i < 10) && (n!=0) ){
i++;
moy = som/n;
printf(" la valeur de i =%d et moy=%f\n", i,moy) ;
}
else {
printf ("erreur \n");
i = i +2;
// i +=2 ;
}

if(delta)

if(!delta)

if(delta!=0)
if(delta==0)

!
32

Attention!

Ne pas confondre = = (oprateur logique dgalit)


et = (oprateur daffectation)
#include <stdio.h>
int
{

main(void)
int

i = 0;

if(i = 0)

/* ici affectation */
printf("i = zero\n");

else
printf(Quand i != de zero\n");
return 0;
}

Quand
Quandii!=
!=de
dezero
zero

33

if embots

else est associ avec le if le plus proche


int i = 100;
if(i > 0)
if(i > 1000)
printf("i > 1000\n");
else
printf("i is reasonable\n"); i is reasonable
i is reasonable
int i = 100;
if(i > 0) {
if(i > 1000)
printf(" i > 1000 \n");
} else
printf("i is negative\n");
34

s)
e
l
uc
o
(B

Les itrations for

for( init ; test; increment)


{
/* corps de for */
}
double angle;

int i,j;

i i==00
i i==11
for (i = 0; i <3; i++) {
printf ( "i = %d\n", i); i i==22
j j==55
}
j j==44
for(j = 5; j > 0; j- -)
printf("j = %d\n", j); j j==33
j j==22
j j==11

for(angle = 0.0; angle < 3.14159; angle += 0.2)


printf("sine of %.1lf is %.2lf\n",angle, sin(angle));

int i, j, k;
for( ; ; )
for(i = 0, j =
{
............; /* bloc d'instructions */
............;
............;
}

2, k = -1; (i < 20) &&(j==2); i++, k--)

est une boucle infinie (rptition infinie du bloc d'instructions).


35

s)
e
l
uc
LA BOUCLE
o
B
(

TANT QUE ... FAIRE ...

Boucle pr-teste

Il s'agit de l'instruction while :


tant que (expression vraie)
faire{BLOC D'INSTRUCTIONS}

tant que, pas jusqu ce que!

Syntaxe en C:

Organigramme:

while (expression)
{

oui

condition
vraie

............;
............;
............;

non

/* bloc d'instructions */

}
Le test se fait d'abord, le bloc d'instructions
n'est pas forcment excut.

bloc d'
instructions

Rq: les {} ne sont pas ncessaires lorsque le


bloc ne comporte qu'une seule instruction.

36

Exemple

itration

i=1;
while(i<5)
{
printf(Intrieur %d\n",i);
i++;
}
printf("Extrieur %d\n",i);

Intrieur
Intrieur
Intrieur
Intrieur
Intrieur
Intrieur
Intrieur
Intrieur
Extrieur
Extrieur

11
22
33
44
55

int
intj j==5;5;

tant que, pas jusqu ce que!

i=1;
while(i<5);
{
printf(Intrieur %d\n",i);
i++;
}

start
start
printf("start\n");
end
printf("start\n");
end
while(j
==
0)
while(j == 0)
printf("j
printf("j==%d\n",
%d\n",j--);
j--);
printf("end\n");
printf("end\n");

"tant que l'expression est vraie


attendre".

37

es
l
c
ou
B
(

do while = REPETER tant que


(guarantit lexcution au moins une fois)
do
{
............; /* bloc d'instructions */
............;
}
while (expression);

blocd'
instructions

oui

condition
vraie

non

suiteduprogramme

int
intjj==5;5;
do
do
printf("j
printf("j==%i\n",
%i\n",j--);
j--);
while(j
while(j>>0);
0);
printf("stop\n");
printf("stop\n");

jj==55
jj==44
jj==33
jj==22
jj==11
stop
stop

i=1;
do
{
printf(i=%d ",i);
i++;
}while(i<0);
printf("stop\n");

ii==11
stop
stop

38

switch = AU CAS OU ... FAIRE ...


switch(variable de type char ou int)
{
case valeur1: ......;
.......;
break;

case valeur2:........;
........;
break;
.
.
.
default: .......;
........;

/* au cas o la variable vaut: */

/* cette valeur1(tiquette): excuter ce bloc d'instructions.*/


/* L'instruction d'chappement break;
permet de quitter la boucle ou l'aiguillage le plus proche.
*/
/* cette valeur2: excuter ce bloc d'instructions.*/

/* etc ...*/
/* aucune des valeurs prcdentes: excuter ce bloc
d'instructions, pas de "break" ici.*/

}
Le bloc "default" n'est pas obligatoire. valeur1, valeur2, . doivent tre des expressions
constantes. Linstruction switch correspond une cascade dinstructions if ...else
39

Cette instruction est commode pour les "menus":


char choix;
printf("SAISIE TAPER 1\n");
printf("AFFICHAGE TAPER 2\n");
printf("POUR SORTIR TAPER S\n");
printf("\nVOTRE CHOIX: ");
choix = getchar();
switch(choix)
{
case '1': .......;
break;

int choix;

float
floatf;f;
scanf(" %d ", &choix);
switch(choix)
{
case 1:

switch(f)
switch(f){{
case
case2:2:
....
....
switch(i)
switch(i){{
case
case22**j:j:
....
....

case '2': ......;


break;
case 'S': printf("\nFIN DU PROGRAMME ....");
break;
default; printf("\nCE CHOIX N'EST PAS PREVU "); /* pas de break ici */
}
40

Instructions
d'chappement
Pour rompre le droulement
squentiel d'une suite d'instructions
Break;

Continue;

int i, j=1;
char a;
for (i = -10; i <= 10; i++){

for (i = -10; i <= 10; i++)


{
if (i == 0)
continue;

while(j!=0) /* boucle infinie */

// pour viter la division par


zro

printf( %f, 1 / i);

{
a=getchar();
if(a= ='x')
break;
}

}
return (expression);
permet de sortir de la fonction qui la contient

}
Si x est tape au clavier

exit (expression);
La fonction est interrompu.
expression : un entier indiquant le code de terminaison
du processus
41

goto tiquette
#include <stdio.h>
void main()
{
int i, j;
for (i=0; i < 10; i++)
for (j=0; j < 4; j++) {
if ( (i*j) == 10)
goto trouve;
printf("i*j != 10.\n");
}
trouve:
printf("i*j =%d * %d = %d== 10.\n",i,j,i*j);
}

42

Tableaux : Introduction
Dclaration de tableaux

Un tableau (array) est une collection de variables de mme type, appeles lments
On les dclare par un type, un nom et une dimension (CONSTANTE) place entre [ ]

Le C alloue toujours un tableau dans une zone contige de la mmoire

Une fois dclar, on ne peut redimensionner un tableau

Exemples
int tab[4]; dclare un tableau de 4 valeurs entires

#define
#define
int
int

SIZE
10
SIZE
10
a[SIZE];
a[SIZE];

tab[0] tab[1] tab[2] tab[3]

/*/*aaest
estun
unvecteur
vecteurde
de10
10entiers
entiers*/*/

le compilateur rserve SIZE places en mmoire pour ranger les lments du tableau.

float
float

A[5]
A[5]

=={{10.1,
10.1,20.3,
20.3,30.5,
30.5,40.0,
40.0,50.4
50.4};};
43

Accs aux lments dun tableau

Les lments sont numrots de 0 dim-1


Il ny a pas de vrification de bornes

void
voidmain(void)
main(void)
{{
int
a[6];
int
a[6];
int
i i==7;7;
int
a[0]
a[0]==59;
59;
a[5]
a[5]==-10;
-10;
a[i/2]
a[i/2]==2;2;

}}

a[6]
a[6]==0;
0;
a[-1]
a[-1]==5;5;

59

?
2

2
3

-10

void
void main(void)
main(void)
{{
int
inti;i;
int
intA[6]
A[6]=={{1,1,2,3,
2,3,5,5,7,7,11
11};};
for
for(i=0;i<6;i++)
(i=0;i<6;i++)
printf("%d
printf("%d",",A[i]);
A[i]);
}}

Les tableaux consomment beaucoup de place mmoire.


On a donc intrt les dimensionner au plus juste.
44

void main()
{
const int N=10;
int t[N],i;
for (i=0;i<N;i++){
printf("Entrez t[%d]=",i);
scanf("%d",&t[i]);
}
}
45

Fonctions en C
Encapsule un traitement particulier formant un tout

Peut implmenter la notion de module en logique

Notion de librairie

Augmente la lisibilit dun programme

Ralise un objectif prcis

Amliore le dbogage et la maintenance dun programme


Son utilisation se dcompose en trois phases :

Dfinition de la fonction

Dclaration de la fonction

Appel de la fonction
Dclarer une fonction
Appeler une fonction
Rgles de visibilit des variables
Passage des paramtres par valeur
Fonction renvoyant une valeur au programme
Passage des paramtres par valeur et par adresse
Passage des tableaux aux fonctions
46

Fonctions en C
Les principes

En C, tout est fonction (Dfinition, Dclaration et Appel).


Une fonction peut avoir autant de paramtres que lon veut, mme
aucun
(comme void main(void))
Une fonction renvoie une valeur ou aucune.
Les variables dclares dans une fonction sont locales cette fonction
Unefonctionpossdeunetunseulpointd'entre,mais
ventuellementplusieurspointsdesortie(l'aidedumotreturn).
L'imbricationdefonctionsn'estpasautorise:

unefonctionnepeutpastredclarel'intrieurd'uneautrefonction.Parcontre,unefonction
peutappeleruneautrefonction.Cettederniredoittredclareavantcellequil'appelle.

47

Dclarer une fonction


TYPE de la valeur de retour

int
{

3 doubles comme paramtres

print_table(double start, double end, double step)


double
int

d;
lines = 1;

Nom de la fonction

printf("Celsius\tFarenheit\n");
for(d = start; d <= end; d += step, lines++)
printf("%.1lf\t%.1lf\n", d, d * 1.8 + 32);
return lines;
}
Valeur renvoye
48

Appeler une fonction


IMPORTANT: cette instruction spcifie comment la fonction est dfinie

#include <stdio.h>
int

print_table(double, double, double);

void main(void)
{
int
combien;
double end = 100.0;

Le compilateur attend des


doubles; les conversions sont
automatiques

combien = print_table(1.0,end,3);
print_table(end, 200, 15);
}
Ici, on ne tient pas compte de la valeur de retour

49

float calculeFloat(float, float);


int addition();
void main(void)
{
int Val ;
Val = addition();
printf(val = %d, Val);
}
int addition()
{
float tmp;
tmp = calcule(2.5,3) + calcule(5,7.2);
return (int)tmp;
}
float calcule(float float1, float float2)
{
return ( (float1 + float2 ) / 2) ;
}
50

Rgles de visibilit des variables


Le C est un language structur en blocs { } , les variables
ne peuvent tre utilises que l o elles sont dclares
void func(int x);
int glo=0;
// variableglobale
void main(void)
{
int
i = 5, j, k = 2; //lacales main
float f = 2.8, g;

Le compilateur ne
connat pas d

d = 3.7;
func (i);
}
void func(int v)
{
double d, e = 0.0, f =v; //lacales func
i++; g--;glo++;
f = 0.0;
}

Le compilateur ne
connat pas i et g
Cest le f local qui est
utilis
51

Passage des paramtres par valeur


* Quand une fonction est appele, ses paramtres sont copis
(passage par valeurs)
* La fonction travaille donc sur des copies des paramtres et
ne peut donc les modifier
* En C, le passage des paramtres par rfrence se fait en
utilisant des pointeurs (voir plus loin)
* scanf() travaille avec pointeur. C'est le pourquoi du &

52

Passage des paramtres par valeur


#include <stdio.h>
void change(int v);
void main(void)
{
int var = 5;
change(var);
printf("main: var = %d\n", var);

change:
change:vv==500
500
main:
main:var
var==55

}
void change(int v)
{
v *= 100;
printf("change: v = %d\n", v);
}
53

FONCTION RENVOYANT UNE VALEUR AU


PROGRAMME
#include <stdio.h>
int

change(int v);

void main(void){
int var = 5;
int valeur;
valeur = change(var);
printf("main: var = %d\n", var);
printf("main: valeur = %d\n", valeur);
}

change:
change:vv==
main:
main:var
var==
main:
main:valeur
valeur==

int change(int v)
{
v *= 100;
printf("change: v = %d\n", v);
return (v+1);
}
54

Une fonction se termine et rend la main au code appelant lorsque son


excution rencontre linstruction : return expression; ou return;
#include <stdio.h>
int return_Val(int v);
void main(void){
int var = 5;
int valeur;
valeur = return_Val(var);
printf("main: var = %d\n", var);
printf("main: valeur = %d\n", valeur);
}

return_Val
return_Val::rien
rien

main:
main:var
var==
main:
main:valeur
valeur==

int return_Val(int v)
{
if (v == 10)
return (2*v);
else
return (3*v);
}

55

int max (int a, int b) {


if (a > b)

return a ;

else return b ;
}
int min (int a, int b) {
if (a < b)

return a ;

else return b ;
}
int difference (int a, int b, int c) {
return (max (a, max(b,c)) - min (a, min (b, c))) ;
}
void main ()
{
printf ("%d", difference (10, 4, 7)) ;
}
56

Une fonction est dite rcursive, ds lors ou elle se fait appel pour
calculer une sous partie de la valeur finale qu'elle retournera.
#include <stdio.h>
int fact(int n);
int return_Val(int v);
void main(void){
int var = 5, int valeur;
valeur = return_Val(var);
printf("main: var = %d\n", var);
printf("main: valeur = %d\n", valeur);
}
int fact(int n) {
return (n<2?1:((int)n*fact(n-1));
}
int return_Val(int v)
{
if (v == 10)
return (2*v);
else
return fact(v);
}

return_Val
return_Val::rien
rien

main:
main:var
var==
main:
main:valeur
valeur==

(0)=0*fact(-1)
int temp=1;
while(n>1) temp*=n--;

57

Loprateur ternaire ?:

return(n<2?1:((int)n*fact(n-1));
Cet oprateur scrit: (condition) ? (instruction_1) : (instruction_2)
si la condition est vrifie le bloc instruction_1 est excut, sinon cest le
bloc instruction_2 qui lest.

if (n<2 ) {
return 1;
}
else {
return ((int)n*fact(n-1));
}

return(n<2?1:((int)n*fact(n-1));

58

int fact( int n) {


if (n < 1) return 1;

ti
v
i
s
r
u

else return ( n * fact(n-1) );


}

voidhanoi(intn,inta,
intb){

R
a
L

intc;

if(n==1)move(a,b);
else{
hanoi(n1,a,c);
move(a,b);
hanoi(n1,c,b);
}
}
59

Passer des tableaux aux fonctions

Les tableaux peuvent tre passs comme paramtres d'une fonction.


!
Ils ne peuvent pas tre retourns comme rsultat d'une fonction.
La longueur du tableau ne doit pas tre dfinie la dclaration de la fonction.
Un tableau peut tre modifi dans une fonction. Il est pass par rfrence
(adresse) et non par valeur.
#include
#include<stdio.h>
<stdio.h>
void
void somme(int
somme(intx[],
x[],int
intn);
n);
void
void main(void){
main(void){
int
inti;i;
int
intp[6]
p[6]=={{1,1,2,3,
2,3,5,5,7,7,11
11};};
somme(p,
somme(p,6);
6);
for
for(i=0;i<6;i++)
(i=0;i<6;i++)
printf("%d
printf("%d",",p[i]);
p[i]);
}}
void
void somme(int
somme(inta[],
a[],int
intn){
n){
int
int i;i;
for(i
for(i==n-1;
n-1;i i>0
>0;;i--)
i--)
a[i]
a[i]+=
+=a[i-1];
a[i-1];
}}

p avant somme

p aprs somme

12

11

18

60

Exemple: transposition d'une matrice


void transpose ( float a[][20], int m, int n);
void main(void)
{float matrice [100][20]; /* matrice (100,20) */
/**/
transpose (matrice, 3, 2);
}
void transpose ( float a[][20], int m, int n)
{ int i,j;
float tmp;
for (i=0;i<m;i++)
for(j=0;j<i;j++) {
tmp = a[i][j];
a[i][j]=a[j][i];
a[j][i]=tmp;
}
}
}
61

TP1
crire un programme en C qui range au maximum (taille
Nmax ) 20 nombres entiers saisis au clavier dans un
tableau. Il doit grer en boucle le menu de choix suivant :
ABCDEQ-

Saisie et affichage
Moyenne
Suppression du Max et affichage
Suppression du Min et affichage
Ajout dun entier une position donne
Quitter

62

Le point A sera trait par deux fonctions :


Saisie : la saisie au clavier des entiers et leur rangement dans le tableau.
Dans cette fonction on demandera le nombre dlments (NE<= Nmax) saisire.
Affichage : affichage des donnes.
Le point B sera trait par une fonction :
Moyenne : fonction de calcul de la moyenne du tableau (avec affichage du rsultat).
Le point C sera trait par trois fonctions :
Max_elem : une fonction qui retourne la position du maximum des valeurs du tableau.
Supprimer : supprime le Max du tableau.
Affichage : affichage des donnes.
Le point D sera trait par trois fonctions :
Min_elem : une fonction qui retourne la position du minimum des valeurs du tableau.
Supprimer : supprime le Mix du tableau.
Affichage : affichage des donnes.
Le point E sera trait par deux fonctions :
Ajout : cest une fonction o on demande lutilisateur dintroduire lentier et la
position. Puis vous insrer lentier dans le tableau la position indique.
Affichage : affichage des donnes.
63

Strings

Le C na pas de type string, on utilise donc des tableaux de char.

Un caractre spcial, le caractre null, marque la fin du string ( ne pas


confondre avec le pointeur NULL ).

Ce caractre est not \0, de code ASCII 0 .

Ce caractre est soit ajout automatiquement par le compilateur, soit


introduire par le programmeur, dpendant des fonctions utilises.

char
char

first_name[5]
first_name[5]={
={'J','o','h','n','\0'};
'J','o','h','n','\0'};

'J'

'o'

'h'

'n'

char
char

last_name[6]
last_name[6] ="Minor";
="Minor";

'M' 'i'

'n'

'o'

'r'

char
char

other[]
other[]

'o' 'n'

'y'

32

'B'

'l'

o'

char
char

characters[7]
characters[7]=="No
"Nonull";
null";

'u'

'l'

'l'

=="Tony
"TonyBloot";
Bloot";

'T'

'N'

'o' 32

'n'

o'

't'

Pas de \0
64

Entres/Sorties Standards

lire un caractre sur entre standard (valeur -1 = EOF = fin)


putchar() : crire un caractre sur sortie standard
getchar() :

Exemple: Copie de Input sur Output.


main(){
char c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}

main(){
char c;
while ( (c=getchar())!= EOF)
putchar(c);
}

Fichiers stdin et stdout: Tout programme lit ou crit sur ces fichiers (dfaut clavier et cran).
65

Affichage l'cran des strings

Soit caractre par caractre, avec le format %c ou putchar,


ou, plus simplement, avec le format %s ou puts .

char last_name[6] = "Minor";

Minor

'M' 'i' 'n' 'o' 'r' 0

int i = 0;
last_name[3] = \0;
while(last_name[i] != '\0')
printf("%c", last_name[i++]);
printf("\n");

Min

printf("%s\n", last_name);
puts(last_name);

66

Saisie des strings


chartexte[30];
printf("ENTRERUNTEXTE:");
scanf("%s",texte); //estquivalent gets(texte);

Unechane:pasdesymbole&.Onutiliserade
prfrencelafonctiongetsnonformate.

Si text = un deux entre scanf et gets?

67

RQ:
scanfnepermetpaslasaisied'unechanecomportantdesespaces:
lescaractressaisispartirdel'espacenesontpasprisencompte.
Poursaisirunechanedetype"ilfaitbeau",ilfaututilisergets.
#include <stdio.h>

Affectation de strings :
Les strings peuvent tre
initialiss avec =,
mais pas affects avec =
(ce sont des tableaux!)

#include <string.h>
void main(void) {
char who[] = "Tony Bloot";
who = "John Minor";
strcpy(who, "John Minor");
}
68

Fonctions permettant la manipulation des chanes


string.houstdlib.h

void*strcat(char*chaine1,char*chaine2)

//Concatneles2chanes,rsultatdanschaine1.

void*strcpy(char*chaine1,char*chaine2)

//Copielachaine2danschaine1.+'\0
void *strncpy(char*chaine1,char*chaine2, NCmax)
// idem strcpy mais limite la copie au nombre de caractres NCmax.

intstrcmp(char*chaine1,char*chaine2)

//Compareleschanesdecaractreschaine1etchaine2,

renvoieunnombre:
positifsilachane1estsuprieurelachaine2(ausensdel'ordrealphabtique)
ngatifsilachane1estinfrieurelachane2
nulsileschanessontidentiques.

intstrlen(char*chaine)

//renvoielalongueurdelachaine('\0'noncomptabilis).

int atoi(const char *s)


// convertit l'argument s en un int,
69

Exemple:

#include <string.h>
#include <ctype.h>
#define EOL \n

// toupper

void main(void)
{
int L,i=0;
char s[9] = "midi", u[11] = "avant", v[10] = "soir";
char text[80];
While ( (text[i] = getchar() ) != EOL ) i++;
puts(text);
L = strlen(s);

text[i] = getchar();
while ( text[i] != EOL ) {
i++;
text[i] = getchar();
}

/* L = 4 */

for (i=0;i<L;i++) {
putchar(toupper(s[i]));

/* M, I, D,I */

}
strcat(u,"-");
/* u devient "avant-" */
strcat(u , s);
/* u devient
"avant-midi" */
if (strcmp (u, s) >=0 )
/* "avant-midi" < "midi" */
printf ("il y a une erreur\n");
else {
printf("%s\n", u);
/* avant-midi */
strcpy (u, v);
printf("%s\n", u);
/* soir */
}
}

70

Passage des paramtres par valeur et par adresse


#include<stdio.h>
voidech(intx,inty){
inttampon;
tampon=x;
x=y;
y=tampon;
}
voidmain(){
inta=5,b=8;
ech(a,b);
printf(a=%d\n,a);
printf(b=%d\n,b);
}

PASSAGEDESPARAMETRES

PARVALEUR

aetb:variableslocalesmain().La
fonctionechnepeutdoncpasmodifier
leurvaleur.Onlefaitdoncenpassantpar
l'adressedecesvariables.

a=5
b=8

Syntaxequiconduituneerreur

71

Les Pointeurs en C

La dclaration de pointeurs
Valeurs pointes et adresses
Passage de paramtres de fonction par rfrence
Pointeurs et tableaux

72

Les pointeurs, c'est quoi?

Un pointeur est une variable particulire, dont la


valeur est l'adresse d'une autre variable.
Pointeur p: valeur 5A0F3 (adresse hexadcimale)
Adresse 5A0F3: valeur 17 (correspondant la
valeur d'un entier i)

En accdant cette adresse, on peut accder indirectement la variable et donc la modifier.

i=17
p=5A0F3

5A0F3

17

Un pointeur est une adresse mmoire. On dit que le


pointeur p pointe vers i, puisque p pointe vers
lemplacement mmoire o est enregistre i.
73

Les pointeurs: pourquoi ?

Les pointeurs sont ncessaires pour:

effectuer les appels par rfrence (i.e. crire des


fonctions qui modifient certains de leurs paramtres)

manipuler des structures de donnes dynamiques (liste,


pile, arbre,)

allouer dynamiquement de la place mmoire

74

Dclaration de Pointeurs
Le symbole * est utilis entre le type et le nom du pointeur
Dclaration dun entier:
int
i;i;
int
Dclaration dun pointeur vers un entier:

int
int

*p;
*p;

Exemples de dclarations de pointeurs


int
int*pi;
*pi;
float
float*pf;
*pf;

/*/* pipiest
estun
unpointeur
pointeurvers
versun
unint
int
*pi
*pidsignelecontenudel'adresse
dsignelecontenudel'adresse*/*/
/*/*pfpfest
estun
unpointeur
pointeurvers
versun
unfloat
float*/*/

char
charc,c,d,d,*pc;
*pc;

/*/*ccetetddsont
sontdes
deschar*/
char*/
/*/*pc
pcest
estun
unpointeur
pointeurvers
versun
unchar
char*/*/
double
double*pd,
*pd,e,e,f;f; /*/*pd
pdest
estun
unpointeur
pointeurvers
versun
undouble*/
double*/
/*/*eeetetffsont
sontdes
desdoubles
doubles*/*/
double
double**tab;
**tab; /*/*tab
tabest
estun
unpointeur
pointeurpointant
pointantsur
surun
unpointeur
pointeurqui
qui
pointe
pointesur
surun
unflottant
flottantdouble
double*/*/
75

Oprateurs unaires pour manipuler les pointeurs,


& (adresse de) et * (contenu)
Exemple: int i = 8;
printf("VOICI i: %d\n",i);
printf("VOICI SON ADRESSE EN HEXADECIMAL: %p\n",&i);

void
{

nom_de_Pointeur = &nom_de_variable
cp.
c
r
u
s
e
i nt
o
'a'
0x1132
p
c

main(void)
char
char

c = 'a', d = 'z';
on
d
;
c
e
*p;
d
se
s
e
r
l'ad
t
i
reo
*p = c;
p = &c;
printf("%c\n", *p);
p = &d;
}

printf("%c\n", *p);

0x1132

p
0x91A2

d
'z'
0x91A2

Loprateur * (valeur pointe par)


aa
zz
76

#include <stdio.h>
void main() {
int *p, x, y;
p = &x;

/* p pointe sur x */

x = 10;

/* x vaut 10 */

y = *p - 1;

printf(" y= *p - 1 =? = %d\n" , y);

y vaut ?

*p += 1;

printf(" *p += 1 =? *p = x= ? = %d %d\n" , *p, x);

x vaut ?

(*p)++;
y);

printf(" (*p)++ =? *p = x= ? = %d %d alors y=%d \n" , *p, x,

*p=0;

printf(" *p=0 x=? = %d\n"


comme, x);
p pointe sur x, maintenant x vaut ?

incrmente aussi de 1 la variable pointe par p, donc x vaut ??.


y vaut 9

*p++; *p=20; printf(" *p++ x=? =


%d\n"p ,ne
x);pointe plus sur x, x vaut tjr ?
comme
}

77

Utiliser des pointeurs

long
long

On peut donc accder aux lments par pointeurs en


faisant des calculs dadresses (addition ou soustraction)
v[6] = { 1,2,
3,4,5,6 };
*p;

p = v;
printf("%ld\n", *p);
p++;
printf("%ld\n", *p);
p += 4;
printf("%ld\n", *p);

p += 4

p++
11
22
66

p
1000

1016
1000
1008
1012
1020
1004

78

* et ++
*p++ signifie:
*p++ trouver la valeur pointe
*p++ passer ladresse suivante
(*p)++ signifie:
(*p)++ trouver la valeur pointe
(*p)++ incrmenter cette valeur (sans
changer le pointeur)
*++p signifie:
*++p incrmenter dabord le pointeur
*++p trouver la valeur pointe

79

Passage des paramtres par valeur et par adresse


Syntaxequiconduituneerreur:
#include<stdio.h>
voidech(intx,inty)
{
inttampon;
tampon=x;
x=y;
y=tampon;
}

voidmain()
{
inta=5,b=8;
ech(a,b);
printf(a=%d\n,a); a=?
printf(b=%d\n,b);
b=?
}
PASSAGEDESPARAMETRES

PARVALEUR

Syntaxecorrecte:

aetb:
variables
locales
main().La
fonctionech
nepeutdonc
pasmodifier
leurvaleur.
Onlefait
doncen
passantpar
l'adressede
cesvariables.

#include<stdio.h>
voidech(int*x,int*y)
{
inttampon;
tampon=*x;
*x=*y;
*y=tampon;
}

voidmain()
{
inta=5,b=8;
ech(&a,&b);

printf(a=%d\n,a);
printf(b=%d\n,b);
}
PASSAGEDESPARAMETRES

a=?
b=?

PARADRESSE

80

Passage de paramtres de fonction


par rfrence ou adresse

Quand on veut modifier la valeur d'un paramtre dans une


fonction, il faut passer ce paramtre par rfrence ou adresse

En C, cela se fait par pointeur

void change ( int *a, int *b)


{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
81

Appel des fonctions par rfrence


#include
#include<stdio.h>
<stdio.h>
void
void change(int*
change(int*p);
p);
void
void main(void)
main(void)
{{
int
intvar
var==5;5;
change(&var);
change(&var);
printf("main:
printf("main:var
var==%d\n",var);
%d\n",var);
}}
void
void change(int*
change(int*p)
p)
{{
*p
*p*=
*=100;
100;
printf("change:
printf("change:*p
*p==%d\n",*p);
%d\n",*p);
}}

change:
change:*p
*p==500
500
main:
main:var
var==500
500

82

#include <stdio.h>
void somme(int , int , int *);
int modif(int , int *, int *);
void main(){
int a, b, c;
a = 2; b = 8;
somme(a, b, &c);

Somme de a=? et b=? :

printf("Somme de a=%d et b=%d : %d\n",a, b, c);


a = modif(a, &b, &c);
printf(" Modif : a=%d , b=%d et c= %d\n",a, b, c);
}
void somme(int x, int y, int *z){

Modif : a=?, b=? et c=

*z = x + y;
}
int modif(int x, int *y, int *z){
x *= 2;

*y= x+ *y; *z= 5;

return x;
}

83

Identification des tableaux et pointeurs

En C, le nom dun tableau reprsente ladresse de sa


composante 0, donc
a == &a[0]

C'est pour cela que les tableaux passs comme paramtres


dans une fonction sont modifiables

Passer des tableaux aux fonctions

Pour le compilateur, un tableau comme argument de fonction,


cest un pointeur vers sa composante 0 ( la rservation mmoire prs).
La fonction peut donc modifier nimporte quel lment (passage
par rfrence)
Le paramtre peut soit tre dclar comme tableau, soit comme
pointeur
int add_elements(int a[], int size)
{

int add_elements(int *p, int size)


{
84

Exemple
#include <stdio.h>
void sum(long [], int);
int
main(void)
{
long Tab[6] = { 1, 2,
3, 5, 7, 11 };
sum(Tab, 6);
printf("%ld\n", Tab[0]);
return 0;
}

Tab

Tab
1

29

11

11

void
{

sum(long a[], int sz)


int
i;
long total = 0;
for(i = 0; i < sz; i++)
total += a[i];
a[0] = total;

sz

}
85

Utiliser des pointeurs - exemple


#include <stdio.h>
long

sum(long*, int);

int
{

main(void)
long

Tab[6] = { 1, 2,
3, 5, 7, 11 };

printf("%ld\n", sum(Tab, 6));


return 0;
}
long
{

sum(long *p, int sz)


long
long

*end = p + sz;
total = 0;

while(p < end)


total += *p++;

Tab

Tab
1

1000

1004

1008

1012

1016

11

1020

11

1024
p
1000
end

1024

return total;
}
86

Quelle notation?

A[0] est quivalent *A


A[i] est quivalent *(A + i)
&A[0] est quivalent A

short
short a[8]
a[8]=={{10,
10,20,
20,30,
30,40,
40,50,
50,60,
60,70,
70,80
80};};
short
short *p
*p==a;
a;
printf("%d\n",
printf("%d\n",a[3]);
a[3]);
printf("%d\n",
printf("%d\n",*(a
*(a++3));
3));
printf("%d\n",
printf("%d\n",*(p
*(p++3));
3));
printf("%d\n",
printf("%d\n",p[3]);
p[3]);
p

40
40
40
40
40
40
40
40

1000

10
1000

20 30 40 50 60 70 80
1002

1004

1008
1012
1006
1010
1014
87

SCANF
Pour saisir un caractre ou un nombre
char c;
float Tab[10], X[5][7]; // *Tab,(*X)[7]
printf("TAPER UNE LETTRE: ");
scanf("%c",&c);
scanf("%f",&Tab[5]);
On saisit ici le contenu de l'adresse &c c'est--dire le caractre
c lui-mme.
pointeur
char *adr;
printf("TAPER UNE LETTRE: ");
scanf("%c",adr);
On saisit ici le contenu de l'adresse adr.
88

float x[dim]; rserve un espace de stockage pour dim lments


x[0] stocke l'adresse du premier lment.
#include <stdio.h>
#include <stdlib.h>

float *x; ne rserve que le seul


espace destin au pointeur x,
AUCUN espace n'est rserv
pour une ou plusieurs variables.

void main()
{
char*texte;
float *adr1,*adr2;

adr1 = (float*)malloc(4*sizeof(float));
La rservation d'espace est la
charge du programmeur qui doit
le faire de faon explicite, en
utilisant les fonctions standard
malloc(), qui sont
prototypes dans <stdlib.h> et
<alloc.h>

adr2 = (float*)malloc(10*sizeof(float));
texte=(char*)malloc(10);
*adr1 = -37.28;
*adr2 = 123.67;
printf("adr1 = %p adr2 = %p r1 = %f
r2 = %f\n",adr1,adr2,*adr1,*adr2);
free(adr1); // Libration de la mmoire
free(adr2);
free(texte);
}
89

sizeof
void main()
{
int i;
char c;
float f;
double d;
printf (caractre : %d \n , sizeof c);
printf (entier : %d \n , sizeof i);

caractre : 1
entier : 2 ou 4
rel : 4
double : 8

printf (rel : %d \n , sizeof f);


printf (double : %d \n , sizeof d);
}

90

EXP : Cration dun tableau de taille quelconque


#include <stdio.h>
#include <stdlib.h>

// pour la fonction printf()


// pour la fonction malloc()

void main(){
int i , dim;
long* tableau;

// compteur et taille du tableau


// pointeur pour stocker ladresse du tableau

scanf (%d, &dim);


// saisie par l'utilisateur de la taille du tableau
tableau = (long*) malloc(dim * sizeof(long)); //allocation (dynamique) du tableau
//

remplissage du tableau, on utilise les indices 0 (dim -1)

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


tableau[i] = i;
//

affichage du contenu du tableau

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


printf("%ld\n", tableau[i]);
//

destruction du tableau : libration de la mmoire rserve

free(tableau);
}
91

La mmoire dynamique varie en cours d'excution, et peut n'tre pas


suffisante pour allouer les variables, provoquant le plantage du programme.
Il faut donc tester le retour des fonctions d'allocation et traiter les erreurs.
Exemple:
#define BUFSIZE 100
long *var;

if ( ! var = (long *) malloc(BUFSIZE * sizeof(long)) )


// Si chec de rservation de BUFSIZE emplacement de type long ( ) 0
{
fprintf(stderr, "ERREUR espace mmoire insuffisant !\n");
exit (1); // fin anticipe du programme ; code de retour 1
}
else {
// le programme continue
}

L'espace allou doit tre libr par free(), dont l'argument


est un pointeur rserv dynamiquement. free(var);
92

char * malloc( unsigned taille);


rserve taille octets, sans initialisation de l'espace. Retourne un pointeur sur
une zone de taille octets.
char * calloc( unsigned nombre, unsigned taille);
rserve nombre lments de taille octets chacun ; l'espace est initialis 0.
#define alloue(nb,type) (type *)calloc(nb,sizeof(type))
char *s;
s = alloue(250,char);
// rserve 250 octets initialiss '\0'
void * realloc( void *block, unsigned taille);
modifie la taille affecte au bloc de mmoire fourni par un prcdent appel
malloc() ou calloc().
void free( void *block);
libre le bloc mmoire point par un prcdent appel malloc(), calloc() ou
realloc().
Valable pour rserver de l'espace pour les autres types de donnes int, float,
Elles retournent le pointeur NULL (0) si l'espace disponible est insuffisant.
93

Structures en C

Concepts
Crer un type de structure
Crer une instance de structure
Initialiser une instance
Accder aux membres dune instance
Passer les structures comme paramtres
Listes chanes

94

Concepts

Une structure est une collection de plusieurs variables (champs) groupes


ensemble pour un traitement commode
Les variables dune structure sont appeles membres et peuvent tre de
nimporte quel type, par exemple des tableaux, des pointeurs ou dautres
structures

Les tapes sont:


dclarer

struct
structMembre
Membre
{{
char
char nom[80];
nom[80];
char
char adresse[200];
adresse[200];
int
*numero;
int
*numero;
float
float amende[10];
amende[10];
};};

le type de la structure
utiliser ce type pour crer autant dinstances que
dsires
Accder les membres des instances
95

Dclarer les structures

Les structures sont dfinies en utilisant


le mot-cl struct
struct
structMembre
Membre

struct
structDate
Date
{{
int
int jour;
jour;
int
int mois;
mois;
int
int an;
an;
};};
struct
structLivre
Livre
{{
char
char titre[80];
titre[80];
char
char auteur[80];
auteur[80];
float
float prix;
prix;
};};

{{

};};

char
nom[80];
char
nom[80];
char
adresse[200];
char
adresse[200];
int
numero;
int
numero;
float
amende[10];
float
amende[10];
struct
struct Date
Date emprunt;
emprunt;
struct
struct Date
Date creation;
creation;

struct
structPret
Pret
{{
struct
struct
struct
struct
struct
struct
};};

Livre
Livre b;b;
Date
Date due;
due;
Membre
Membre *who;
*who;

96

Dclarer des instances

Une fois la structure dfinie, les


instances peuvent tre dclares
Par abus de langage, on appellera
structure une instance de structure
struct
structDate
Date
{{
int
int jour;
jour;
int
int mois;
mois;
int
int an;
an;
}}hier,
hier,demain;
demain;

Dclaration
avant ; .

struct
structDate
Datepaques;
paques;
struct
structDate
Datesemaine
semaine[7]
[7];;
struct
structDate
Datenouvel_an
nouvel_an=={{1,1,1,1,2001
2001};};

Initialisation .
97

Des structures dans des structures


struct
structDate
Date
{{
int
int jour;
jour;
int
int mois;
mois;
int
int an;
an;
};};

struct
structMembre
Membre
{{
char
char
char
char
int
int
float
float
struct
struct Date
Date
struct
Date
struct
Date
};};

nom[80];
nom[80];
adresse[200];
adresse[200];
numero;
numero;
amende[10];
amende[10];
emprunt;
emprunt;
creation;
creation;
struct
mm=={{
structMembre
Membre
"Arthur
"ArthurDupont",
Dupont",
rue
de
Houdain,
rue de Houdain,9,9,7000
7000Mons",
Mons",
42,
42,
{{0.0
0.0},},
{{0,0,0,0,00},},
{{5,5, 2,2,2001
2001}}
};};
98

Accder aux membres dune


structure

Les membres sont accds par le nom de linstance,


suivi de . , suivi du nom du membre
struct
structMembre
Membre m;
m;
printf("nom = %s\n", m.nom);
printf(numro de membre = %d\n", m.numero);
printf(amendes: ");
for(i = 0; (i < 10) && (m.amende[i] > 0.0); i++)
printf("%.2f Euros", m.amende[i]);
printf("\nDate demprunt %d/%d/%d\n", m.emprunt.jour,
m.emprunt.mois, m.emprunt.an);
99

Diffrence entre tableaux et


structures
Arrays

Structures

Nom
lment 0

pointeur

La structure

passage aux fonctions

pointeur

valeur /pointeur

retour de fonctions

interdit

valeur /pointeur

assignation

interdit

possible

100

Assignation des structures

Lopration daffectation = peut se faire avec


des structures
Tous les membres de la structure sont copis
(aussi les tableaux et les sous-structures)
struct
structMembre
Membre m
m=={{
"Arthur
"ArthurDupont",
Dupont",
.....
.....
};};
struct
structMembre
Membretemp;
temp;

temp
temp==m;
m;
101

Passer des structures comme


paramtres de fonction

Une structure peut tre passe, comme une autre


variable, par valeur ou par adresse
Passer par valeur nest pas toujours efficace
(recopiage lentre)
Passer par adresse ne ncessite pas de recopiage
void
void
void
void

Par_valeur(struct
Par_valeur(struct Membre
Membrem);
m);
Par_reference(struct
Par_reference(struct Membre
Membre*m);
*m);

Par_valeur(m);
Par_valeur(m);
Par_reference(&m);
Par_reference(&m);
102

Quand la structure est un pointeur !


Utiliser p->name
!

Lcriture p->name est synonyme de (*p)->name,


o p est un pointeur vers une structure
void
void affiche_membre
affiche_membre(struct
(structMembre
Membre*p)
*p)
{{
printf("nom
printf("nom==%s\n",
%s\n",p->nom);
p->nom);
printf("adresse
printf("adresse==%s\n",
%s\n",p->adresse);
p->adresse);
printf(numro
printf(numrode
demembre
membre==%d\n",
%d\n",p->numero);
p->numero);

}}

printf("\nDate
printf("\nDatedaffiliation
daffiliation%d/%d/%d\n",
%d/%d/%d\n",
p->creation.jour,
p->creation.jour,p->creation.mois,
p->creation.mois,p->creation.an);
p->creation.an);
103

Retour de structures dans une fonction

Par valeur (recopiage) ou par rfrence

struct
structComplex
Complex add(struct
add(structComplex
Complexa,a,struct
structComplex
Complexb)
b)
{{

}}

struct
structComplex
Complex result
result==a;a;
result.real_part
result.real_part +=
+=b.real_part;
b.real_part;
result.imag_part
+=
b.imag_part;
result.imag_part += b.imag_part;

return
returnresult;
result;
struct
structComplex
Complex
struct
structComplex
Complex
struct
structComplex
Complex

c1
c1=={{1.0,
1.0,1.1
1.1};};
c2
c2=={{2.0,
2.0,2.1
2.1};};
c3;
c3;

c3
c3==add(c1,
add(c1,c2);
c2); /*/*c3
c3==c1
c1++c2
c2*/*/
104

TP
Enonc
Ecrire un programme permettant de :
Constituer un tableau de 20 Enseignants max(NE_max). La structure est la suivante :

struct {
char nom_pren[40];
// nom+pren
char nom[20];
char pren[20];
int NH[NM_max] ;
// NM_max=3 : nbre dheures pr NM_max matires
}
Le programme doit grer en boucle le menu de choix suivant:
12345-

Saisie et affichage
Construction et affichage
Modifier et affichage
Tri et affichage
Quitter
105

Tri bulles
while(???){
for j = 0 to . {
if tab[j] > tab[j+1] {
<on change tab[j] et tab[j+1]>
}
}
}

1
3

1
2

6
6
6
6

2
4
4
4

2
8
8

12 13

6
0

j
tab[j]

tab[j] < tab[j+1]


2
12
1
2

13

0
106

Gestion des fichiers en C


Elle est assure par la librairie standard <stdio.h> via un
ensemble de fonctions commenant par f

Avant de manipuler un fichier, il faut lui associer un


descripteur (pointeur vers la structure fichier)
Il y a 3 descripteurs automatiquement ouvert par tout
programme C, stdin, stdout et stderr
stdin (standard input) est connect au clavier. On peut y
lire
stdout (standard output) et stderr (standard error) sont
relis au moniteur. On peut y crire.

FILE *f;
/*dclare un descripteur f de fichier*/
107

Ouvrir et fermer des fichiers


Les fichiers sont ouverts avec la fonction fopen
ils sont ferms avec la fonction fclose
FILE*
FILE*fopen(const
fopen(constchar*
char*name,
name,const
constchar*
char*mode);
mode);
int
intfclose
fclose(FILE
(FILE*f);
*f); #include <stdio.h>
#include <stdio.h>
void
voidmain(void)
main(void)
{{

FILE*
FILE*
FILE*
FILE*
FILE*
FILE*

in;
in;

out;
out;
append;
append;

in
in==fopen("autoexec.bat",
fopen("autoexec.bat","r");
"r");
out
out==fopen("autoexec.bak",
fopen("autoexec.bak","w");
"w");
append
=
fopen("config.sys",
append = fopen("config.sys","a");
"a");
/*/*
*/
*/

fclose(in);
fclose(in);
}}

fclose(out);
fclose(out);
fclose(append);
fclose(append);
108

Lecture et criture sur fichier


Fonctions de lecture
int
int
int
int
char*
char*

fscanf(FILE*
fscanf(FILE*stream,
stream,const
constchar*
char*format,
format,...);
...);
fgetc(FILE*
fgetc(FILE*stream);
stream);
fgets(char*
fgets(char*buffer,
buffer,int
intsize,
size,FILE*
FILE*stream);
stream);

Fonctions dcriture
int
int
int
int
int
int

fprintf(FILE*
fprintf(FILE*stream,
stream,const
constchar*
char*format,
format,...);
...);
fputc(int
fputc(intch,
ch,FILE*
FILE*stream);
stream);
fputs(const
fputs(constchar*
char*buffer,
buffer,FILE*
FILE*stream);
stream);

int feof(FILE *f); /*renvoie une valeur non nulle si fin de fichier*/
109

Exemple dcriture (lecture) de fichier


#include <stdio.h>
void sauvegarde( char titre[], int n,
float x[], int ind [] )
{
int i=0;
FILE *f;

f = fopen(monfichier.dat,w);

if (f !=NULL){

FILE *f;
f = fopen(monfichier.dat,r);
if (f!= NULL) {
fgets(titre,80,f);
while(!feof(f)) {
fscanf(f,%f %d,&x[i],&ind[i]);
i++;
}
}

fprintf(f,%s\n,titre);
for (i=0; i < n; i++ ) {
fprintf(f,%f %d\n, x[i],ind[i]);
}
Mon titre

fclose(f);
}

#include <stdio.h>
void main(void)
{
char titre[81];
float x[10];
int ind[10], i=0;

3.0 1
4.5 2

fclose(f);
}

7.3 3
La constante NULL (dfinie comme 0 dans stdio.h) rfre une adresse non dfinie
110

Compilation Spare et dition de Lien


Un programme C est un ensemble de fonctions dans un ou plusieurs fichiers.
Fichier PP.c
main(){

appelle f()

}
f(){
appelle g()
}
g(){

}
Cas I

Fichier PP.c

Fichier SP.c

main(){

appelle f()

}
f(){
appelle g()
}

g(){

Cas II

111

Structure d'un programme C


#include <stdio.h>
#define DEBUT -10
#define FIN 10
#define MSG "Programme de dmonstration\n"
int fonc1(int x);
int fonc2(int x);
void main()
{
int i;

Directives du prprocesseur :
accs avant la compilation
Dclaration des fonctions

/* dbut du bloc de la fonction main*/


/* dfinition des variables locales */

i=0;
fonc1(i) ;
fonc2(i) ;
}
int fonc1(int x) {
return x;
}

Programme
principal

/* fin du bloc de la fonction main */

Dfinitions des
fonctions

int fonc2(int x) {
return (x * x);
}
112

Structure d'un programme C


#include <stdio.h>
#define DEBUT -10
#define FIN 10
#define MSG "Programme de dmonstration\n"
int fonc1(int x);
int fonc2(int x);

Fichier.h

#include Fichier.h
void main()
{
int i;

/* dbut du bloc de la fonction main*/


/* dfinition des variables locales */

i=0;
fonc1(i) ;
fonc2(i) ;
}
int fonc1(int x) {
return x;
}
int fonc2(int x) {
return (x * x);
}

Programme
principal

/* fin du bloc de la fonction main */

Dfinitions des
fonctions

113

MANIPULATIONDESFICHIERS

Rgles de visibilit des variables


Les variables ne peuvent tre utilises que l o elles sont dclares
double func(int x);
int glob=0;

// variableglobale

void main(void)
{
int
i = 5, j, k = 2; //lacales main
glob++;
func (i);
func (k);
}
double func(int v)
{
double d, f =v;
glob++;
f += glob;
return f;
}

//lacales func

#include <stdio.h>
int next(){
static value = 0;
return value++;
}
void main(void) {
printf("Appel 1 :
%d\n",next());
printf("Appel 2 :
%d\n",next());
}

Appel 1 :
0
114

Variables et fonctions externes


Le fichier impose lui aussi un domaine de visibilit. Une variable dfinie globale au fichier
(en dehors de toute fonction) ne sera alors visible que par les fonctions de ce fichier. Le
problme est de savoir comment exporter cette variable pour dautres fonctions du
programme (externes au module) si le besoin sen fait ressentir ?

Fichier "Module.h"

Fichier "Module.c"

extern int a;

#include "module.h"

void fct();

int a = 0;
void fct() { a++; }

Fichier "main.c"
#include <stdio.h>
#include "module.h"
void main(void) {
fct();
a++;
printf("%d\n",a);
}

// Rsultat affich : 2
115

Directives de compilation
Les directives de compilation permettent d'inclure ou d'exclure du programme des
portions de texte selon l'valuation de la condition de compilation.

#ifdefined(symbole)/* inclusion si symbole est dfini */


#ifdef(symbole)/* idem que #if defined */
#ifndef(symbole)/* inclusion si symbole non dfini */
#if (condition)
#else
#elif
#endif
#undef symbole

/* inclusion si condition vrifie */


/* sinon */
/* else if */
/* fin de si */
/* supprime une dfinition */

116

Exemple :
#ifndef (BOOL)
#define BOOL char
#endif
#ifdef (BOOL)
BOOL FALSE = 0;
BOOL TRUE = 1;
#else
#define FALSE 0
#define TRUE 1
#endif

/* type boolean */

/* type boolean */
/* dfinis comme des variables */
/* dfinis comme des macros */
Utile pour les fichiers include.
#ifndef _STDIO_H_
#define _STDIO_H_
texte a compiler une fois

#endif
117

Listes chanes
Une liste est une structure de donnes constitue de cellules
chanes les unes aux autres par pointeurs.
Une liste simplement chane : une cellule est un
enregistrement qui peut tre dclare comme suit:
struct
structNode
Node{{
int
int
struct
structNode
Node
};};

data;
data;
*next;
*next;

/*/*les
lesinformations
informations*/*/
/*/*lelelien
lien*/*/

Une liste doublement chane


struct
structNode
Node{{
int
int
struct
structNode
Node
struct
structNode
Node
};};

data;
data;
*next;
*next;
*prev;
*prev;

/*/*les
lesinformations
informations*/*/
/*/*lien
lienvers
verslelesuivant
suivant*/*/
/*/*lien
lienvers
versleleprcdent
prcdent*/*/
118

Structures de donnes dynamiques


typedef : mot rserv,
cre de nouveaux noms
de types de donnes
Ex :
typedefchar*
STRING;
fait de STRING un synonyme
de "char *
Porte:commelesvariables.

typedefstruct
typedefstructNode
Node{{
int
data;
int
data;
struct
structNode
Node *next;
*next;
}cellule;
}cellule;
cellule
cellule**new_node(int
new_node(intvalue)
value)
{{
cellule
cellule**p;
p;
pp==(cellule
(cellule*)malloc(sizeof(cellule));
*)malloc(sizeof(cellule));
p->data
p->data==value;
value;
p->next
p->next==NULL;
NULL;

p=new struct Node;

}}

return
returnp;
p;
119

Nouvelle cellule dans une liste chane vide


cellule
cellule*debut;
*debut;
debut
debut==(cellule
(cellule*)
*)malloc
malloc(sizeof(cellule));
(sizeof(cellule));
strcpy
strcpy((debut->name,
debut->name,Denis);
Denis);
debut->next
debut->next==NULL;
NULL;

Denis\0
NULL

debut

Le dbut de la liste est indiqu par un pointeur indpendant (debut) et la fin par NULL

Nouvelle cellule en dbut de liste chane


cellule
cellule*prec;
*prec;
prec
prec==(cellule
(cellule*)
*)malloc
malloc(sizeof(cellule));
(sizeof(cellule));
strcpy
strcpy((prec->name,
prec->name,Claire);
Claire);
prec->next
prec->next==debut;
debut;
Claire
debut
=
prec;
debut = prec;
debut

prec

Denis
NULL

120

Nouvelle cellule aprs la


cellule prec
cellule
cellule*p;
*p;
pp==(cellule
(cellule*)
*)malloc
malloc(sizeof(cellule));
(sizeof(cellule));
strcpy
strcpy((p->name,
p->name,Alfred);
Alfred);
p->next
p->next==prec->next;
prec->next;
prec->next
prec->next==p;
p;
Alfred

Claire
Claire

Denis
Denis
NULL
NULL

debut
debut

OK?

prec
121

Parcourir une liste


void
voidparcours
parcours(struct
(structNode
Node*debut)
*debut)
{{
struct
structNode
Node*p;
*p;
pp==debut;
debut;
while
while((pp!=
!=NULL)
NULL){{
printf
printf(%s\n,
(%s\n,p->name);
p->name);
pp==p->next;
p->next;
}}
}}
Claire

Alfred

debut est un pointeur sur


la cellule qui contient le
premier lment de la
liste
Liste identifier par l'adresse
de sa premire cellule

Denis
NULL

debut
122

void liberation(liste L){


if (L) {
liste temp = L>suivant;
free(L);
liberation(temp);
}
}
void liberation (liste *lis)
{
liste *p;
while ( lis != NULL) {
p = lis;
lis=lis->next;
free(p);
}
}

123

Exemple

LIFO
Last-In-First-Out
Le dernier lment ajout dans la
liste, est le premier en sortir.
Oprations:
Crer la pile,
Ajouter un lment (Push),
Effacer un lment (Pop),
Eliminer la pile .
124

PUSH procdure
Push(5)

Push(9)

NULL

Push(3)
Push(7)

Top

Top

Top

Top

Overflow risk si la pile est pleine!!!


125

POP procdure
Pop(7)
Pop(3)
Pop(9)
Pop(5)

NULL
Underflow risk
si
la
pile
est
vide
!!!
Top
Top
Top
Top
Top
Top
Top

126

Simulation de la factorielle
5! = ??
5! = 5*4!
4! = 4*3!
3! = 3*2!
2! = 2*1!
1! = 1*0!
0! = 1

0
1
2
3
4
5
127

Simulation de la factorielle
5! = ??
5! = 5*4!

0! = 1

4! = 4*3!

1! =

*1 = 1

3! = 3*2!

2! =

*1 = 2

2! = 2*1!

3! =

*2 = 6

1! = 1*0!

4! =

*6 = 24

0! = 1

5! =

*24 = 120

0
1
2
3
4
5
128

TP3
Crer une liste simplement chane dont chaque cellule contient les champs
suivants :
{
int
struct Node

data;
*next;

/* les informations */
/* le lien : pointeur sur la cellule suivante */

}
Le programme doit grer en boucle le menu de choix suivant :
1- Crer une liste avec insertion en tte de liste (avec affichage)
2- Sauver la liste
3- Insrer dans la liste (avec affichage)
4- Nettoyer la mmoire et sortir

129

1 : Cre une liste en insrant 2n, puis 2n-2, puis 2n-4, et enfin 0 qui sera
en tte de la liste. (Liste : 0,2,4,6,8,10, 2n.)

Push(6)

Push(4)

NULL

Push(2)
Push(0)

debut

Top

Top

Top

2 : Sauvegarde la liste dans le fichier Liste1


3 : Insre dans la liste 1, puis 1, puis 3, et en fin 2n-1.
(Liste finale : -1,0,1,2,3,4,5,6,7,8,9,2n)

2 : Sauvegarde la nouvelle liste dans le fichier Liste2


4 : Libre la mmoire avant de quitter le programme.
130

Listes doublement chanes


struct
structNode
Node{{
int
int
struct
structNode
Node
struct
structNode
Node
};};

data;
data;
*prev;
*prev;
*next;
*next;

/*/*les
lesinformations
informations*/*/
/*/*lien
lienvers
versleleprcdent
prcdent*/*/
/*/*lien
lienvers
verslelesuivant
suivant*/*/

data

prev next

typedef struct Node Cell;


Cell *debut, *fin, *act;
int dim = sizeof(Cell);
debut = (Cell *) malloc(dim);
fin = (Cell *) malloc(dim);

debut

fin
131

debut->prev = NULL;

data

prev next

debut->next = fin;
fin->prev = debut;
fin->next = NULL;

NULL

debut

NULL

fin

132

Insrer un lment en fin de liste


fin->next = act;

data

act->prev = fin;

prev next

act->next = NULL;
fin = act;
NULL

NULL

fin

debut

NULL

NULL

act

fin

debut
133

Insrer un lment dans la liste pos=qlq


Cell *tmp;
tmp = (Cell *) malloc(dim);

data

prev next

tmp->prev = act->prev ;
act->prev->next = tmp;
tmp->next = act;
act->prev = tmp;

tmp
NULL

NULL

act
debut

fin

134

tmp
NULL

NULL

fin

debut

NULL

NULL

fin
debut
135

Arbre binaire

typedef struct noeud{


int donnee;
struct noeud *gauche;
struct noeud *droite;
}

Tri par arbre binaire de recherche ABR

136