Vous êtes sur la page 1sur 135

Langage de Programmation

- Le Langage C -

Sommaire
1. 2. 3. 4. 5. 6.

Histoire du langage C Introduction au langage lments de base (rgles dcriture, types) Les variables Oprateurs et expressions Les entres-Sorties (printf, scanf) Les structures de contrle

Sommaire
7. 8. 9. 10. 11. 12.

Classification des variables Les objets structurs (tableaux, structures) Les Fonctions Les pointeurs Les fichiers Le prprocesseur (#include, #define)

Histoire du C

Origines

C a trois anctres: les langages CPL, BCPL et B. CPL : (pour Combined Programming Language) a t conu au dbut des annes 1960 - universits de Cambridge et de Londres. Fortement typ mais trop complexe disparition dans las anne 70 BCPL : (pour Basic CPL) Cambridge en 1966 par Martin Richards. Version siplifie Ecriture dun 1er Compilateur et de divers systmes dexploitations B : Ken Thompson vers 1970 dans les laboratoires Bell Version simplifie du BCPL

Histoire du C
C: dvelopp par un collgue de Ken Thompson, Dennis Ritchie qui ajouta les tableaux, les pointeurs, les nombres virgule flottante, les structures... 1972 fut l'anne de dveloppement la plus productive et sans doute l'anne de baptme de C. En 1973, C fut suffisamment au point pour que 90% de UNIX puisse tre rcrit avec. - Une 1re dfinition du langage est apparue en 1978 avec louvrage de Ritchie et Kernighan The C programming language. - Son succs international a contribu sa normalisation: 1- ANSI (American National Standard Institute 2- ISO (International Standadization Organisation 3- CEN (Comit Europen de Normalisation) en 1993

1. Introduction au langage C
- Le langage C est un langage de bas niveaux, dans le sens o il permet la manipulation de donnes que manipulent les ordinateurs (Bit, octet, adresse) Langages volus (Pascal, Fortran, ADA) - Il est suffisamment gnral pour permettre de dvelopper des application de type scientifique ou de gestion base sur laccs aux bases de donnes (Word et Excel sont crits partir de C ou C++) - Il est un des 1ers langages offrant des possibilits de programmation modulaire: Un programme peut tre constitu de plusieurs module (module = fichier .c)

1. Introduction au langage C
- Un langage de programmation a pour finalit de communiquer avec la machine. Le langage maternel de la machine n'utilise que deux symboles (0 et 1): c'est le langage machine. Exemple: le nombre 5 est reconnu par une machine par la succession des symboles 101 (c'est la reprsentation du nombre en base 2). De mme, les oprations qu'une machine est capable d'excuter sont codes par des nombres, c'est--dire une succession de 0 et 1. Par exemple, l'instruction Machine 00011010 0001 0010 demande la machine d'effectuer l'opration 1+2. Ce langage est le seul qui soit compris par l'ordinateur, Est-il alors le seul moyen pour communiquer avec celui-ci??? Rponse : Non, utilisation du langage assembleur : add $1 $2

Il fut suivi par des langages plus sophistiqus et de plus en plus proche du langage humain

1. Introduction au langage C
- La programmation structure (Fortran, Pascal, C, Perl, Tcl ), - La programmation structure et modulaire (Ada, Modula), - La programmation fonctionnelle (Lisp) - La programmation logique (Prolog) - La programmation objet (C++, Java, VB.net, C# ).

Compilateur

1. Introduction au langage C
Quest ce quun programme C? Cest un texte crit avec un diteur de texte, respectant une certaine syntaxe et stock sous forme d'un ou plusieurs fichiers (gnralement avec l'extension .c). A l'oppos du langage assembleur, les instructions du langage C sont obligatoirement encapsules dans des fonctions et il existe une fonction privilgie appele main qui est le point de dpart de tout programme. Exemple: main() { printf(Bonjour!); } Source.c Compilation Objet.o Edition des liens Excutable

2. lments de base
2.1 les fichiers include
Exemple: # include <stdio.h> main() { printf(Bonjour!); } La directive #include inclu le fichier stdio.h au programme avant la compilation (pour pouvoir utiliser la fonction prdfinie printf. On parle alors de prproceseur

2. lments de base
2.2 les Commentaires
Exemple: # include <stdio.h> //pour pouvoir utiliser la fonction printf main() { printf(Bonjour!); } /*Ce programme imprime la chaine de caractre Bonjour! lcran*/

2. lments de base
2.3 Prsentation de quelques instructions du langage C

2. lments de base
2.3 Prsentation de quelques instructions du langage C
Exemple 2 :

2. lments de base
2.4 Les identificateurs
Les identificateurs servent dsigner les diffrents objets manipuls par le programme:Variables, fonctions, - Commence ncessairement par une lettre - une lettre majuscule est tenue pour diffrente de la lettre minuscule correspondante; - Au plus 31 caractre - Le caractre _ (appel blanc soulign ) est considr comme une lettre ; il peut donc figurer n'importe quelle place dans un identificateur: _Total2, Prix_unit

2. lments de base
2.5 Les Types dans C
Les types de base du langage C se rpartissent en 3 grande catgories en fonction de la nature des informations quils permettent de reprsenter: Nombres entiers (int) Nombres flottants (float ou double) Caractre (char): apparat en C comme un cas particulier de int.

Ils peuvent tre signs ou non signs : signed ou unsigned (unsigned int x;)

2. lments de base
a. Les Types Entiers

short int ou short (entier sur 16 bits : - 32 768 32 767) int (entier sur 32 bits : - 2 147 483 648 2 147 483 647) long int ou long (entier sur 32 bits ou 64 bits, selon les machines)

Chacun des 3 peut tre nuanc par lutilisation du qualificatif unsigned pour ne reprsenter que des nombres positifs: Exemple: unsigned short x; x peut aller de 0 65 535 pas de bit rserv pour le signe - C accepte les constantes entire en notation dcimale, hexadcimale ou octale

2. lments de base
b. Les Types Flottants
Float : cod sur 4 octets avec 1 bit de signe, 23 bits de mantisse et 8 bits d'exposant Double : cod sur 8 octets avec 1 bit de signe, 52 bits de mantisse et 11 bits d'exposant Long : cod sur 10 octets avec 1 bit de signe, 64 bits de mantisse et 15 bits d'exposant

- C accepte les constantes flottante en notation dcimale ou scientifique 3.5e+3 3500 2.43 -0.38 -.38 4. .27

2. lments de base
c. Le Type Char
En C, un caractre est un entier sign cod sur 1 octet Notation des constantes caractres : a , $ ..

Important:

a a

Il existe des caractres non imprimables, tel que le changement de ligne, de Tabulation, en voici un tableau rcapitulatif

2. lments de base
NOTATION \a \b \f \n \r \t \v \\ \' \ '' \? RESULTAT cloche ou bip (alert ou audible bell) Retour arrire (Backspace) Saut de page (Form Feed) Saut de Ligne (Line Feed) Retour chariot (Carriage Return) Tabulation horizontaLe (HorizontaL Tab) Tabutation verticale (VerticaL Tab) \ ?

2. lments de base
A propos du type boolen :

Pas de type boolen en C. Le type boolen est reprsent par un entier. Il se comporte comme la valeur boolenne vraie si cette valeur entire est non nulle. Dans un contexte qui exige une valeur boolenne (comme les tests, par exemple), un entier non nul quivaut vrai et la valeur zero quivaut faux

2. lments de base
2.6 Les Mots rservs

Les mots suivants sont rservs. Leur fonction est prvue par la syntaxe de C et ils ne peuvent pas tre utiliss dans un autre but :
auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if static while

3. Les Variables
3.1 Declaration
Char Unsigned Auto Register Static extern Const volatile Float Double Long double Signed Short Int long identificateur = expression

Exemple:

int x, y=0, z; extern float a,b; static unsigned short n=1000;

3. Les Variables
3.2 Les variables statiques locale

Le qualificatif static, plac devant la dclaration d'une variable locale, produit une variable qui est: -Pour sa visibilit , locale -Pour sa dure de vie, statique (Permanente) Elle n'est accessible que depuis l'intrieur du bloc ou elle est dclare, mais elle est cre au dbut du programme et elle existe aussi longtemps que dure l'excution de celui-ci. Exemple : void bizarre(void) { static int cpt = 1000; printf("%d ", cpt); cpt++; } Appels conscutifs : 1000 1001 1002

4. Oprateurs et Expressions
C dispose d'un important ventail d'oprateurs originaux d'affectation et d'incrmentation.

4.1 Oprateurs arithmtiques en C

Comme tous les langages, C dispose d'oprateurs classiques "binaires" , savoir l'addition (+), la soustraction (-), la multiplication (*) et la division (/), ainsi que d'un oprateur "unaire" correspondant l'oppos not - (comme dans -n ou -x+y). Les oprateurs binaires ne sont priori dfinis que pour deux oprandes ayant le mme type parmi: int, long int, float, double, long double et ils fournissent un rsultat de mme type que leurs oprandes.

4. Oprateurs et Expressions
4.1 Oprateurs arithmtiques en C
De plus, il existe un oprateur de "modulo" not % qui ne peut porter que sur des entiers et qui fournit le reste de la division de son premier oprande par son second. Par exemple, 11%4 vaut 3, 23%6 vaut 5 Remarque: le quotient de deux entiers fournit un entier. Ainsi 5/2 vaut 2; en revanche, le quotient de deux flottants (not, lui aussi, /) est bien un flottant (5.0/2.0 vaut bien approximativement 2.5). Priorit des oprateurs : les rgles sont "naturelles" et rejoignent celles de l'algbre traditionnelle

4. Oprateurs et Expressions
Conversions implicites :

On peut crire des expressions mixtes dans lesquelles interviennent des oprandes de types diffrents: Int n,p; float x; Conversion implicite: int float Mme mcanisme : n*x + p (int * float) + int ( float*float) + int float float + + int float float

On parle de conversion dajustement de type: intlongfloatdoublelong double

4. Oprateurs et Expressions
Promotions numriques :

On a vu que les oprateurs numriques ne sont pas dfinis pour le types char et short :

C prvoit que toute valeur char ou short soit dabord convertie en int. short n,p; float x; Conversion systmatique: Conversion implicite : n*x + p (short * float) + short ( int * float) + int float + float float float * float + int

4. Oprateurs et Expressions
4.2 Oprateurs Relationnels
Comme tout langage, C permet de "comparer" des expressions l'aide d'oprateurs classiques de comparaison. exemple : 2*a > b +5

Par contre, C se distingue de la plupart des autres langages sur deux points: 1-le rsultat de la comparaison est, non pas une valeur "boolenne" (on dit aussi "logique") prenant l'une des deux valeurs vrai ou faux, mais un entier valant:

0 si le rsultat de la comparaison est faux, 1 si le rsultat de la comparaison est vrai.

Ainsi, la comparaison ci-dessus devient en fait une expression de type entier. Cela signifie qu'elle pourra ventuellement intervenir dans des calculs arithmtiques;

4. Oprateurs et Expressions
4.2 Oprateurs Relationnels
2-les expressions compares pourront tre de type quelconque et seront soumises au rgles de conversion prsentes prcdemment. Liste des oprateurs: < <= > >= mme priorit Exemple: a < b == c < d == !=

> mme priorit

(a < b) == (c < d)

Remarque: les oprateurs relationnels sont moins prioritaires que les oprateurs arithmtiques ( x+y < a+2 (x+y) < (a+2) )

4. Oprateurs et Expressions
4.3 Oprateurs Logiques
C dispose de trois oprateurs logiques classiques: et (not &&), ou (not | |) et non (not ! ). Par exemple: (a<b) && (c<d) prend la valeur 1 (vrai) si les deux expressions a<b et c<d sont toutes deux vraies ( de valeur 1), la valeur 0 (faux) dans le cas contraire. Ces oprateurs acceptent n'importe quel oprande numrique, y compris les types flottants, avec les rgles de conversion implicite dj rencontres. condition de considrer que:

0 correspond faux, toute valeur non nulle correspond vrai

4. Oprateurs et Expressions
4.3 Oprateurs Logiques Exemples: n et p sont des entiers, le compilateur accepte des expression telles que: n && p n||p if ( !n ) if (n == 0)

Remarque1: loprateur ! a une priorit suprieur celle de tous ls oprateurs arithmtiques et relationnels. La ngation de a==b serait !(a==b) et non !a==b

Ne sera value que si a<b est vrai

Remarque2: loprateur | | est moins prioritaire que &&. Tous deux sont de priorit infrieure aux oprateurs arithmtique et relationnels a<b && c<d quivaut (a<b) && (c<d)

4. Oprateurs et Expressions
4.4 Oprateur daffectation ordinaire
Nous avons dj eu l'occasion de remarquer que : i = 5 tait une expression qui ralisait une action : l'affectation de la valeur 5 i. Cet oprateur d'affectation (=) peut faire intervenir d'autres expressions comme dans : c=b + 3

Cet oprateur possde une associativit de droite gauche : i = j = 5

4. Oprateurs et Expressions
4.5 Oprateurs dincrmentation et de dcrmentation ( ++

-- )

++ i : expression qui incrmente de 1 la valeur de i, et sa valeur est celle de i aprs incrmentation si la valeur de i est 5, l'expression : n = ++i - 5 affectera i la valeur 6 et n la valeur 1. n = i++ - 5 (n==0 , i++ vaut 5, i vaut 6)

On dit que ++ est: -un oprateur de pr incrmentation lorsqu'il est plac gauche -un oprateur de post incrmentation lorsqu'il est plac droite

4. Oprateurs et Expressions
4.5 Oprateurs dincrmentation et de dcrmentation ( ++
Priorit: 3 * i++ * j-- + k++ quivaut 3 * (i++) * (j--) + (k++)

-- )

La priorit leve de ces oprateurs unaires permet dcrire des expression assez compliques sans quil soit ncessaire demployer des ( )

4.6 Oprateurs daffectation largie: i=i+k i+=k a=a*b a*=b i=i-k i-=k a=a/b a/=b

4. Oprateurs et Expressions
4.7 Loprateur de CAST :
Exemple: n=10, p=3; (double) (n/p) (double) n/p aura comme valeur 3 aura comme valeur 3.33333

4.8 Loprateur conditionnel : (seul oprateur ternaire en C) syntaxe : condition ? Valeur si vrai : valeur si faux on utilise la valeur de lexpression la valeur de lexpression nest pas utilise

z = (x=y) ? a : b ; a>b ? i++ : i-- ;

4. Oprateurs et Expressions

EXERCICES

5. Les Entes-Sorties Conversationnelles

Quelles sont les critures autoriss pour des nombres fournis en donnes? Que se passe-t-il lorsque lutilisateur ne les respecte pas?

Comment organiser les donnes lorsque lon mlange les types numriques et les types caractres?

Que se passe-t-il lorsque, en rponse scanf, on fournit trop ou peu dinformations?

Comment agir sur la prsentation des informations lcran?

5.1 Les possibilits de la fonction printf


La fonction printf a comme 1er argument une chane de caractres qui spcifie: Des caractres afficher tels quels; Des code de format reprs par %. Un code de conversion (c, d, f..) prcise le type de linformation afficher. Un code de format peut contenir des informations complmentaires agissant sur le cadrage, le gabarit ou la prcision. Exemple: printf("leur somme est : %d",n1+n2);

5.1 Les possibilits de la fonction printf


a. Les principaux codes de conversion:

c : char: caractre affich ''en clair" (convient aussi short ou int compte tenu des conversions systmatiques)

d : int (convient aussi char, compte tenu des conversions systmatiques) u : unsigned int (convient aussi unsigned char ou unsigned short, compte tenu des conversions systmatiques)

ld : long lu : unsigned long

5.1 Les possibilits de la fonction printf


a. Les principaux codes de conversion:

f : double ou float crit en notation "dcimale" avec six chiffres aprs le point e : double ou float crit en notation 'exponentielle'' (mantisse entre 1 et 9) avec six chiffres aprs le point dcimal, sous la forme x.xxxxxxe+yyy ou x.xxxxxxe-yyy pour les nombres positifs et -x.xxxxxxe+yyy ou -x.xxxxxxe-yyy pour les nombres ngatifs

s : chane de caractres dont on fournit l'adresse (notion qui sera tudie ultrieurement)

5.1 Les possibilits de la fonction printf


b. Action sur le gabarit daffichage: Les entiers sont affichs par dfaut sans espaces avant ou aprs. Les flottants avec six chiffres aprs le point. Pour agir sur laffichage un nombre est plac aprs % et prcise le nombre de caractre minimum utiliser. Exemples: printf("%3d" , n ); n = 20 n=3 n = 2358 n = -5200 ^20 ^^3 2358 -5200

5.1 Les possibilits de la fonction printf


b. Action sur le gabarit daffichage: Exemples: printf("%f" , x ); x = 1.2345 x = 12.3456789 1.234500 12.345678

printf("%10f" , x ); x = 1.2345 x = 1.2345E5 x = 1.2345 x = 123.45 ^^1.234500 123450.000000 1.234500e+000 1.234500e+002

printf("%e" , x );

5.1 Les possibilits de la fonction printf


c. Actions sur la prcision : pour les flottants, on peut prciser un nombre de chiffres aprs le point dcimal Exemples: printf("%10.3f" , x ); x = 1.2345 x = 1.2345E3 x = 1.2345E7 Remarques: Cadrage de laffichage gauche printf("%-10.3f" , x ); x = 1.2345 1.235^^^^^ - Le caractre * figurants la place dun gabarit ou une prcision signifie que la valeur effective est fournie dans la liste des arguments de printf: printf("%8.*f" , n, x ); n=1; x=1.2345 ^^^^^1.2 - La fonction printf fournit une valeur de retour (nombre de caractre affichs) ^^^^^1.235 ^^1234.500 12345000.000

5.1 Les possibilits de la fonction printf


d. Les erreurs de programmation : Erreur 1 : Code de format en dsaccord avec le type de lexpression afficher: Consquence : mauvaise interprtation si mme taille (int en %u), sinon, consquences plus dsastreuses. Erreur 2: Nombre de code de format diffrents du nombre dexpressions de la liste Consquence 1 : si des expressions de la liste nont pas de format, elles ne seront pas affiches ( printf("%d" , n, p ); // valeur de p ne sera pas affich ) Consquence 2 : sil y a trop de code de format, printf cherchera afficher nimporte quoi ( printf("%d %d" , n ); n=8 8 2 )

5.1 Les possibilits de la fonction scanf


a. Les principaux codes de conversion :

c : char d : int u : unsigned int hd : short int hu : unsigned short ld : long lu : unsigned long

5.1 Les possibilits de la fonction scanf


a. Les principaux codes de conversion :

f ou e : float crit en notation "dcimale" ou 'exponentielle'' Lf ou le : double crit en notation "dcimale" ou 'exponentielle'' s : chane de caractres dont on fournit l'adresse (notion qui sera tudie ultrieurement)

b. Premires notion de tampon et de sparateurs : Lorsque scanf attend des donnes, linformation frappe au clavier est range temporairement dans lemplacement mmoire nomm tampon . Ce dernier est explor caractre par caractre au fur et mesure des besoins. Certains caractres jouent un rle particulier: les sparateurs (lespace et la fin de ligne \n)

5.1 Les possibilits de la fonction scanf


c. Les premires rgles utilises par scanf :

Les codes de format correspondant un nombre entranent lavancement du pointeur jusquau 1er caractre diffrent dun sparateur, puis scanf prend en compte tous les caractres suivants jusqu la rencontre dun sparateur.

Quand au code de format %c, il entrane la prise en compte du caractre dsign par le pointeur (mme un sparateur) et il est avanc sur le caractre suivant.

5.1 Les possibilits de la fonction scanf


c. Les premires rgles utilises par scanf : Exemples : (n et p sont de type int, c char, @ dsigne une fin de ligne) scanf("%d%d" , &n, &p ); 12^25@ ^12^^25^^@ 123@ @ ^25 scanf("%d%c" , &n, &c ); 12^a@ n = 12 c= n = 12 p=25 n = 12 n = 12 p=25 p=25

5.1 Les possibilits de la fonction scanf


d. On peut imposer un gabarit maximal : Le traitement dun code de format sinterrompe soit la rencontre dun sparateur, soit lorsque le nombre de caractre indiqu a t atteint !! Exemples : (n et p sont de type int, @ dsigne une fin de ligne) scanf("%3d%3d" , &n, &p ); 12^25@ ^^^^^12345@ 12@ 25@ n = 12 p=25 n = 12 n = 123 p=25 p=45

5.1 Les possibilits de la fonction scanf


e. Rle dun espace dans le format : Un espace entre deux codes de format demande scanf de faire avancer le pointeur au prochain caractre diffrent dun sparateur !! Exemples : (n et p sont de type int, c char, @ dsigne une fin de ligne) scanf("%d %c" , &n, &c ); 12^a@ 12^^^@ a@ n = 12 c=a n = 12 c=a

5.1 Les possibilits de la fonction scanf


f. Arrt prmatur de scanf : Compte = scanf("%d %d %c" , &n, &p, &c ); 12^25^b@ 12b@ b@ n = 12 n = 12 p = 25 p inchang c=b c inchang c inchang compte = 3 compte = 1 compte = 0

n indfini p inchang

Un arrt prmatur de scanf a lieu dans le cas o scanf nest pas en mesur de fabriquer une valeur adquate !!

5.1 Les possibilits de la fonction scanf


f. Problme de synchronisation entre lcran et le clavier : Examinons cet exemple: #include <stdio.h> main() { int n, p; printf("donner une valeur pour n : "); scanf("%d",&n); printf("Merci pour %d\n",n); printf("donner une valeur pour p : "); scanf("%d",&p); printf("Merci pour %d\n",p); }

excution

5.1 Les possibilits de la fonction scanf


f. Problme de synchronisation entre lcran et le clavier : Le tampon nest pas vide chaque nouvel appel de scanf g. Erreurs de programation : 1- Code de format en dsaccord avec le type de lexpression: Si mme taille introduction dune mauvaise valeur Si la variable a une taille infrieur crasement dun emplacement mmoire conscutif cette variable 2- Nombre de codes de format diffrent du nombre dlments de la liste: Scanf("%d",&n, &p); seule la valeur de n est lue Scanf("%d%d",&n); on affecte une valeur un emplacement alatoire de la mmoire

Instructions de contrle

Le langage C dispose d'instructions structures permettant de raliser : - des choix : instructions if...else et switch, - des boucles : instructions do...while, while et for.

La notion de branchement est aussi disponible en langage C - Instructions de branchement inconditionnel : goto, break et continue, - Instruction de choix multiple que constitue switch

Instructions de contrle

if (expression) instruction_1 else Instruction

if (expression) instruction_1

Exemples if (a<=b) printf("min(a,b) est %f, a) ; else printf ("min(a,b) est %f", b) ; Ambigut ? if (a<=b) if (b<=c)printf ("ordonn") ; else printf ("non ordonn") ;

Instructions de contrle

switch (expression) { case constante_1 : [ suite_d'instructions_1 ] case constante_2 : [ suite_d'instructions_2 ] .............. case constante_n : [ suite_d'instructions_n ] [ default : suite_d'instructions ] }

Exemples int n ; nul printf ("donnez un entier : ") ; scanf ("%d", &n) ; switch (n) { case 0 : printf ("nul\n") ; _______ case 1 : printf ("un\n") ; case 2 : printf ("deux\n") ; }

Instructions de contrle
main() { Int n ; printf ("donnez un entier : ") ; scanf ("%d", &n) ; switch (n) { case 0 : printf("nul\n") ; break ; Case 1 : case 2 : printf("petit\n") ; Case 3 : Case 4 : case 5 : printf("moyen\n") ; break ; default : printf("grand\n") ; } }

donnez un entier : 1 petit moyen ___________ donnez un entier : 4 moyen ___________ donnez un entier : 25 grand

Instructions de contrle
do instruction while (expression) ;

Exemples do { printf ("donnez un nb > 0 : ) ; scanf ("%d", &n) ; printf("vous avez fourni %d", n); } while (n<= 0 ) Peut s'crire :
do { printf ("donnez un nb > 0 : ) ; scanf ("%d", &n) ; } while ( printf("vous avez fourni %d", n), n<= 0 )

ou encore :
do printf ("donnez un nb >0 : ") ; while ( scanf("%d", &n), printf ("vous avez fourni %d", n), n <= 0 ) ;

Instructions de contrle
while (expression) Instruction

Exemples main() { int n, som ; som = 0 ; donnez un nombre : 15 donnez un nombre : 25

while (som<100) donnez un nombre : 12 {printf ("donnez un nombre : ") ; donnez un nombre : 60 scanf ("%d", &n) ; somme obtenue : 112 som += n ; } printf ("somme obtenue : %d", som) ; }

Instructions de contrle
for ( [ expression_1 ] ; [ expression_2 ] ; [ expression_3 ] ) instruction

Exemples int i ; for ( i=1 ; i<=5 ; i++ ) { printf ("bonjour ") ; printf ("%d fois\n", i) ; } Cette instruction est quivalente : I = 1 ; for ( ; i<=5 ; i++ ) { printf ("bonjour ") ; printf ("%d fois\n", i) ; } ----------------i = 1 ; for ( ; i<=5 ; ) { printf ("bonjour ") ; printf ("%d fois\n", i) ; I++ ; }

Exercices

Exercices

Correction

Exercice

Quelles seront les valeurs lues dans les variables n et p (de type int), par l'instruction suivante ? scanf ("%4d %2d", &n, &p) ; lorsqu'on lui fournit les donnes suivantes (le symbole ^ reprsente un espace et le symbole @ reprsente une fin de ligne, c'est-dire une "validation") ? a) 12^45@ b) 123456@ c) 123456^7@ d) 1^458@ e) ^^^4567^^8912@

Programmation modulaire et les fonctions

Programmation modulaire

On dcoupe les programmes en plusieurs parties : programme difficile lire pas de squence rptitives criture modulaire, programmation structure les modules sont dcomposs eux-mmes en sous-modules partage d'outils communs compilation spare. En gnral, on utilise deux types de module : Les fonctions prennent des arguments et ramnent un rsultat scalaire simple comme en mathmatique. Les procdures (sous-programmes) prennent des arguments, font une action et modifient des valeurs de variables.

Fonctions en C

Les fonctions en C :
faire des actions ne rien renvoyer fournir des rsultats complexes (structures) modifier la valeur des arguments et la valeur des variables dites "globales".

Le langage C autorise la compilation spare (programme source en plusieurs parties), ce qui facilite la cration de grand programme.

Exemple : fonction puissance (1)


Main() { long int puissance(int, long int); Int n, exp; long int r;

/* dclaration la fonction */

printf("Entrez un nombre entier :"); /* Lire la valeur du nombre suivant */ scanf("%d", &n); printf("Entrez l'exposant (positif) :"); /* lire l'exposant */ scanf("%d", &exp); r = puissance(exp+ 1, (long int) n); /* calcul de la puissance */ printf("le resultatest %ld\n",r); } /* Dfinition de la fonction puissance */ long int puissance(int exposant, long int base) { long int resultat; int i; resultat= base;

for(i = 0; i < exposant -1; i++) resultat= resultat* base; return resultat; }

Exemple de fonction

return

renvoie la valeur rsultat si l'argument de return n'est pas du mme type que celui dclar dans l'entte le compilateur convertit. fonction sans valeur de retour : void sans_de_retour(int n) on peut utiliser return sans argument. fonction sans paramtre: int sans_de_param(void)

Les dclarations des fonctions

La dclaration n'est ncessaire que lorsque la fonction appelante se trouve plus haut que l'appele. La dclaration reste fortement conseille. Dclaration partielle possible (interdit en C++): long int puissance(); viter. Sans dclaration, une fonction renvoie int et ces arguments sont quelconques. Les noms d'arguments sont admis dans le prototype (la dclaration). long int puissance(int exposant, long int base); on place la dclaration soit dans la fonction appelante avant la dfinition de la premire fonction.

Les dclarations des fonctions

La dclaration permet au compilateur : si la dfinition se situe dans le mme fichier source, le compilateur vrifie si les types d'argument formel est le mme que celui du prototype. Le contrle sur le nombre et le type d'argument mentionne dans les appels. La mise en place de conversion. Si le compilateur ne connat pas le type des arguments, il applique la conversion automatique. Char et short --> int et float --> double Seule une fonction dclare peut recevoir un float, short ou un char

Les fichiers d'en-ttes

Les fichiers .H sont inclus au source par la directive #include ils contiennent, entre autre, des dclarations.
Contrle sur le nombre et le type d'argument mentionn dans les appels. Mise en place des conversions adquates.

#include<math.h> pour utiliser la fonction sqrt()

Transmission des arguments par valeur

Les arguments sont transmis par valeur Ceci implique qu'une modification de la valeur d'un argument dans la fonction appel n'influe pas sur la fonction appelante. Exemple : void appelante(void) { int i = 10; change(i); printf("valeur de i =%d=", i); } void change(int i) { I = 20; // i vaut 20 }

i vaut 10 i vaut 10

i vaut 20

Les arguments
Pour remdier au passage par valeur :
passer l'adresse de l'argument : scanf("%d",&i); utiliser des variables globales.

Remarque :
l'ordre d'valuation d'un argument n'est pas garanti f(i++, i); l'argument effectif peut tre une expression grce au passage par valeur. Si le passage tait par adresse ou rfrence, on ne pourrait transmettre qu'une "lvalue"

Les variables globales

Les variables globales sont dclares l'extrieur des fonctions exemple :


#include <stdio.h> void change(void); int i = 10; void main(void) {printf("valeur de i =%d=\n", i); /* i vaut 10*/ change(); printf("valeur de i =%d=\n", i); /* i vaut 20*/ } void change(void) { i = 20; /* i vaut 20*/ }

Les variables globales

La porte :
Les variables globales ne sont connues que dans la partie du programme source suivant leur dclaration. On nomme cet espace la porte de la variable

la classe d'allocation :
les variables globales font parties de la classe d'allocation statique. La place mmoire est attribue au dbut de l'excution du programme. Elles sont initialises zro sauf indication contraire.

Les variables locales


Les variables locales sont dclares l'intrieur d'une fonction ou d'un bloc. La porte :
Les variables locales ne sont connues que dans la fonction ou le bloc o elles sont dclares.

Les variables locales automatiques :


Un espace mmoire est allou chaque entre dans la fonction et libr chaque sortie dans la pile. Elles ne sont pas "rmanentes". Pas d'initialisation automatique. Initialisation par constante, constante symbolique, variable.

Les variables locales statiques : static int i;


Un espace mmoire permanent est allou. Sa valeur se conserve d'un appel l'autre. Elles sont "rmanentes". Initialisation 0.

Les fonctions rcursives


Exemple :
long fac(int n) { if ( n > 1) return (fac(n -1) * n)) ; Else return(1); }

chaque appel il y a allocation de mmoire pour les variables locales et les arguments On ne commence dpiler que lorsqu'on excute un return, et on libre la mmoire

Exerices

Exercice 1. crire une fonction qui calcule les racines d'une quation de second degr. On suppose Qu'elles sont relles. Exercice 2. crire une fonction rcursive calculant la valeur de la "fonction d'Ackermann" A dfinie pour m>0 et n>0 par : A(m,n) = A(m-1,A(m,n-1)) pour m>0 et n>0 A(0,n) = n+1 pour n>0 A(m,0) = A(m-1,1) pour m>0.

Les tableaux et les pointeurs

Dfinitions

Les tableaux : c'est une collection d'objets identiques (de mme type) dsigns par un identificateur unique (le pointeur sur le tableau). Int tab[2][5] Les pointeurs : Il s'agit d'une variable contenant l'adresse d'un autre objet, il est caractris par le type de l'objet sur lequel il pointe (variable, fonction, premier lment d'un tableau) Int * point;

Les tableaux un indice

Exemple d'utilisation du tableau : stocker les notes d'une classe de 20 lves. Float notes[20] les indices commencent toujours 0 et finissent donc au nombre d'lments moins 1. Dans notre exemple de 0 19. Attention il n'existe aucun contrle sur les bornes !!! notes[100] = 0; est valide mais o avons-nous crit ??? Utilisation d'un tableau notes[2] est une lvalue : possibilt d'affectation : notes[2] = 18; Affectation globale de tableau impossible : t1 = t2 non valide incrmentation : notes[2]++; --notes[16];

Les indices

Les indices peuvent tre le rsultat d'une expression arithmtique renvoyant un entier positif ou ngatif. notes[(2* n) + 1] De mme on peut utiliser des chars comme indice. C1 et C2 sont de type char : notes[c1 + 3], notes[c1] On peut utiliser des constantes comme indices mais pas les constantes symboliques (const) #define NB 5 Int tab[NB]; valide int tab2[NB+2]; valide Const int nb= 50; Int tab[nb]; non valide

Les tableaux plusieurs indices


Dclaration :
Int notes[5][3] notes est un tableau de 5 lignes et 3 colonnes Principe : les tableaux plusieurs indices en C sont plutt des tableaux de tableau de notes[5][1] est un int notes[5] est un tableau de 3 int notes est un tableau dont chaque lment est un tableau de 3 int pas de limitation du nombre d'indices .Rangement en mmoire Int t[5][3] ==> t[0][0], t[0][1], t[0][2], t[1][0], t[1][1], t[1][2], . t[4][0], t[4][1], t[4][2] Donc t[0][5] est en faite t[1][2]

Initialisation des tableaux

Gnralement : Comme les scalaires, les tableaux de classe statique (globale + locale statique) sont initialiss zro. Les tableaux de classe automatique (locale non statique) ne sont pas initialiss. les tableaux une dimension : Int t[5] = { 1, 2, 3, 4, 5} on peut ne mentionner que les premiers lments : int t[5] = { 1, 2, 3} on peut omettre la dimension : int t[] = { 1, 2, 3, 4, 5} les tableaux plusieurs dimensions : int t[3][4] = { { 1, 2, 3, 4}, { 11,12, 13, 14}, { 21,22, 23, 24} } int t[3][4] = { 1, 2, 3, 4, 11,12, 13, 14, 21,22, 23, 24}

Les pointeurs

Les pointeurs : Il s'agit d'une variable contenant l'adresse d'un autre objet, le pointeur est aussi dtermin par le type sur lequel il pointe (variable, fonction, premier lment d'un tableau) Int * point; *point reprsente le contenu de l'entier point par point.

Rciproquement, int entier; &entier est l'adresse mmoire (le pointeur) de la variable entier.

Utilisation

Exemples

int n = 10, p = 10, *adr1, *adr2 ; adr1 = &n; adr2 = &p; *adr1 = *adr2 + 2; ==> ???? *adr1 += 3 ===> ??? (*adr2)++ ===> ????

Remarque

int n, *adr1; adr1 et *adr1 sont des lvalue, c'est dire que adr1++; ou *adr1= 3; sont valides. Au contraire &adr1 et &n ne sont pas des lvalue, car ces adresses sont ncessairement fixes puisque calcules par le compilateur; elles ne peuvent pas tre modifies. (&adr1)++; ou &n= 3; seront rejetes par le compilateur. Rservation mmoire : int *adr1; rserve de la mmoire pour le pointeur mais pas pour un entier.

Arithmtique des pointeurs


int *adr, adr + 1 reprsente l'adresse de l'entier suivant l'adresse de l'entier contenue dans adr. Le dcalage se fait par rapport la taille de l'objet point (size of) On peut aussi :
incrmenter : adr++; ajouter : adr += 12;

Exception : les pointeurs de fonction.

Arithmtique des pointeurs


Comparaison de pointeur le pointeur est caractris par une adresse et un type. On ne peut donc comparer que des pointeurs de mme type.
int t[10] , *p; for( p = t; p < t +10; p++) *p = 1; int t[10] , i; for(i = 0; i < 10; i++) t[i] = 1;

Soustraction de pointeur entre pointeur de mme type; renvoie le nombre d'lments du type entre les deux pointeurs

Affectation de pointeur

On ne peut pas affecter 2 pointeurs de type diffrent. On peut affecter 2 pointeurs du mme type uniquement.
float *pf1, *pf2; pf1 = pf2;

On peut forcer laffectation de 2 pointeurs de type diffrent avec loprateur cast :


char *c; int *i; i = (int *) c;

Mais attention aux contraintes dalignement

Le pointeur NULL

Le pointeur nul est un pointeur qui ne pointe sur rien. On peut donc affecter lentier 0 nimporte quel pointeur. Il est conseill dutiliser la constante NULL (dfinie dans stdio.h). p = NULL On peut comparer un pointeur NULL. if (p = = 0) p = = NULL;

Comme nimporte quelle variable, un pointeur de la classe dallocation statique (par exemple les variables globales) est initialis 0 / NULL mais cela est dpendant de limplmentation. Par prudence, il vaut mieux initialiser le pointeur.
int *Pa = NULL;

Passage par adresse


include <stdio.h> /* Exemple d'appel de fonction */ void echange(int *a, int *b); /* dclaration de la fonction */ main() { int i = 10, j = 20; printf("valeur de i =%d j =%d=", i,j); i =10 j =20 echange(&i, &j); printf("valeur de i =%d j =%d", i,j); i =20 j =10 } void echange(int a, int b) /* dfinition de la fonction*/ { int x; x = *a; *a = *b; *b = x; }

Pointeurs constants

int * const pc est un pointeur constant sur un entier,

pc est non modifiable. const int *pc est un pointeur sur un entier constant, *pc est non modifiable.

Les tableaux et les pointeurs


Les tableaux sont des pointeurs constants
int t[10]; t <==> &t[0] t + 1 <==> &t[1] t + i <==> &t[i] t[i] <==> *(t + i)

Attention ! t n'est pas une lvalue : int t[10]; t = 2; impossible int i, t[10]; for( i = 0; i < 10; i++) *(t + i) = 1; int *p, t[10]; for( p = t; p < t+10; p++) *p = 1;

Les tableaux transmis en argument


Lors du transfert d'un tableau en argument, on transfert seulement l'adresse du tableau
Les tableaux ne sont pas transmissible par la pile. Dans la fonction appele on reoit un pointeur. Cas une dimension
int t[10], r[20]; f(t, 10); /* syntaxe d'appel */ f(&r[0], 20); /* syntaxe d'appel */ /* syntaxe possible de l'entte de la fonction */ void f(int tt[10], int n) ou void f(int *tt, int n)ou void f(int tt[ ] , int n) {int i; for(i = 0; i < n ; i++,tt++) *tt = 1; }

Les tableaux transmis en argument


Cas d'un tableau plusieurs dimensions
Il n'est pas indispensable pour la premire dimension mais elle est indispensable pour les autres dimensions et doit tre fixe dans l'entte de la fonction. void f(int t[][15], int dim) { int i, j; for(i = 0; i < dim1 ; i++) for(j = 0; j < 15 ; j++) t[i][j] = 1; } f ne peut pas servir pour un tableau dont la seconde dimension n'est pas 15 : int tab[10][15]; f(tab,10); f(&tab[0],10); si int tab[10][5]; f(tab,10); ne convient pas.

Les pointeurs de fonctions


En C, on peut dclarer un pointeur de fonction.
int (* fct) (double, int); (* fct) est une fonction renvoyant un entier et prenant un double et un entier en argument alors que fct est un pointeur sur une fonction renvoyant un entier et prenant un double et un entier en argument. Si on dclare : int (* fct)( double, int); et int f1( double, int); on peut raliser les affectations suivantes : fct = f1; fct = f2; on utilise fct comme suit : (* fct )(1.2, 3); ou par simplification fct(1.2, 3);

Exercices

Exercice . crire, de deux faons diffrentes, un programme qui lit 10 nombres entiers dans un tableau avant d'en rechercher le plus grand et le plus petit : a) en utilisant uniquement le "formalisme tableau", b) en utilisant le "formalisme pointeur", chaque fois que cela est possible.

Exercice 2. crire une fonction permettant de trier par ordre croissant les valeurs entires d'un tableau de taille quelconque (transmise en argument). Le tri pourra se faire par rarrangement des valeurs au sein du tableau lui-mme.

#include <stdio.h> #define NVAL 10 /* nombre de valeurs du tableau */ main() { int i, min, max ; int t[NVAL] ; printf ("donnez %d valeurs\n", NVAL) ; for (i=0 ; i<NVAL ; i++) scanf ("%d", &t[i]) ; max = min = t[0] ; for (i=1 ; i<NVAL ; i++) { if (t[i] > max) max = t[i] ; /* ou max = t[i]>max ? t[i] : max */ if (t[i] < min) min = t[i] ; /* ou min = t[i]<min ? t[i] : min */ } printf ("valeur max : %d\n", max) ; printf ("valeur min : %d\n", min) ; }

Correction

#include <stdio.h> #define NVAL 10 /* nombre de valeurs du tableau */ main() { int i, min, max ; int t[NVAL] ; printf ("donnez %d valeurs\n", NVAL) ; for (i=0 ; i<NVAL ; i++) scanf ("%d", t+i) ; /* et non *(t+i) !! */ max = min = *t ; for (i=1 ; i<NVAL ; i++) { if (*(t+i) > max) max = *(t+i) ; if (*(t+i) < min) min = *(t+i) ; } printf ("valeur max : %d\n", max) ; printf ("valeur min : %d\n", min) ; }

Les chanes caractres String

Dfinition et convention

Il n'y a pas de type chane ou string en C, on recourt un tableau de char. Il existe une convention de reprsentation des chanes.
Pour le compilateur les chanes constantes sont notes entre double quotes"bonjour" Pour les fonctions de traitement des chanes qui indiquent la fin de la chane par le caractre NUL '\0' : char chaine[10]; "bonjour" ==> bonjour\0

chaine[0] = 'b' chaine[1] = 'o' chaine[2] = 'n' chaine[3] = 'j' chaine[4] = 'o'

chaine[5] = 'u' chaine[6] = 'r' chaine[7] = '\0' chaine[8] = indfini chaine[9] = indfini

Rappel : 'a' != "a" car "a" vaut 'a' suivi de '\0' ou 65 suivi de 0 en ASCII.

Dfinition et convention
Vous n'avez pas le droit d'crire : char ch[20]; ch= "bonjour"; Vous pouvez utiliser : char ch[20] = "bonjour"; char ch[20] = {'b','o','n','j','o','u','r','\0'}; les 12 derniers caractres sont initialiss 0 ou non en fonction de la classe d'allocation. char ch2[] = "bonjour"; /* ch2 fait 8 caractres exactement */ Vous pouvez aussi utiliser : char *jour[7] = {"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"} jour est pointeur sur un tableau de chanes .

Initialisation
Attention au constante chane : char *ch= "bonjour"; est valide ; le compilateur remplace "bonjour" par l'adresse de l'emplacement o il a rang la chane. Mais vous ne pouvez pas modifier "bonjour" par: char *ch; ch= "bonjour"; *(ch+ 2) = 'X'; /* accept mais comportement indtermin */ On peut se prmunir contre cette faute par la dclaration char const*ch= "bonjour"; Par contre, si la dclaration est char *ch[20] = "bonjour"; La modification fonctionne

Lire et crire des chanes

Plusieurs possibilits :
le format %s avec les fonctions scanf et printf. les fonctions spcifiques : lecture gets et criture puts d'une seule chane la fois. #include<stdio.h> main() {char nom[20], prenom[20], ville[20]; printf("quelle est votre ville :"); gets(ville); printf("donnez votre nom et prenom:\n"); scanf("%s %s",nom, prenom); printf(" %s %s habite %s \n", prenom, nom, ville); }

Lire et crire des chanes

Scanf avec %s :
Le dlimiteur espace empche de saisir des chanes comportant des espaces. Le dlimiteur n'est pas consomm.

Gets :
Lit une chane et une seule. Le seul dlimiteur est la fin de ligne (\n). Le dlimiteur (\n ou EOF) est consomm mais remplac par \0 et est rajout la fin. Renvoie NULL si erreur ou le pointeur sur la chane saisie.

Puts:
Ajoute un saut de ligne la fin de chaque chane

Fiabiliser la lecture de chane

Pour parer aux problmes poss par scanf:


On peut utiliser gets mais il y a un pb avec l'arrt de la lecture et le dbordement de buffer donc plutt fgets(stdin, ). Puis decoder la chane avec sscanf sscanf(adresse, format, liste vbles)

Matrise du buffer, donc nous pouvons appeler sscanf sans nous soucier de la position du pointeur dans le buffer

Fiabiliser la lecture de chane

#defineLG_LIGNE 41 char ligne[LG_LIGNE], mot [31],c; Int n, n_val_ok; Float x; while(1) {printf("Donnez un entier, un flottant et une chane de caractre:\n"); fgets(ligne, LG_LIGNE, stdin); n_val_ok= sscanf(ligne, "%d %f %s", &n, &x, mot); if(n_val_ok== 3) break; } printf('"Merci pour l\'entier %d le flottant %e la chaine%s \n", n, x, mot);

Les fonctions de manipulation de chanes


Les prototypes des fonctions manipulant les chanes se trouvent principalement dans string.h. Les fonctions travaillent sur l'adresse des chanes. Les fonctions possdent 2 variantes : l'une travaillant sans contrle, l'autre permettant une limitation de l'effet de la fonction un ertain nombre de caractres. Les fonctions renvoient en gnral NULL en cas d'chec. strlen: longueur de la chane; strlen(chane) strlen("bonjour"); ==> 7 char *ch= "coucou"; strlen(adr); ==> 6

Concatnation de chanes
strcat: concatne 2 chanes strcat( but, source) char ch1[50] = "Comment"; char *ch2 = "cava"; strcat(ch1,ch2); ch1 ==> "Commentcava" strncat: concatne 2 chanes avec contrle de la longueur strcat( but, source, lgmax) char ch1[50] = "Comment"; char *ch2 = "cava"; strcat(ch1, ch2, 2); ch1 ==> "Commentca"

Comparaison de chanes

strcmp: compare 2 chanes, ordre des codes de caractre (ASCII). strcmp( ch1, ch1)
positif si ch1 > ch2 nul si ch1 = ch2 ngatif si ch1 < ch2

strcmp("bonjour", "madame"); ==> ngatif strcmp("bonjour", "andre"); ==> posit

Copie de chanes

strcpy: copy source dans dest. strcpy( dest, source) strncpy: de mme que strcpy avec longeur max. strncpy( dest, source, lgmax) char ch1[20] = "123456789" char ch2[20] = "coucou" strncpy(ch1, ch2, 3); ==> ch1 = "cou456789" strncpy(ch1, ch2, strlen(ch2) + 1); ==> ch1 = "coucou"

Recherche dans une chane

On peut rechercher l'occurrence d'un caractre d'une sous chane, les fonctions renvoient un pointeur sur l'endroit recherch ou NULL dans le cas contraire. strchr( chane, caractre) en partant du dbut strrchr( chane, caractre) en partant de la fin strstr( chane, sous-chane) en partant du dbut

Conversion

Les fonctions de conversion ignorent les espaces de dbut de chane et utilisent les caractres suivants pour fabriquer une valeur numrique. Un caractre illgal arrte le traitement. Si aucun caractre n'est exploitable, renvoie nul. atoi( chane) int atol( chane) long atof( chane) double

Exercices

Exercice 1. crire un programme dterminant le nombre de lettres e (minuscules) prsentes dans un texte de moins d'une ligne (suppose ne pas dpasser 132 caractres) fourni au clavier.

Exercice 2. crire un programme qui supprime toutes les lettres e (minuscules) d'un texte de moins d'une ligne (suppose ne pas dpasser 132 caractres) fourni au clavier. Le texte ainsi modifi sera cr, en mmoire, la place de l'ancien.

Correction

#include <stdio.h> #include <string.h> #define CAR 'e' #define LGMAX 132 main() { char texte[LGMAX+1] ; char * adr ; int ncar ; printf ("donnez un texte termin par return\n") ; gets (texte) ; Ncar = 0 ; adr = texte ; while ( adr=strchr(adr,CAR) ) { ncar++ ; adr++ ;} printf ("votre texte comporte %d fois le caractre %c", ncar, CAR) ;
}

Correction

#include <stdio.h> #include <string.h> #define CAR 'e' #define LGMAX 132 main() { char texte[LGMAX+1] ; char * adr ; printf ("donnez un texte termin par return\n") ; gets (texte) ; adr = texte ; while ( adr=strchr(adr,CAR) ) strcpy (adr, adr+1) ; printf ("voici votre texte priv des caractres %c\n", CAR) ; puts (texte) ; }

Les structures

Dfinition
La structure permet de regrouper diffrentes variables en une seule.
Exemple : Struct produit { int id; int qte; Float prix; }; Struct produit oeuf; "produit" est un modle de structure, il n'y a pas de rservation de place mmoire. "id", "qte" et "prix" sont nomms champs. "oeuf" est une variable de type "produit", la place mmoire est rserve lors de la dclaration de "oeuf".

Accs au champs

On peut concentrer l'criture (pas recommand):


Struct produit{ int id; Int qte; Float prix; }oeuf, tomate, mozarella; L'accs au champs se fait par l'oprateur point : oeuf.prix = 1.15; printf("%f", oeuf.prix); scanf("%f", &oeuf.prix); oeuf.prix++;

L'affectation

L'affectation entre 2 structures de mme modle : Struct produit oeuf, tomate; tomate = oeuf; ce qui quivaut : tomate.prix = oeuf.prix; tomate.qte= oeuf.qte; tomate.id = oeuf.id; Remarque: l'affectation globale entre 2 tableaux est impossible, mais on peut la raliser en crant une structures contenant un tableau

Initialisation des structures

Les structures suivent la rgle des classes d'allocation. Il est possible d'initialiser explicitement avec des expressions constantes et non des expressions quelconques, comme les tableaux.
Struct produit tomate = { 2, 2000, 2.15 };

La taille d'une structure dpend des contraintes d'alignement:


Struct taille {intx; char c; }t; printf(" taille %d \n", sizeof(t));

La taille de t devrait tre 5, mais en fait sizeof renvoie la taille relle 8.

Typedef
Typedef permet de dfinir des types synonymes typedef int entier;
entier i, j, k; typedef int * ptent; Ptent pti, ptj, ptk; Struct produit {int id; int qte; float prix; }; typedef struct produit t_produit; t_produit oeuf, tomate

Les structures comportant des tableaux

Struct eleve {int id; char nom[20]; int note[10]; } Ali; Ali.note[4] = note_geo; Ali.nom est l'adresse du tableau "nom". strcpy(Ali.nom, "Ali"); Ali.nom[2] est la lettre 'i' Struct eleve Myrieme= {10, "Myrieme" , {0, 1, 2, 3, 4, 5}};

Les tableaux de structures

Struct point {char nom[10]; int x; int y}; Struct point courbe[50]; "point" est le modle de structure, courbe est tableau de 50 lments de type "point" courbe[3].x est valide, courbe.x[3] n'a pas de sens. courbe[3] est une structure "point" le 4 me point de la courbe. courbe[3].nom[2] pour accder au 3 me caractre de nom du 4 me point de la courbe. courbe est l'adresse du dbut du tableau. Initialisation : Struct point courbe2[25] = {{'a', 1, 2}, {'b', 1, 2}, , {'d', 1, 2}};

Les structures imbriques

Struct date {int jour; int mois; int annee}; Struct person {char nom[10]; char prenom[10]; Struct date date_embauche; Struct date date_poste; } Mohammed; Mohammed.date_embauche.annee= 1985; Mohammed.date_poste.annee= Mohammed.date_embauche.annee;

Porte des modles de structure

Si le modle est dclar : A l'intrieur d'une fonction, la porte est limite la fonction. A l'extrieur d'une fonction, la porte est limite tout le fichier source mais pas dans les autres fichiers sources car la directive "extern" ne peut s'appliquer (seulement aux variables). Par contre on peut utiliser un fichier ".h" inclus par la directive include

Les structures en arguments

On peut transmettre une structure par valeur (contrairement au tableau) et on travaille dans l'appele sur une copie. Pour changer les valeurs de la structure, on envoie un pointeur : f(&date_embauche) dfinition de l'appele : Void f(struct date *d); Dans l'appele on accde au champs par :(*d).annee= 1986 ou on peut aussi utiliser :d->annee= 1986 Structure en valeur de retour Struct date f(.)

Les unions

Les unions permettent de stocker dans un espace mmoire des variables de plusieurs types diffrents. union prime {int fixe; double taux; } sac, *pt_sac; La syntaxe est la mme que pour une structure : sac.val, pt_sac->taux struct salaire {char nom[10]; union prime prime_mensuelle; } employe[50]; employe[5]. prime_mensuelle.fixe, employe[6]. prime_mensuelle.taux L'initialisation explicite se fait par le premier type ici int

Exercices
Exercice 1. Dfinir une structure date contenant trois champs de type entier pour identifier le jours, le mois et lanne. Initialiser une variable de type structure date. Afficher cette structure : laide de la variable. laide dun pointeur. Exercice 2. Dfinir un tableau de structures date. Dfinir un pointeur sur ce tableau. Initialiser ce tableau. Imprimer le contenu du tableau

Correction
#include <stdio.h> struct date /* declaration du modele de structure date */ { int jour; int mois; int annee; }; main () { struct date dat, *ptdate = &dat; /* saisie de la date */ printf (" Entrez une date ( jj mm aaaa ) :"); scanf ("%d %d %d", &dat.jour, &dat.mois, &dat.annee); /* affichage de la date */ printf (" La date est : %d\t%d\t%d\n", dat.jour, dat.mois, dat.annee); /* affichage de la date avec le pointeur */ printf (" La date est : %d\t%d\t%d\n", ptdate->jour, ptdate->mois, ptdate->annee); }

Correction

#include <stdio.h> struct date{ int jour, mois, annee;}; main() { struct date dat[5], *ptdate=dat; int i = 0; printf ("Entrez 5 dates au format ( jj mm aaaa )\n"); while (i < 5){ scanf ("%d %d %d", &dat[i].jour, &dat[i].mois, &dat[i].annee); i++; } for (i = 0; i < 5; i++, ptdate++) { /* sans pointeur */ printf (" Date numero %d : %d\t%d\t%d\n", i + 1, dat[i].jour, dat[i].mois, dat[i].annee); /* avec pointeur */ printf (" Date numero %d : %d\t%d\t%d\n", i + 1, ptdate->jour,ptdate->mois, ptdate->annee); } }