Vous êtes sur la page 1sur 275

1.

Introduction Langage C
Jean-Charles Rgin Licence Informatique 2me anne

JC Rgin - Intro C - L2I - 2011

Remerciements
1.2

Carine Fdle

JC Rgin - Intro C - L2I - 2011

Plan du cours
1.3

9 cours Contrle des connaissances :


QCM

: 20%, interro 20% controle terminal 40% projet 20%

Le cours et les TP
http://deptinfo.unice.fr/~regin/cours/cours/LangageC/intro

C.htm

JC Rgin - Intro C - L2I - 2011

Bibliographie
1.4

Th C Programming The P i Language L Kernighan B.W., Ritchie D.M. Prentice Hall, Hall 1978 Le langage C - C ANSI Kernighan B.W., Ritchie D.M. Masson - Prentice Hall, 1994, 2e dition Traduit p par J.-F. Groff et E. Mottier Langage C - Manuel de rfrence Harbison S.P., Steele Jr. G.L. Masson, 1990 Traduit en franais par J.C. Franchitti
JC Rgin - Intro C - L2I - 2011

Langage C
1.5

Invent en 1972 par Dennis Ritchie Langage g g de bas niveau Cr pour porter des systmes dexploitation (Unix) B t : un compilateur But il t peut-tre t t crit it en 2 mois i A Permis de rcrire des programmes assembleurs Programmation indpendante de la machine Portable : prsent sur presque toutes les architectures ayant t inventes
JC Rgin - Intro C - L2I - 2011

Langage C
1.6

Utilis du micro-controleur au super-ordinateur Prsent dans les systmes y embarqus q Sont crits en C
Unix Linux Windows Wi d Tous

les Compilateurs GNU GNOME Les machines virtuelles JAVA


JC Rgin - Intro C - L2I - 2011

Langage C
1.7

Trs utilis car


Bibliothque

logicielle trs fournie Nombre de concepts restreint Permet de g grer des excutables qui q nont besoin de rien pour sexcuter et pour lesquels on peut contrler parfaitement la mmoire utilise (noyau de Syst. Exploit. Logiciel Embarqu) Contrle de bas niveau : trs puissant p

JC Rgin - Intro C - L2I - 2011

Langage C
1.8

Avantages
Nombreux

types de donnes. Riche ensemble d'oprateurs et de structures de contrle. Bibliothque q d'excution standard. Efficacit des programmes. Transportabilit des programmes (plus facile si on respecte une norme). Libert du programmeur. programmeur Interface privilgie avec Unix
JC Rgin - Intro C - L2I - 2011

Langage C
1.9

Inconvnients
Pas

dobjets Pas de gestion des exceptions Peu de contrles ( (on peut p tout faire : dbordement de tableaux ) Faiblement typ (on peut toujours convertir) Peu devenir franchement complexe Vieux langage

JC Rgin - Intro C - L2I - 2011

Langage C
1.10

De trs nombreux langages sont inspirs du C


C++ Java PhP

(C avec objets (encapsulation, hritage, gnricit))

JC Rgin - Intro C - L2I - 2011

Langage C
1.11

Environnement de dveloppement
Allez

jeter un il sur la page wikipedia du langage C (en franais et en anglais) Visual Studio express C++ est gratuit! Avec MSDNAA vous avez le droit davoir plein de chose
Mail Fabrice Huet (Fabrice.Huet@sophia.inria.fr) ( @ p )

JC Rgin - Intro C - L2I - 2011

Langage C
1.12

Langage normalis (C99)

JC Rgin - Intro C - L2I - 2011

Langage C : pour dbuter


1.13

Un programme C est constitu d'un ou plusieurs fichiers sources suffixs par .c et .h, dans le(s)quel(s) une unique fonction main doit apparatre (ce sera le point d' d'entre du d programme). ) Seules des fonctions peuvent tre dfinies.
Pour

dfinir une procdure, il faut dclarer une fonction renvoyant le type spcial void.

Pour renforcer le fait que la fonction n'a ' pas de paramtres, mettre void entre les parenthses.
JC Rgin - Intro C - L2I - 2011

Compilateur gcc
1.14

Portage compilateur gcc pour windows et linux minGw ou minGw64 http://mingw.org/ htt // i http://mingw-w64.sourceforge.net/ 64 f t/ Editeur : notepad++ http://www.clubic.com/telecharger fiche9567 http://www.clubic.com/telecharger-fiche9567notepad.html
JC Rgin - Intro C - L2I - 2011

Un premier exemple
1.15

int i t main i ( (void) id) { int i; int x = 3; ; int y = 4; /* y doit tre positif */ double z = 1.0; i = 0; while (i < y) { z = z * x; i = i + 1; } return 0; }
JC Rgin - Intro C - L2I - 2011

Quelques rgles
1.16

Ce nest pas obligatoire dans le langage mais suivez ces rgles :


On

met toujours des {}: if (x > 3) {y = 4;} On vite p plusieurs instructions sur la mme ligne g
i=i+1; j=j+2; // on spare sur 2 lignes
On

vite p plusieurs dclarations sur la mme ligne g

int i, j=2, k=5; // a viter

JC Rgin - Intro C - L2I - 2011

Quelques rgles
1.17

Les variables sont crites uniquement en minuscule Les macros ou constantes dfinies laide de #define sont toutes en majuscules Les noms de fonctions commencent par une minuscule Les noms de fonctions utilisent lune des 2 formes
Tout En

en minuscule avec des _ pour p sparer p

fahrenheit_to_celcius

collant tout et mettant des majuscules pour sparer les mots


fahrenheitToCelcius
JC Rgin - Intro C - L2I - 2011

On compile et on excute
1.18

O compile et on excute. On Compilation :


Avec

un compilateur (gcc) On prend le fichier source en entre (monfichier.c) En sortie cela cre un fichier a.out (sous Linux, monfichier.exe sous windows)

gcc -Wall -pedantic -ansi foo.c Ce programme C calcule xy, x et y tant donns (x vaut 3, et y vaut 4). Il n'affiche cependant rien du tout...
JC Rgin - Intro C - L2I - 2011

Affichage (criture)
1.19

int x; fprintf(stdout, "%d %d ",x); ,x);


Ecrit

un entier dans le fichier stdout (sortie standard)

printf("%d ",x);
Ecrit

directement sur la sortie standard

JC Rgin - Intro C - L2I - 2011

On affiche quelque chose


1.20

#include #i l d <stdio.h> < tdi h> int main (void) { int x = 3; int y = 4; double z = 1.0; fprintf(stdout," p ( , x = %d, , y = %d", , x, , y) y); while (y > 0) { z *= x; y -= 1; } fprintf(stdout, " , z = %.2f \ n", z); return 0; }
JC Rgin - Intro C - L2I - 2011

Compilation et excution
1.21

O compile On l et on excute.
gcc -Wall -pedantic -ansi foo.c a.out

x = 3, y = 4, z = 81.00 Le programme calcule 34 et affiche les valeurs de x, y et z. En C, il n'y a pas d'instructions d'E/S. En revanche, il existe d fonctions des f i de d bibliothque, bibli h dont d l le fichier fi hi de d d dclarations l i s'appelle stdio.h (standard input-output. .h pour headers . L fonctions Les f ti de d bibliothque bibli th d'E/S font f t partie ti de d la l bibliothque C: libc
JC Rgin - Intro C - L2I - 2011

Compilation et excution
1.22

Le compilateur l C utilis l est celui l d du projet : gcc. Du fichier source au fichier excutable, diffrentes tapes sont effectues ff :
le prprocesseur cpp; le l compilateur il t C cc t traduit d it l le programme source en un programme quivalent en langage d'assemblage; l l'assembleur assembleur as construit un fichier appel objet contenant le code machine correspondant; l'diteur de liens ld construit le programme excutable partir des fichiers objet et des bibliothques (ensemble de fichiers objets prdfinis).

JC Rgin - Intro C - L2I - 2011

Compilation et excution
1.23

Les fichiers objets sont suffixs par .o sous Unix et .obj sous Windows Les librairies sont suffixes par .a .sl .sa sous Unix et par .lib sous Windows Les librairies charges dynamiquement (lors de lexcution l excution du programme et non aps lors de l ldition dition de liens) sont suffixes par .so sous Unix et .dll sous Windows. Windows

JC Rgin - Intro C - L2I - 2011

Options du compilateur
1.24

Q l Quelques options ti d du compilateur il t


-c : pour n'obtenir que le fichier objet (donc l'diteur de liens n'est pas appel). p pp ) -E : pour voir le rsultat du passage du prprocesseur. -g : pour le dbogueur symbolique (avec les noms des fonctions). -o : pour renommer la sortie. -Wall : pour obtenir tous les avertissements. -lnom_de_bibliothque lnom de bibliothque : pour inclure une bibliothque prcise. prcise -ansi : pour obtenir des avertissements certaines extensions non ansi de gcc. -pedantic : pour obtenir les avertissements requis par le C standard strictement \ansi.

JC Rgin - Intro C - L2I - 2011

Calcul dune d une puissance


1.25

#include #i l d <stdio.h> di h double puissance (int a, int b) { /* Rle : retourne a^b (ou 1.0 si b < 0) */ double z = 1.0; while (b > 0) { z *= a; b -= 1; } return z; } int main (void) { fprintf(stdout," 3^4 = %.2f \ n",puissance(3, 4)); fprintf(stdout," 3^0 = %.2f \ n",puissance(3, 0)); return 0; }
JC Rgin - Intro C - L2I - 2011

Dfinition de fonctions
1.26

En C, C on peut dfinir d f des d fonctions. f La fonction principale main appelle la fonction puissance i , afin fi d de calculer l l 3^4 et affiche ffi h le l rsultat. l Elle Ell appelle aussi la fonction puissance avec les valeurs 3 et 0 et affiche le rsultat. rsultat Remarque : Pour compiler, l encore, il n'y a aucun changement.
gcc -Wall -pedantic -ansi foo.c a.out

3^4 = 81.00 3^0 = 1.00


JC Rgin - Intro C - L2I - 2011

Dclarations : prototype
1.27

double d bl puissance i (i (int t a, int i t b) { /* corps de la fonction puissance dclarations instructions */ } Si on utilise ili une f fonction i avant sa dfinition dfi i i alors l il faut f la l dclarer en utilisant ce que lon appelle un prototype :

double puissance (int, (int int);

Le compilateur en a besoin pour sy retrouver L'utilisation L utilisation de prototypes permet une dtection des erreurs sur le type et le nombre des paramtres lors de l'appel effectif de la fonction.
JC Rgin - Intro C - L2I - 2011

Lecture au clavier
1.28

int x; fscanf(stdin, "%d %d ", , &x);


Lit

un entier dans le fichier stdin (entre standard)

scanf("%d ", &x);


Lit

directement sur lentre standard

JC Rgin - Intro C - L2I - 2011

Puissance : lecture au clavier


1.29

#include #i l d <stdio.h> < tdi h> double puissance (int a, int b) { /* Rle : retourne a^b (ou 1.0 si b < 0) */ double z = 1.0; while hil (b > 0) { z *= a; b -= 1; } ret rn z; return } int main (void) { int x; int y; fprintf(stdout, " x = "); fscanf(stdin, "%d ", &x); fprintf(stdout, " y = "); fscanf(stdin, "%d ", &y); fprintf(stdout," x = %d, y = %d, x^y = %.2f \ n ",x, y,puissance(x, y)); return 0; } JC Rgin - Intro C - L2I - 2011

Lecture au clavier
1.30

Dans les D l prcdentes d t versions, i pour modifier difi les l valeurs l de d x et de y, il fallait modifier le texte source du programme, le recompiler p et l'excuter. En C, on peut demander l'utilisateur des valeurs sur l'entre standard. gcc -Wall -pedantic -ansi foo.c a.out x=3 y=4 x = 3, y = 4, x^y = 81.00
JC Rgin - Intro C - L2I - 2011

Un autre exemple
1.31

crire sur l la sortie standard d d ce qui est lu l sur l'entre l' standard d d (l'entre et la sortie standard sont ouvertes par dfaut). En pseudo-langage pseudo langage : variable c : caractre dbut lire(c) tantque non findefichier(entre) faire crire(c) lire(c) fintantque fin
JC Rgin - Intro C - L2I - 2011

En C :
1.32

#include #i l d <stdio.h> di h int main (void) { char c; c = fgetc(stdin); while (c != EOF) { fputc(c, stdout); c = fgetc(stdin); } return 0; ; }
JC Rgin - Intro C - L2I - 2011

En C : (en plus court)


1.33

#include <stdio.h> int main (void) { char c; while ((c = fgetc(stdin)) != EOF){ fputc(c, stdout); } return 0; }

JC Rgin - Intro C - L2I - 2011

Un autre exemple
1.34

Compter l C le nombre b de d caractres lus l sur l'entre l' standard d d et crire le rsultat sur la sortie standard. E pseudo-langage En d l : variable nb : entier dbut nb := 0 q non fdf(entre) ( ) faire tantque nb := nb + 1 fintantque afficher(nb) ff h ( b) fin
JC Rgin - Intro C - L2I - 2011

Une premire version


1.35

Une premire U i version i (l (les fonctions f ti non dclares d l avant tl leur utilisation tili ti sont t considres id comme renvoyant un entier) : #include <stdio.h> long g compte p ( (void); ); / /* dclaration de compte p */ / /* Rle : compte le nombre de caractres lus sur lentre standard jusqu une fin de fichier */ int main (void) { fprintf(stdout, "nb nb de caractres = %ld \ n n", , compte()); return 0; } long compte (void) { /* dfinition de compte */ l long nb; b nb = 0; while (fgetc(stdin) != EOF){ nb += 1; } return nb; }
JC Rgin - Intro C - L2I - 2011

En C :
1.36

#include #i l d <stdio.h> tdi h extern long compte (void); /* Rle : compte le nombre de caractres lus sur lentre standa d j standard jusqu sq une ne fin de fichie fichier */ int main (void) { fprintf(stdout, "nb de caractres = %ld \ n", compte()); return 0; } long compte (void) { l long nb b = 0 0; for (; fgetc(stdin) != EOF; nb++){ /* Rien */; } return nb; }
JC Rgin - Intro C - L2I - 2011

Compilation spare
1.37

O veut rutiliser On ili le plus possible les codes existants


On

organise le code : on le spare par thme, par module :

Les fonctions de maths Les fonctions dentre/sortie (affichage/saisie)


On

met un ensemble de code source de fonctions (dfinition des fonctions) dans le mme fichier .c Pour donner accs aux autres ces fonctions, on doit donner leur signature g (type ( yp de retour, , nombre de paramtres, p , type yp des paramtres) = dclaration. On met ces dclarations dans un fichier publique le .h
JC Rgin - Intro C - L2I - 2011

Compilation spare
1.38

fichier math.h : fichier de dclarations double puissance (int , int); /* Rle Rl : retourne t a^b ^b (ou ( 1.0 1 0 si i b < 0) */

JC Rgin - Intro C - L2I - 2011

Compilation spare
1.39

f h math.c fichier th : fichier f h de d dfinitions d f #include "math.h" double puissance (int a, int b) { double z = 1 1.0; 0; while (b > 0) { z *= a; b--; } return z; }
JC Rgin - Intro C - L2I - 2011

1.40

Fichier Fi hi essai.c essai c : fichier fi hi principal i i l #include <stdio.h> #include <stdlib.h> #include "math.h" int main (int argc, char *argv[]) { if (argc != 3) { fprintf(stderr, " usage: %s x y>=0 (x^y ) \ n", argv[0]); return 1; } int x = atoi(argv[1]); int y = atoi(argv[2]); if (y < 0) { fprintf(stderr, " usage: %s x y>=0 (x^y ) \ n", argv[0]); return 2; } printf("x printf( x = %d %d, y = %d %d, z = % %.2f 2f \n \n" ,x, x y, y puissance(x, puissance(x y)); return 0; }

JC Rgin - Intro C - L2I - 2011

Compilation spare
1.41

Compilation C il ti d du programme compos d des fichiers fi hi essai.c i et t math.[hc] $ gcc -Wall -pedantic -ansi -o vasy \ math.c essai.c $ ou bien $ gcc -c c -Wall Wall -pedantic pedantic -ansi ansi math.c $ gcc -c -Wall -pedantic -ansi essai.c $ gcc -o o vasy math.o essai.o $
JC Rgin - Intro C - L2I - 2011

Dclarations et code
1.42

O va sorganiser On un peu

Il faut une dclaration avant utilisation


Prototypes P t t mis i d dans un fichier fi hi : les l .h h Code source des dfinitions : les .c Certains fichiers sont dj j compils p (les ( objets) j ) : les .o On a des librairies (comme libc ou les maths) : les .so

Il faut arriver grer tout cela :


On compile les .c avec les .h, On ne veut pas tout recompiler quand un .c est modifi, mais une modif dun d un .h peut avoir de l limportance importance On utilise les autres .o et les lib

Le gestionnaire : lutilitaire make avec les makefile


JC Rgin - Intro C - L2I - 2011

Utilitaire make et makefile


1.43

Existe partout (make sur Linux, nmake sur windows) Excute une suite dinstructions contenues dans un fichier dit makefile Souvent le fichier makefile s sappelle appelle Makefile Structure du fichier entree: t d d dpendances action raliser Attention tabulations importantes !!!! Avant actions
JC Rgin - Intro C - L2I - 2011

makefile
1.44

CC= CC=gcc CFLAGS=-Wall -pedantic -ansi OBJECTS=math.o essai.o vasy : $(OBJECTS) $(CC) -o vasy $(OBJECTS) @echo "La La compilation est finie finie" essai.o : essai.c math.h $(CC) -c $(CFLAGS) essai.c math.o h : math.c h math.h hh $(CC) -c $(CFLAGS) math.c clean : -rm -f $(OBJECTS) $ vasy *~ * print : a2ps p math.h math.c essai.c | lpr p
JC Rgin - Intro C - L2I - 2011

1.45

Remarque : Si math.o nest pas lu lors de ldition de liens, il y aura une rfrence non rsolue de la fonction puissance. $g gcc essai.c ...: In function main: ...: undefined d fi d reference f t puissance to i ... ld returned 1 exit status $
JC Rgin - Intro C - L2I - 2011

Compilation
1.46

essai.c

math.c

Preprocesseur (tout ce qui commence par #) Compilateur Assembleur

essai.o
linker

math.o
vasy

lib libc

JC Rgin - Intro C - L2I - 2011

Elments lexicaux
1.47

Commentaires C t i : /* */ Identificateurs : suite de lettres non accentues, de chiffres ou de soulign, dbutant par une lettre ou un soulign Mots rservs Classes de variables :

auto const, auto, const extern, extern register, register static, static volatile break, case, continue, default, do, else, for, goto, if, return, switch, while char, double, float, int, long, short, signed, unsigned, void enum, struct, typedef, union

Instructions :

Types :

Constructeurs de types :

JC Rgin - Intro C - L2I - 2011

Squences d dchappement chappement


1.48

\ \a \b \f \ \n \r \t \v \\ \? \ \ \" \o \oo \ooo \xh \xhh

S Sonnerie i Retour arrire Saut de p page g Fin de ligne Retour chariot Tabulation horizontale Tabulation verticale B Barre lenvers l Point dinterrogation apostrophe p p guillemet Nombre octal Nombre hexadcimal
JC Rgin - Intro C - L2I - 2011

Constantes
1.49

Constantes C t t de d type t entier ti en notation t ti d dcimale, i l octale t l ou hexadcimale int unsigned g int long g long g long g ou __int64 123 12u 100L 1234LL 0173 0123u 125L 128LL 0x7b 0xAb3 0x12UL 0xFFFFFFFFFFFFFFFFLL Constantes de type rel float double 123e0 123.456e+78 12.3f 12.3L 12.3 12F long double

JC Rgin - Intro C - L2I - 2011

Constantes
1.50

Constantes C t t d de t type caractre t (char) ( h ) : un caractre t entre t apostrophes


'a' a '\n'

'\141' \141 '\0'

'\x61' \x61 '\12'

en C, un caractre est considr comme un entier (conversion unaire).


char ca = 'a'; ' ' /* / tout est quivalent */ / char ca = 97; char ca = '\141'; \141 ; char ca = '\x61';

JC Rgin - Intro C - L2I - 2011

Constantes
1.51

Constantes de type chane (char *) : chane place entre guillemets


"" "here

we go" g "une chane sur \ deux lignes" g "et" "une une autre autre"

JC Rgin - Intro C - L2I - 2011

Variables
1.52

Une variable est un nom auquel on associe une valeur que le programme peut modifier pendant son excution. Lors de sa dclaration, on indique son type. Il faut dclarer toutes les variables avant de les utiliser. utiliser On peut initialiser une variable lors de sa dclaration. On peut prfixer toutes les dclarations de variables par const (jamais modifis).

JC Rgin - Intro C - L2I - 2011

Variable
53

i t x; // Rserve int R un emplacement l t pour un entier ti en mmoire. i x = 10; // Ecrit la valeur 10 dans l'emplacement rserv.

Une variable est destine contenir une valeur du type avec lequel l l elle ll est d dclare. l Physiquement cette valeur se situe en mmoire. int x;

JC Rgin - Intro C - L2I - 2011

Variable
54

i t x; // Rserve int R un emplacement l t pour un entier ti en mmoire. i x = 10; // Ecrit la valeur 10 dans l'emplacement rserv.

int x; x=10; ; &x : adresse de x en C : ici 62


Adresse

= numro de la case mmoire


JC Rgin - Intro C - L2I - 2011

Types lmentaires
1.55

Si ou pas : Sign

unsigned : non sign pas de ngatif si n bits : 0 .. (2n 1) signed : sign, ngatifs, si n bits -2n-1 .. (2n-1 1) ne peut pas tre considr comme un type normal char , sign par dfaut : -128..+128 unsigned char : 0..255 parfois appel byte short, sign par dfaut en gnral sur 16 bits int, sign par dfaut, sinon unsigned int peut scrire unsigned : 32 bits en gnral long sign par dfaut . Attention 32 ou 64 bits long, long long sur 64 bits

Type spcial : void

Type caractre :

Type entier :

JC Rgin - Intro C - L2I - 2011

Types lmentaires
1.56

Type rel :
float,

sign, en gnral 32 bits double, 32 ou 64 bits long g double, , souvent 64 bits

PAS de type boolen : 0 reprsente le faux, et une valeur diffrente de 0 le vrai. vrai ATTENTION nombre de bits du type nest pas dans le langage. l
JC Rgin - Intro C - L2I - 2011

Norme IEEE 754


1.57

Le standard IEEE en format simple prcision utilise 32 bits pour reprsenter un nombre rel x : x = (-1)S x 2E-127 x 1,M
S

est le bit de signe (1 bit), E l'exposant (8 bits), M la mantisse (23 bits)

Pour la double et quadruple prcision, seul le nombre de bits de l'exposant et de la mantisse diffrent.
JC Rgin - Intro C - L2I - 2011

Type numr
1.58

#include <stdio.h> <stdio h> enum Lights { green, yellow, red }; enum Cards { diamond=1, spade=-5, club=5, heart }; enum Operator { Plus = '+', Min = '-', Mult = '*', Div = '/' }; int main (void) { enum Lights feux = red; enum Cards jeu = spade; enum Operator op = Min; printf( L = %d %d %d\n" printf("L %d\n , green, green yellow yellow, red); printf("C = %d %d %d %d\n", diamond, spade, club, heart); printf("O = %d %d %d %d\n", Plus, Min, Mult, Div); jeu = yellow; printf("%d printf( %d %d %c\n" %c\n , feux, feux jeu, jeu op); return 0; }
JC Rgin - Intro C - L2I - 2011

Type numr
1.59

On peut affecter ou comparer des variables de types numrs. Un type numr est considr comme de type int : la numrotation commence 0, , mais on p peut donner n'importe quelles valeurs entires. Comme on a pu le remarquer, remarquer il n n'y y a pas de vrification.

JC Rgin - Intro C - L2I - 2011

Types structurs
1.60

#include <stdio.h> <stdio h> int main (void) { int t[4]; int i; int j; int u[] = {0, 1, 2, 3}; float x[3][10]; char w[][3] = {{'a', 'b', 'c'}, {'d', 'e', 'f'}}; for (i = 0; i < 4; i++) { t[i] = 0; printf("t[%d]=%d ", i, t[i]); } fputc('\n', stdout); for (i = 0; i < 2; i++) { for (j = 0; j < 3; j++) { w[i][j] = 'a'; fprintf(stdout, "w[%d][%d]=%c ", i, j, w[i][j]); } fputc('\n' fputc( \n , stdout); } return 0; }

JC Rgin - Intro C - L2I - 2011

Tableaux
1.61

JC Rgin - Intro C - L2I - 2011

Tableaux
1.62

Tableaux T bl une seule l dimension di i : possibilit ibilit d de t tableau bl d de tableau. Dans ce cas, cas la dernire dimension varie plus vite. vite Indice entier uniquement (borne infrieure toujours gale 0). ) On peut initialiser un tableau lors de sa dclaration (par agrgat). Dimensionnement automatique par agrgat (seule la premire dimension peut ne pas tre spcifie). L oprations Les ti se font f t l lment t par l lment. t Aucune A vrification sur le dpassement des bornes.
JC Rgin - Intro C - L2I - 2011

Tableaux
1.63

La dimension L di i doit d it t tre connue statiquement t ti t (lors (l d de la l compilation) il ti ) int n = 10; int t[n]; [ ]; /* INTERDIT */ Ce qu'il faut plutt faire : #define N 10 ... int t[N]; / /* c c'est est le prprocesseur qui travaille */ / On verra plus tard comment dfinir des tableaux de faon dynamique (taille connue lexcution)

JC Rgin - Intro C - L2I - 2011

Tableaux : initialisation
1.64 #incl de <stdio.h> #include <stdio h> void init (int t[], int n, int v) { int i; for (i = 0; i < n; i++) t[i] = v; } } void aff (int t[], int n) { i t i; int i for (i = 0; i < n; i++){ printf("%d ", t[i]); } printf("\n"); ( ) } int main (int argc, char *argv[]) { int tab[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; aff(tab 5); aff(tab, init(tab, 5, 0); aff(tab, 10); return 0; }

JC Rgin - Intro C - L2I - 2011

Chaines de caractres
1.65

Ce sont C td des tableaux t bl de d caractres t : ce nest t donc d pas un vrai i type. t Par convention, elles se terminent par le caractre nul \0 (valeur 0). Il n'y a pas d'oprations pr-dfinies (puisque ce n'est pas un type), mais il existe des fonctions de bibliothque, dont le fichier de dclarations s'appelle ' string.h (toutes ces fonctions suivent la convention). char string1[100]; char s[15] = {'b', 'o', 'n', 'j', 'o', 'u', 'r', '!', '\0'}; /* "bonjour!" */ char chiffres[] = "0123456789"; 0123456789 ; char *chiffresb = "0123456789"; Ecriture sur la sortie standard :

printf("%s",chiffres); fputs(chiffres,stdout);
JC Rgin - Intro C - L2I - 2011

Chaines de caractres
1.66

JC Rgin - Intro C - L2I - 2011

Chaines de caractres : initialisation


1.67

#include <stdio.h> <stdio h> #include <string.h> int main (void) { char chaine[] = "bonjour "; char chRes[256]; printf("%s\n", strcpy(chRes, chaine)); printf("%s\n", strcat(chRes, "tout le monde!")); printf("%s\n", chRes); return 0; }
JC Rgin - Intro C - L2I - 2011

Structures
1.68

#include <stdio.h> <stdio h> struct date { short jour, mois, annee; }; struct personne { int num; /* numro de carte */ struct date neLe; short tn[3]; /* tableau de notes */ }; int main (void) { struct personne p; struct personne etud[2]; , n, , somme; ; short e, p.num = 15; p.neLe.jour = 5; p.neLe.mois = 10; p.neLe.annee = 1992; p.tn[0] p [ ] = 10; ; p.tn[1] = 15; p.tn[2] = 20; etud[0] = p;

JC Rgin - Intro C - L2I - 2011

Structures
1.69 int main (void) { struct personne p, etud[2]; short e, n, somme; p.num = 15; p.neLe.jour = 5; p.neLe.mois = 10; p neLe annee = 1992; p.neLe.annee p.tn[0] = 10; p.tn[1] = 15; p.tn[2] = 20; etud[0] = p; p.num = 20; p.neLe.jour L j = 1; 1 p.neLe.mois = 1; p.neLe.annee = 1995; p.tn[0] = 0; p.tn[1] = 5; p.tn[2] = 10; etud[1] t d[1] = p; for (e = 0; e < 2; e++) { somme = 0; for (n = 0; n < 3; n++){ somme = somme + etud[e].tn[n]; } printf("moy de %d, ne en %d = %.2f\n", etud[e].num, etud[e].neLe.annee, somme/(double)3); } return 0; }

JC Rgin - Intro C - L2I - 2011

Structures
1.70

struct t t personne { int num; /* numro de carte */ ; struct date neLe; short tn[3]; /* tableau de notes */ }; Objet composite form d'lments de types quelconques. La place rserve est la somme de la longueur des champs ( minimum, (au i i cause de d l'alignement). l' li t) On peut affecter des variables de types structures. L de Lors d l la d dclaration l ti d de variables i bl de d types t structures, t t on peut initialiser avec un agrgat.
JC Rgin - Intro C - L2I - 2011

Union
1.71

union aword { unsigned int i; unsigned char b[4]; unsigned short s[2]; }; const aword a ={ buf[k]}; / /* initialisation */ / if (a.i) cnt += (lut[a.b[0]] + lut[a.b[1]] + lut[a.b[2]] + lut[a b[3]]); lut[a.b[3]]);

JC Rgin - Intro C - L2I - 2011

Union
1.72

La place rserve est le maximum de la longueur des champs. Sert partager la mmoire dans le cas o l'on a des objets j dont l'accs est exclusif. Sert interprter la reprsentation interne d'un objet comme s'il s il tait d'un d un autre type. type

JC Rgin - Intro C - L2I - 2011

Champs de bits
1.73

#include #i l d <stdio.h> < tdi h> typedef struct { unsigned rouge : 10; unsigned d vert : 10; 10 unsigned bleu : 10; unsigned : 2; } couleur; int main (void) { couleur rouge g = {0x2FF, { , 0x000, , 0x000}, }, vert = { {0x133, , 0x3FF, , 0x133}, }, bleu = {0x3FF, 0x3FF, 0x2FF}; printf("rouge = %x\tvert = %x\tbleu = %x\n", rouge, vert, bleu); printf("rouge = %u\tvert = %u\tbleu = %u\n",rouge, vert, bleu); return 0; }
JC Rgin - Intro C - L2I - 2011

Champs de bits
1.74

Pour les champs de bits, on donne la longueur du champ en bits; longueur spciale 0 pour forcer l'alignement (champ sans nom pour le remplissage). Attention aux affectations (gauche droite ou vice versa). Utiliser pour coder plusieurs choses sur un mot :
Je

veux coder les couleurs sur un mot machine (ici 32 bits) 3 couleurs l donc10 d 10 bits bi par couleur l au lieu li d dun octet

JC Rgin - Intro C - L2I - 2011

Champs de bits
1.75

Dpend D d fortement f t td de la l machine, hi donc d difficilement diffi il t transportable. Architectures droite gauche : little endian (petit bout)
Octet de poids faible en premier (adresse basse) x86

Architectures gauche droite : big endian (gros bout)


Octet de poids fort en premier (adresse basse) Motorola 68000

Souvent S t remplac l par des d masques binaires bi i et t des d dcalages


JC Rgin - Intro C - L2I - 2011

Dfinition de types : typedef


1.76

M t l typedef (trs Mot-cl (t utilis). tili ) P Permet td de dfinir dfi i d de nouveau t type ( (aide id le l compilateur) il t ) typedef int Longueur; typedef char tab_car[30]; typedef struct people { char Name[20]; short Age; long SSNumber; } Human; typedef struct node *Tree; Tree; typedef struct node { char *word; Tree left; Tree right; } Node; yp int ( (*PFI) ) (char ( *, , char *); ); typedef
JC Rgin - Intro C - L2I - 2011

Instructions : instruction vide


1.77

Dnote par le point-virgule. Le point-virgule sert de terminateur dinstruction : la liste des instructions est une suite dinstructions se terminant toutes par un ;. for (; (fgetc(stdin) != EOF); nb++) /* rien */ ; Note :
Ne

pas mettre systmatiquement un ; aprs la parenthse fermante du for... Mettre toujours des { }, avec les if et les for
JC Rgin - Intro C - L2I - 2011

Expression, affectations et instructions


1.78

En gnral
instruction

= action expression = valeur

Une expression a un type statique (cest--dire qui ne d d pas d dpend de lexcution l ti d du programme) ) et t une valeur. l Laffectation en C est dnote par le signe =.

JC Rgin - Intro C - L2I - 2011

Affectation compose
1.79

partie_gauche ti h ?= ? expression i ? est lun des oprateurs suivants :


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

int main (int argc, char *argv[]) { int a, b; a = b = 3; 3; /* warning: statement with no effect */ a += 3; /* a = a + 3 */ a -= 6: 6 /* a = a 6; 6 */ a *= 3 - 5; /* a = a * (3 - 5) */ a *= (3 - 5); /* a = a * (3 - 5) */ return 0; }

JC Rgin - Intro C - L2I - 2011

Bloc
1.80

Sert S t grouper plusieurs l i instructions i t ti en une seule. l Sert restreindre (localiser) la visibilit dune variable. Sert marquer le corps dune fonction. #include <stdio.h> int main (int argc, argc char *argv[]) argv[]) { int i = 3, j = 5; { int i = 4; printf(" f( i = %d, % j=% %d \ n ", i, j); ) i++; j++; } printf(" i = %d, printf( %d j = %d \ n n", i, i j); / /* valeur de i et j ? */ / return 0; }
JC Rgin - Intro C - L2I - 2011

Instruction conditionnelle
1.81

Il ny a pas de mot-cl alors et la partie sinon est facultative. La condition doit tre parenthse. Rappel : en C C, il ny n y a pas dexpression d expression boolenne ; une expression numrique est considre comme faux si sa valeur est gale 0, 0 vrai sinon. sinon

JC Rgin - Intro C - L2I - 2011

Instruction Conditionnelle
1.82

#include <stdio.h> <stdio h> #include <stdlib.h> int main (int argc, char *argv[]) { int x, x y = -3, 3 z = -5; 5; printf(" valeur de x? "); scanf("%d ", &x); if (x == 0) x = 3; else if (x == 2) { x = 4; y = 5; } else z = x = 10; printf(" x = %d, y = %d, z = %d \ n", x, y, z); if (0) x = 3; else x = 4; /* / viter */ / return 0; }
JC Rgin - Intro C - L2I - 2011

Instruction Conditionnelle
1.83

#include <stdio.h> <stdio h> #include <stdlib.h> int main (int argc, char *argv[]) { int x, y = -3, z = -5; printf(" valeur de x? "); printf( ); scanf("%d ", &x); if (x == 0) { x = 3; } else { if (x == 2) { x = 4; y = 5; } else { z = x = 10; } } printf(" x = %d, y = %d, z = %d \ n", x, y, z); if (0) x = 3; else x = 4; return 0; }

JC Rgin - Intro C - L2I - 2011

Aiguillage (switch)
1.84

L encore, lexpression doit tre parenthse. Les tiquettes q de branchement doivent avoir des valeurs calculables la compilation et de type discret. Pas derreur d erreur si aucune branche nest n est slectionne slectionne. Excution des diffrentes branches en squentiel : ne pas oublier bli une instruction i t ti de d dbranchement db h t (break b k par exemple)

JC Rgin - Intro C - L2I - 2011

Switch
1.85 #include <stdio.h> <stdio h> int main (int argc, char *argv[]) { short i = 0, nbc = 0, nbb = 0, nba = 0; if (argc != 2) { fprintf(stderr, " usage: %s chane \ n", argv[0]); return t 1; 1 } while (argv[1][i]) { switch (argv[1][i]) { case 0 : case 1 : case 2 : case 3 : case 4 : case 5 : case 6 : case 7 : case 8 : case 9 : nbc++; break; case : case \ t : case \n : nbb++; break; default : nba nba++; ; }; i++; } printf(" chiffres = %d, blancs = %d , autres = %d \ n", nbc, nbb, nba); return 0;}

JC Rgin - Intro C - L2I - 2011

Les boucles
1.86

while (expression_entire) (expression entire) instruction #include #i l d <stdio.h> tdi h #define MAX 30 int main ( (int argc, g , char *argv[]) g []) { char tab[MAX], c; int i; i = 0; while ((i < MAX - 1) && (c = fgetc(stdin)) != EOF){ tab[i++] = c; } []=\0; tab[i] printf(" \n %s\ n ", tab); return 0; }
JC Rgin - Intro C - L2I - 2011

Les boucles
1.87

do instruction while (expression_entire); #include <stdio.h> #include <string.h> #include <ctype.h> <ctype h> #define NB 3 int main (int argc, char *argv[]) { char rep[NB]; do { printf(" Voulez vous sortir ? " ); fgets(rep, NB, stdin); rep[0] = toupper(rep[0]); } while (strcmp(rep, "O\ n")); return 0; }
JC Rgin - Intro C - L2I - 2011

Les boucles
1.88

for (init; cond_continuation; cond continuation; rebouclage) instruction quivalent init; while ( (cond_conti) ){ instruction; rebouclage; } #include <stdio.h> #define MAX 30 int main (int argc, char *argv[]) { char tab[MAX] [ ] = "toto"; ; int i; printf("*%s*\n" ,tab); for (i = 0; i < MAX; i++) tab[i] = \ 0 ; printf("*%s*\n" p ( ,tab); , ); return 0; }

JC Rgin - Intro C - L2I - 2011

Les boucles
1.89

#include <stdio.h> <stdio h> int main (int argc, char *argv[]) { int i; i = 0; while (i < 10) { i++; } printf(" i = %d \ n ", i); i = 0; do { i++; } while (i < 10); printf(" i = %d \ n ", i); (i = 0; i < 10; i++); ) for ( printf(" i = %d \ n ", i); return 0;
JC Rgin - Intro C - L2I - 2011

Instructions de dbranchement
1.90

b k break

Utilise dans un switch ou dans une boucle Se dbranche sur la premire instruction qui suit le switch ou la boucle Utilise dans les boucles Poursuit l lexcution excution de la boucle au test (ou au rebouclage) saute ltiquette donne ltiquette, etq par exemple, est place comme suit
etq :

continue

goto

return

Provoque la sortie dune fonction La valeur de retour est place derrire le mot-cl
JC Rgin - Intro C - L2I - 2011

Fonction exit
1.91

Fonction exit
Met

fin lexcution dun programme 0 en paramtre indique larrt normal

JC Rgin - Intro C - L2I - 2011

Dbranchements : exemple
1.92

#include <stdio.h> <stdio h> void f(int j){ int i = 0; while hil (i < j) { /* instruction? */ i++; } printf(" f i n de f , i = %d \ n ", i); } int main (int argc, char *argv[]) { int i = 100; f(i); printf(" i tf(" f i n d de main i , i = %d \ n ", " i) i); return 0; }
JC Rgin - Intro C - L2I - 2011

Dbranchements : exemple
1.93

Instruction? b k break; continue; return; exit(2); /* aucune instruction */

Rsultat fi de fin d f, f i=0 fin de main, i = 100 Ca boucle fin de main, i = 100 fin de f, i = 100 fin de main, i = 100

JC Rgin - Intro C - L2I - 2011

Oprateurs
1.94

Affectation Cest un oprateur p (signe ( g =) ) dont les oprandes p sont de tout type (attention si de type tableau). Cas particulier des oprateurs unaires (din-/d)crmentation: ++, --. Att ti : lordre Attention l d dvaluation d l ti nest t pas garanti. ti t[i++] = v[i++]; /* viter */ i = i++; i++ nest pas dfini dfi i
JC Rgin - Intro C - L2I - 2011

Oprateurs de calcul
1.95

Arithmtiques A ith ti Relationnels L i Logiques Bit bit

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

3+4 3*4+5 3/4 30/4 3.0 3%4 !(n % 2) (x = 1) || b (x = 0) && b


JC Rgin - Intro C - L2I - 2011

Oprateurs de calcul
1.96

#include #i l d <stdio.h> tdi h int main (int argc, char *argv[]) { short i; for (i = 0; i < 10; i++){ printf("i i tf("i = %h %hx ,~i i = %h %hx",i,~i); " i i) printf("!i = %hx ,i << 1 = %hx", !i, i << 1); printf("i printf( i >> 1 = %hx \ n ",i i >> 1); } return 0; }
JC Rgin - Intro C - L2I - 2011

Oprateurs de calcul
1.97

Rsultat R lt t : i = 0, ~i = ffff, !i = 1, i << 1 = 0, i >> 1 = 0 i=1 1, ~i = fffe fffe, !i = 0 0, i << 1 = 2 2, i >> 1 = 0 i = 2, ~i = fffd, !i = 0, i << 1 = 4, i >> 1 = 1 i = 3, ~i i = fffc, !i = 0, i << 1 = 6, i >> 1 = 1 i = 4, ~i = fffb, !i = 0, i << 1 = 8, i >> 1 = 2 i = 5, ~i = fffa, !i = 0, i << 1 = a, i >> 1 = 2 i = 6, ~i = fff9, !i = 0, i << 1 = c, i >> 1 = 3 i = 7, ~i = fff8, !i = 0, i << 1 = e, i >> 1 = 3 i = 8, ~i = fff7, !i = 0, i << 1 = 10, i >> 1 = 4 i = 9, ~i = fff6, !i = 0, i << 1 = 12, i >> 1 = 4
JC Rgin - Intro C - L2I - 2011

Oprateurs sur les types


1.98

Taille dun objet (nombre ( doctets ncessaires la mmorisation dun objet) sizeof(nom_type) sizeof expression Renvoie une valeur de type size_t dclar dans le fichier de dclarations stdlib.h.
size_t

: taille dun mot machine


JC Rgin - Intro C - L2I - 2011

Oprateurs sur les types


1.99

#include <stdio.h> <stdio h> #define imp(s, t) printf(" sizeof %s = %d \ n", s, sizeof(t)) int main (int argc, char *argv[]) { i t t1[10]; int t1[10] float t2[20]; imp(" char ", char); imp(" short ", short); imp( imp(" int ", int); imp(" long ", long); imp(" float ", float); i (" double imp(" d bl " ", double); d bl ) imp(" long double ", long double); printf(" sizeof t1 = %d, sizeof t2 = %d \ n",sizeof t1, sizeof t2); printf(" sizeof t1 [0] = %d, printf( %d sizeof t2 [1] = %d \ n n",sizeof t1[0], t1[0] sizeof t2[1]); return 0; }
JC Rgin - Intro C - L2I - 2011

Oprateurs sur les types


1.100

Excution : $ a.out sizeof char = 1 sizeof short = 2 sizeof int = 4 sizeof long = 4 sizeof float = 4 sizeof double = 8 sizeof long double = 12 sizeof t1 = 40, sizeof t2 = 80 sizeof t1[0] = 4, sizeof t2[1] = 4 $
JC Rgin - Intro C - L2I - 2011

Oprateurs sur les types


1.101

#include <stdio.h> <stdio h> #include <string.h> void f (int t[]) { printf(" p ( f : sizeof t = %d, , sizeof t [ [0] ] = %d \ n", ,sizeof t, , sizeof t[0]); [ ]); } void g (char s[]) { printf("g: sizeof s = %d, sizeof s[0] = %d \ n",sizeof s, sizeof s[0]); printf("g: printf( g: l g r de s = %d \ n ", strlen(s)); } int main (int argc, char *argv[]) { [ ]; int t1[10]; char s1[] = " 12345"; printf(" main : sizeof t1 = %d \ n", sizeof t1); f(t1); printf(" main : sizeof s1 = %d, s t r l e n ( s1) = %d \ n",sizeof s1, strlen(s1)); g(s1); ( 1) return 0; }

JC Rgin - Intro C - L2I - 2011

Oprateurs sur les types


1.102

Excution : $ a.out main: sizeof t1 = 40 f: sizeof t = 4, 4 sizeof t[0] = 4 main: sizeof s1 = 6, strlen(s1) = 5 g: sizeof s = 4, sizeof s[0] = 1 g: lgr de s = 5 $
JC Rgin - Intro C - L2I - 2011

Casting ou transtypage
1.103

Conversion C i explicite li it ( ( casting ti ou transtypage) t t ) (type) expression #include <stdio.h> int main (int argc, argc char *argv[]) { printf("%.2 f ", 3/(double)4); printf("%d p ( ", (int)4.5); ) ) printf("%d ", (int)4.6); printf("%.2 f ", (double)5); fputc( \n \n , stdout); return 0; }
JC Rgin - Intro C - L2I - 2011

Oprateur de condition
1.104

condition ? expression_si_vrai expression si vrai : expression_si_faux expression si faux Seul oprateur ternaire du langage. #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int x, y, n; if (argc != 2) { fprintf(stderr " usage: %s nb \ n ", argv[0]); return 1; fprintf(stderr, } n = atoi(argv[1]); x = (n % 2) ? 0 : 1; y = (n == 0) ? 43 : (n == -1) ? 52 : 100; printf(" x = %d , y %d \ n ", x, y); return 0; }
JC Rgin - Intro C - L2I - 2011

Oprateur virgule
1.105

Le rsultat de expr1, expr2, , exprn est le rsultat de exprn expr1, expr2, , expr(n-1) sont values, mais leurs rsultats oublis ( (sauf si effet de bord) )

JC Rgin - Intro C - L2I - 2011

Oprateur virgule
1.106

#include <stdio.h> (int argc, g , char *argv[]) g []) { int main ( int a, b, i, j, t[20]; for ( (i = 0, , j = 19; ; i < j; i++, , j--) j ) t[i] = t[j]; printf("%d printf( %d \ n ", , (a = 1, b = 2)); printf("%d \ n ", (a = 1, 2)); return 0; }
JC Rgin - Intro C - L2I - 2011

Oprateurs
1.107

Types
postfix unaire casting multiplicatif additif dcalage relationnel (in)galit et bit bit xor ou bit bit et logique ou logique condition affectation virgule

Symboles
(), [], ., ->, , ++, , -&, *, +, -, ~, !, ++, --, sizeof (<type>) *, /, % +, <<, >> <, >, <=, >= ==, != & ^ | && || ? =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |= JC Rgin - Intro C - L2I - 2011 ,

Associativit
GD DG DG GD GD GD GD GD GD GD GD GD GD DG DG GD

Pointeurs
1.108

Les p pointeurs sont trs utiliss en C. En gnral, ils permettent de rendre les programmes
plus

compacts, compacts plus efficaces,

L'accs un objet se fait de faon indirecte.

JC Rgin - Intro C - L2I - 2011

Pointeurs
1.109

int i t x; // alloue ll d de la l mmoire i pour x x=10; // met 10 dans la(les) case(s) mmoire correspondant x On ne peut pas dcider de lemplacement mmoire (adresse) de x On ne peut pas changer ladresse de x Les pointeurs vont permettre de faire cela int *p; p; // pointeur reprsent avec une * Toute variable contient une valeur : la valeur dun pointeur est une adresse p= &x;

JC Rgin - Intro C - L2I - 2011

Pointeurs
1.110

int i t *p; * pointeur i t Toute variable contient une valeur : la valeur dun pointeur est une adresse p= &x; Drfrencement : operateur * Permet dinterprter le contenu de la case situe ladresse pointeur : du p
p=&x; //&x vaut 1234 *p contenu la mmoire la case 1234

On peut l O la li lire ( (y = * *p;) ) On peut la modifier (*p = 22;)


JC Rgin - Intro C - L2I - 2011

Pointeurs
111

i t x; // Rserve int R un emplacement l t pour un entier ti en mmoire. i x = 10; // Ecrit la valeur 10 dans l'emplacement rserv.

Une variable est destine contenir une valeur du type avec lequel l l elle ll est d dclare. l Physiquement cette valeur se situe en mmoire. int x;

JC Rgin - Intro C - L2I - 2011

Pointeurs
112

i t x; // Rserve int R un emplacement l t pour un entier ti en mmoire. i x = 10; // Ecrit la valeur 10 dans l'emplacement rserv.

int x; x=10; ; &x : adresse de x : ici 62

JC Rgin - Intro C - L2I - 2011

Pointeurs
113

i t x; // Rserve int R un emplacement l t pour un entier ti en mmoire. i x = 10; // Ecrit la valeur 10 dans l'emplacement rserv.

int x; x=10; int* px; // pointeur sur un entier

JC Rgin - Intro C - L2I - 2011

Pointeur Implmentation
114

int x; x=10; ; int* px; // pointeur sur un entier int px=&x (adresse de x)

JC Rgin - Intro C - L2I - 2011

Pointeur Implmentation
115

int x; x=10; ; int* px; // pointeur sur un entier int px=&x (adresse de x) int y=*px
JC Rgin - Intro C - L2I - 2011

Pointeur Implmentation
116

Si px contient ladresse de x

Alors *px Al * contient ti t la l valeur l d de l ladresse d d de x, d donc l la valeur de x

JC Rgin - Intro C - L2I - 2011

Pointeur Implmentation
117

S px contient ladresse de x Si

Alors *px p contient la valeur de ladresse de x, , donc la valeur de x

Si je change la valeur l ladresse adresse de x x, alors je change la valeur de x,


JC Rgin - Intro C - L2I - 2011

Pointeur Implmentation
118

Si px contient ladresse de x, donc *px la valeur de x

Si je j change h l la valeur l l ladresse d d de x, alors l je j change h la valeur de x : *px=5


5

JC Rgin - Intro C - L2I - 2011

Pointeur Implmentation
119

px=&x & Si je modifie *px alors je modifie x (mme case mmoire concerne) px=&y Si je modifie *px px alors je modifie y (mme case mmoire concerne) p px=&bidule Si je modifie *px alors je modifie bidule (mme case mmoire concerne) px dsigne lobjet point *px modifie lobjet point
JC Rgin - Intro C - L2I - 2011

Pointeurs : type
1.120

Types des pointeurs :


on

a vu quon avait besoin dinterprter le contenu des cases mmoires (2 octets pour un short, 4 pour un int, big-endian, small-endian). On va donc typer les pointeurs pour obtenir ce rsultat int *p veut dire que *p sera un int, donc int y =*p est parfaitement ok.

JC Rgin - Intro C - L2I - 2011

Pointeurs
1.121

A quoi cela sert-il ?


accs

direct la mmoire passage de paramtres p partage g dobjets j indirection passage par rfrence allocation dynamique

JC Rgin - Intro C - L2I - 2011

Pointeurs
1.122

A quoi cela sert-il ?


accs

direct la mmoire passage de paramtres p partage g dobjets j indirection passage par rfrence allocation dynamique

JC Rgin - Intro C - L2I - 2011

Pointeurs : passage de paramtre


1.123

Passage d P de paramtres t par rfrence f struct etudiant { char nom[50]; char prenom[50]; char adresse[255]; int notes[10]; }; int calculMoyenne(struct etudiant etud){ int i, sum=0; for(i 0;i 10;i ) for(i=0;i<10;i++) sum += etud.notes[i]; return sum/10; } Que se passe til quand on passe un tudiant en paramtre ?
JC Rgin - Intro C - L2I - 2011

Pointeurs : passage de paramtre


1.124

Passage d P de paramtres t par rfrence f struct etudiant { char nom[50]; char prenom[50]; p [ ]; char adresse[255]; int notes[10]; }; int calculMoyenne(struct etudiant etud){ int i, sum=0; for(i=0;i<10;i++) [ ]; sum += etud.notes[i]; return sum/10; } Il y a cration dune variable locale

on ralloue de la mmoire pour cette structure locale la structure est entirement copie p ! Donc au moins 365 oprations p !
JC Rgin - Intro C - L2I - 2011

Pointeurs : passage de paramtre


1.125

Passage de paramtres par rfrence struct etudiant { char nom[50]; char prenom[50]; char adresse[255]; int notes[10]; }; int calculMoyenne(struct etudiant etud){ int i, sum=0; for(i=0;i<10;i++) sum += etud.notes[i]; etud notes[i]; return sum/10; } Comment viter cela ?

On dfinit un tableau global de structure et on passe lindice de llment dans le tableau (je ne vois pas dautres solutions sans les pointeurs) GROS dfauts
Cela impose des donnes globales (je ne peux pas passer le tableau ! Sinon copie !) Cela impose une structure de tableau, comment gre ton les suppressions/ajouts ? Je dois connaitre la taille du tableau au dbut du programme

Cest pratiquement injouable

JC Rgin - Intro C - L2I - 2011

Pointeurs : passage de paramtre


1.126

Passage de paramtres par rfrence struct etudiant { char nom[50]; char prenom[50]; char adresse[255]; int notes[10]; }; int calculMoyenne(struct etudiant etud){ int i, sum=0; for(i=0;i<10;i++) sum += etud.notes[i]; etud notes[i]; return sum/10; } Solution : on utilise un pointeur sur la structure d dun un tudiant int calculMoyenne(struct etudiant *etud){ int i, sum=0; for(i=0;i<10;i++) sum += *(etud).notes[i]; return sum/10; } On ne passe que ladresse mmoire et on travaille avec cette adresse mmoire : il ny a pas de copie locale

JC Rgin - Intro C - L2I - 2011

Pointeurs
1.127

A quoi cela sert-il ?


accs

direct la mmoire passage de paramtres p partage g dobjets j indirection passage par rfrence allocation dynamique

JC Rgin - Intro C - L2I - 2011

Pointeurs : partages d dobjets objets


1.128

Pour chaque note on veut connaitre celui qui a la meilleure note


Premier

(meilleure note) en C Premier en Systme y Exploitation p Premier en Algorithmique Premier en Anglais

C Comment tf faire i ?
JC Rgin - Intro C - L2I - 2011

Pointeurs : partages d dobjets objets


1.129

P chaque Pour h note t on veut t connaitre it celui l i qui ial la meilleure ill note t

Premier (meilleure note) en C Premier en Systme Exploitation Premier en Algorithmique Premier en Anglais

On fait une copie chaque fois : mauvaise solution, problme de synchronisation entre les copies On utilise des indices pour dsigner chaque tudiant : problme demande une gestion sous la forme de tableau des tudiants ( (avec les l i inconvnients i t vu) ) On utilise des pointeurs !
JC Rgin - Intro C - L2I - 2011

Pointeurs : partages d dobjets objets


1.130

P chaque Pour h note t on veut t connaitre it celui l i qui i a la l meilleure ill note t

Premier (meilleure note) en C Premier en Systme Exploitation Premier en Algorithmique Premier en Anglais

On utilise des pointeurs ! struct etudiant *pC; struct etudiant *pSE; struct etudiant *pAlgo; struct etudiant *pAnglais; Un meme lment peut tre partag!
JC Rgin - Intro C - L2I - 2011

Pointeurs
1.131

A quoi cela sert-il ?


accs

direct la mmoire passage de paramtres p partage g dobjets j indirection passage par rfrence allocation dynamique

JC Rgin - Intro C - L2I - 2011

Pointeurs : indirection
1.132

Lindice dun tableau est diffrent du contenu : on fait une indirection Cest pareil avec les pointeurs Plus petit lment dun d un ensemble (ppelt)
Avec

un tableau dlment de type t : ppelt est un indice Avec A nimporte i t quelle ll structure t t d de d donnes dlment dl td de type t : ppelt est un pointeur de type t (t *ppelt)

JC Rgin - Intro C - L2I - 2011

Pointeurs
1.133

A quoi cela sert-il ?


accs

direct la mmoire passage de paramtres p partage g dobjets j indirection passage par rfrence allocation dynamique

JC Rgin - Intro C - L2I - 2011

Pointeurs : passage par rfrence


1.134

Comment C t modifier difi un paramtre t avec une f fonction ti ? int moyenne(int* t, int nbelt){ /* on calcule la moyenne y et on la retourne */ return moy; } Je veux faire : void modifierMoyenne(int* t, int nbelt, int moy){ /* je veux modifier la moyenne moy / moy*/ / moy = 12; } Cette solution ne marche pas car moy est copi dans une variable locale

JC Rgin - Intro C - L2I - 2011

Pointeurs : passage par rfrence


1.135

Un pointeur contient une adresse d mmoire. Si S on drference d f on touche directement ladresse mmoire. Cest ce quil nous faut ! void modifierMoyenne(int* t, int nbelt, int* moy){ /* je veux modifier la moyenne moy*/ *moy = 12; } Cette solution marche car on modifie ce qui est ladresse mmoire i passe en paramtre. Cest C ladresse l d qui i est passe et non plus la valeur
JC Rgin - Intro C - L2I - 2011

Pointeurs
1.136

A quoi cela sert-il ?


accs

direct la mmoire passage de paramtres p partage g dobjets j indirection passage par rfrence allocation dynamique

JC Rgin - Intro C - L2I - 2011

Pointeurs : allocation dynamique


1.137

O ne peut pas toujours connaitre la taille dune On structure de donnes au moment ou on crit le code source
Nombre

jardin ?

dtudiants luniversit ? Nombre darbres dans un

On peut surestimer mais cela peut crer des problmes All Allocation d dynamique
Comment

allouer n lments, avec n qui sera dfini l ti ? lexcution Comment dfinir cette variable dans le programme ?
JC Rgin - Intro C - L2I - 2011

Pointeurs : allocation dynamique


1.138

All Allocation d dynamique


Comment allouer n lments, avec n qui sera dfini lexcution ? Comment C dfinir dfi i cette variable i bl dans d le l programme ?

Solution : on travaille en fait avec des cases mmoires avec les pointeurs pointe rs
on na pas besoin que la mmoire soit dfinie, on a juste besoin de savoir que cest c est la mmoire un certain endroit qui va tre utilise.

On allouera cette mmoire (cela veut dire on rservera cette place mmoire) aprs quand on connaitra la taille, en utilisant des fonction spciales : malloc, calloc, realloc
JC Rgin - Intro C - L2I - 2011

Pointeurs : allocation dynamique


1.139

int* tab; /* tab est un tableau */ int n; ; tab = calloc(n,sizeof(int)); /* rserve de la place pour n entiers */ / /* calloc retourne une adresse mmoire et dit lOS q e la palce est rser que rserve e cet endroit */

JC Rgin - Intro C - L2I - 2011

Pointeurs : allocation mmoire


1.140

En utilisant E l l les f fonctions standard d d suivantes, l lutilisateur l a la l garantie que la mmoire alloue est contige et respecte les contraintes d dalignement. alignement. Ces fonctions se trouvent dans le fichier de dclarations stdlib.h.

void *malloc ( (size_t taille); );


permet dallouer taille octets dans le tas.

void *calloc (size_t nb, size_t taille);


permet dallouer taille x nb octets dans le tas, en les initialisant 0.

void *realloc (void *ptr, size_t taille);


permet de rallouer de la mmoire. mmoire

void free (void *ptr);


permet de librer de la mmoire (ne met pas ptr NULL)
JC Rgin - Intro C - L2I - 2011

Pointeur
141

Un pointeur est un type de donnes dont la valeur fait rfrence (rfrencie) directement (pointe vers) une autre valeur. Un pointeur rfrencie une valeur situe quelque part en mmoire en utilisant son adresse Un pointeur est une variable qui contient une adresse mmoire
JC Rgin - Intro C - L2I - 2011

Pointeur
142

Un pointeur est un type de d donnes d dont d la l valeur l pointe i vers une autre valeur. Obtenir la valeur vers laquelle un pointeur pointe est appel d f drfrencer l pointeur. le i t Un pointeur qui ne pointe vers aucune valeur aura la valeur NULL ou 0 En Java TOUT est pointeur
JC Rgin - Intro C - L2I - 2011

Pointeurs : dclarations
1.143

Comment C t dclarer d l un pointeur i t ? type *nom_pointeur; char *p; int *p1, p1, *p2; p2; struct {int x, y;} *q; void *r; int *s1[3]; int (*fct)(void); int (*T[5])(void); double *f(void);
JC Rgin - Intro C - L2I - 2011

Pointeurs : syntaxe
1.144

Adresse dune variable x est dsigne en utilisant &


exemple

&x;

Pointeur universel : void * Pointeur sur rien du tout : constante entire 0 ou NULL (macro dfinie dans le fichier de dclarations stdlib h) stdlib.h) Simplification dcriture : si q est un pointeur sur une structure contenant un champ x
q

-> x est quivalent (*q).x


JC Rgin - Intro C - L2I - 2011

Rfrences fantmes !
1.145

#include <stdlib.h> int *f1 (void) { int a = 3; return &a; /* warning: function returns address of local variable */ } int *f2 (void) { int *a = malloc(sizeof(int)); *a = 3; return a; } int main (int argc, char *argv[]) { int *p1 = f1(); p = f2(); int *p2 return 0; }

JC Rgin - Intro C - L2I - 2011

Que se passe t til il ?


1.146

#include <stdio.h> int main (int argc, char *argv[]) { i int i = 0 0; char c, *pc; int *pi; printf("sizeof(char) = %d, sizeof(int) = %d,\n, sizeof(void *) %d\n\n", sizeof(char), sizeof(int), sizeof(void *)); printf(stdout, "&i = %p, &c = %p,\n&pc = %p, &pi = %p\n", (void *)&i, (void *)&c, (void *)&pc, (void *)&pi); c = 'a'; pi = &i; pc = &c; *pi = 50; *pc = 'B'; printf("i p ( = %d, , c = %c,\npc ,\ p = %p, p, *pc p = %c,\n ,\ p pi = %p, p, *pi p = %d\n", \ , i, c, pc, *pc, pi, *pi); return 0; }
JC Rgin - Intro C - L2I - 2011

1.147

Excution E ti : $a.out sizeof(char) i f( h ) = 1 1, sizeof(int) i f(i t) = 4, 4 sizeof(void *) = 4 &i = 0xbffff7b4, 0xbffff7b4 &c = 0xbffff7b3, 0xbffff7b3 &pc = 0xbffff7ac, &pi = 0xbffff7a8 i = 50, 50 c = B, B pc = 0xbffff7b3, *pc = B, pi = 0xbffff7b4 0xbffff7b4, *pi pi = 50 $
JC Rgin - Intro C - L2I - 2011

Que se passe t til il ?


1.148

#include <stdio.h> #include <stdlib.h> int main (int argc argc, char *argv[]) { int i = 0; char c, *pc; int *pi; printf("sizeof(char) = %d, sizeof(int) = %d, sizeof(void *) = %d\n\n", sizeof(char),sizeof(int), sizeof(void *)); printf("&i = %p, &c = %p, &pc = %p, &pi = %p\n", (void *)&i, ( ) , ( (void *)&c, ) , ( (void *)&pc,(void ) p ,( *)&pi); ) p ) c = 'a'; pc = calloc(1, sizeof(char)); pi = calloc(1, sizeof(int)); *pi = 50; *pc = 'B'; printf(stdout, "i = %d, c = %c,pc = %p, *pc = %c,pi = %p, *pi = %d\n", i, c, pc, *pc, pi, *pi); return 0; }
JC Rgin - Intro C - L2I - 2011

1.149

Excution E ti : $ a.out sizeof(char) i f( h ) = 1 1, sizeof(int) i f(i t) = 4, 4 sizeof(void *) = 4 &i = 0xbffff7b4, 0xbffff7b4 &c = 0xbffff7b3, 0xbffff7b3 &pc = 0xbffff7ac, &pi = 0xbffff7a8 i = 0, 0 c = a, a pc = 0x80497c8, *pc = B, pi = 0x80497d8 0x80497d8, *pi pi = 50 $
JC Rgin - Intro C - L2I - 2011

Passage par rfrence


1.150

En C, le passage des paramtres se fait toujours par valeur. Les pointeurs permettent de simuler le passage par rfrence.
#include <stdio.h> void id Swap (i (int a, i int b) { int aux; aux = a; a = b; b = aux; } int main (int argc, char *argv[]) { int x = 3 3, y = 5; printf("av: x = %d, y = %d\n",x, y); Swap(x, y); printf("ap: x = %d, y = %d\n",x, y); return 0; 0 }

JC Rgin - Intro C - L2I - 2011

Passage par rfrence


1.151

#include <stdio <stdio.h> h> void Swap (int *a, int *b) { int aux; aux = *a; *a = *b; *b = aux; } int main (int argc, char *argv[]) { int x = 3, y = 5; printf("av: x = %d, y = %d\n", x, y); Swap(&x, &y); printf("ap: i tf(" x = %d %d, y = %d\ %d\n", " x, y); ) return 0; }

JC Rgin - Intro C - L2I - 2011

Passage par rfrence


1.152

#include <stdio.h> #include <stdlib.h> void imp (int t[], int lg) { int i; for (i = 0; i < lg; i++) printf("%d printf( %d ", , t[i]); fputc('\n', stdout); } void MAZ (int t[], int lg) { int i; f for (i = 0 0; i < l lg; i++) t[i] = 0; } void Mess (int t[], int lg) { int i; t = malloc(sizeof(int) * lg); for (i = 0; i < lg; i++) t[i] = 33; imp(t, lg); } #define MAX 10 int main (int argc, char *argv[]) { int t[MAX]; MAZ(t, MAX); imp(t, MAX); Mess(t, MAX); imp(t, MAX); return t 0 0; }

JC Rgin - Intro C - L2I - 2011

Pointeurs et tableaux
1.153

Notions N ti trs t li lies en C. C Le nom du tableau correspond ladresse de dpart du tableau (en fait l ladresse adresse du premier lment) lment).

Si int t[10]; alors t = &t[0]

S on Si o passe u un tableau ab eau en e pa paramtre, a e, seu seule e ladresse ad esse du tableau est passe (il nexiste aucun moyen de connatre le nombre dlments). En fait, f l lutilisation l d des crochets h est une simplification lf dcriture. La formule suivante est applique pour accder llment l lment i.

a[i] est quivalent *(a + i)


JC Rgin - Intro C - L2I - 2011

Pointeurs : oprations arithmtique


1.154

Un pointeur contenant une adresse, on peut donc lui appliquer des oprations arithmtiques pointeur + entier donne un pointeur pointeur entier donne un pointeur pointeur pointeur donne un entier Le dernier p point est FORTEMENT dconseill car trs peu portable.
JC Rgin - Intro C - L2I - 2011

Pointeurs : oprations arithmtiques


1.155

#i l d < #include <stdio.h> tdi h> int main (int argc, char *argv[]) { int t1[10], t2[20]; printf("t1 = %p, t2 = %p\n", t1, t2); printf("t1 + 3 = %p, &t1[3] = %p\n", t1 + 3, &t1[3]); printf("&t1[3] - 3 = %p\n", &t1[3] - 3); printf("t1 - t2 = %d\n", t1 - t2); printf("t2 printf( t2 - t1 = %d\n" %d\n , t2 - t1); return 0; }

Excution : $ a.out t1 = 0xbffff780, t2 = 0xbffff730 t1 + 3 = 0xbffff78c, &t1[3] = 0xbffff78c &t1[3] - 3 = 0 0xbffff780 bffff780 t1 - t2 = 20 t2 - t1 = -20 $
JC Rgin - Intro C - L2I - 2011

1.156

#include <stdio.h> void aff (int t[], int n) { /* Antcdent : n initialis */ /* Rle : affiche les n premiers lments de t spars par des blancs et termins par une fdl */ int i; (i = 0; ; i < n; ; i++) ) for ( printf("%d ", t[i]); fputc('\n', stdout); } int main (int argc, char *argv[]) { int tab[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; aff(tab, sizeof tab / sizeof tab[0]); aff(tab + 5, 5); return 0; }

JC Rgin - Intro C - L2I - 2011

1.157

#include <stdio.h> #include <stdlib.h> #define M 5 void saisieTab (int t[], short n) { /* Antcdent : t et n initialiss */ /* Rle : saisie de n entiers dans t */ short i; printf("les %d nombres? ", n); for (i = 0; i < n; i++) scanf("%d", &t[i] /* t + i */); } void copieTab (int t[], int *p, short n) { /* A Antcdent t d t : t t, p et t n i initialiss iti li */ /* Consquent : $\forall$ i $\in$ [0..n-1] p[i] = t[i] */ short i; for (i = 0; i < n; i++) *p++ = t[i]; } void affTab (int t[], short n) { /* Antcdent : n initialis */ /* Rle : affiche les n premiers lments de t spars par des blancs et termins par fdl */ short i; for (i = 0; i < n; i++) printf("%d ", t[i]); fputc('\n', stdout); } int main (int argc, char *argv[]) { int *p = calloc(M, sizeof(int)), t[M]; saisieTab(t, i i T b(t M) M); affTab(t, ffT b(t M) M); affTab(p, ffT b( M) M); copieTab(t, p, M); affTab(t, M); affTab(p, M); return 0; JC Rgin - Intro C }

- L2I - 2011

Pointeurs et chanes de caractres


1.158

Une constante chane de caractres a comme valeur l'adresse mmoire de son premier caractre (on ne peut la modifier). Son type yp est donc pointeur p sur caractres.
#include <stdio.h> int main (int argc argc, char *argv[]) { char y[] = "1234"; char *x = "1234"; char z[10] = "1234"; char h t tc[] [] = {'1' {'1', '2' '2', '3' '3', '4'} '4'}; printf("x=%p &x=%p\n", x, (void *)&x); printf("y=%p &y=%p\n", y, (void *)&y); return 0; }
JC Rgin - Intro C - L2I - 2011

Parcours de chanes de caractres


1.159

#i l d < #include <stdio.h> tdi h> void aff (char *s) { while (*s) ( s) { fputc(*s, stdout); s++; } fputc('\n', \ stdout); } int main (int argc, char *argv[]) argv[]) { char s1[] = "bonjour vous!", *s2 = "et vous aussi"; aff(s1); aff(s2); return 0; }
JC Rgin - Intro C - L2I - 2011

Pointeurs et fonctions
1.160

En C, C le type pointeur sur f fonction existe :


typedef

int (*tpf) (int);

dclaration de tpf comme tant un type pointeur sur fonction prenant un int en paramtre et renvoyant un int
float

(*vpf) (double, (double char *);

dclaration de vpf comme tant une variable de type pointeur sur fonction prenant en paramtres un double et un char * et renvoyant un float
char

*f (int);

dclaration de f comme tant une constante de type pointeur sur fonction prenant en paramtre un int et renvoyant un char *
JC Rgin - Intro C - L2I - 2011

Pointeurs et fonctions
1.161

Lorsqu'on dfinit une fonction, en fait on dclare une constante de type pointeur sur fonction et sa valeur est l'adresse de la premire instruction de la fonction.
#include <stdio.h> int max (int a, int b) { return a > b ? a : b; } int main (int argc, char *argv[]) { printf("%p\n", (void *)printf); printf("%p\n" printf( %p\n , (void *)&printf); printf("%p\n", (void *)max); printf("%p\n", (void *)max(1, 16)); return 0; }
JC Rgin - Intro C - L2I - 2011

Fonctions en paramtre
1.162

il suffit de passer le type du pointeur sur fonction (concern) en paramtre.


#include <stdio.h> void imp (int t[], int lg) { int i; for (i = 0; i < lg; i++) printf("%d ", t[i]); fputc('\n', \ stdout); } int maz (int a) { return 0; } int p plus1 (int a) { return a + 1; } void modifierTableau (int t[], int lg, int (*f) (int)) { int i; for (i = 0; i < lg; i++) t[i] = f(t[i]); } #define MAX 10 int main (int argc, char *argv[]) { int t[MAX]; modifierTableau(t, MAX, maz); imp(t, MAX); modifierTableau(t, difi bl ( MAX, plus1); l 1) i imp(t, ( MAX); ) modifierTableau(t, MAX, plus1); imp(t, MAX); return 0; JC Rgin - Intro }

C - L2I - 2011

Pointeur polymorphe (void (void*) )


1.163

#include <stdio <stdio.h> h> void Swap (int *a, int *b) { int aux; aux = *a; *a = *b; *b b = aux; } int main (int argc, char *argv[]) { int x = 3, y = 5; printf("av: x = %d, y = %d\n", x, y); Swap(&x, &y); printf("ap: x = %d, y = %d\n", x, y); return 0; }
JC Rgin - Intro C - L2I - 2011

Pointeur polymorphe (void (void*) )


1.164

#include #i l d <stdlib.h> tdlib h #include <string.h> #include "swapPoly1.h" void Swap (void *a, void *b, short taille) { void *aux = malloc(taille); memcpy(aux, ( b b, t taille); ill ) memcpy(b, a, taille); memcpy(a, aux, taille); #if 0 /* c'est compltement faux: on drfrence un void *!!! */ *aux = *b; *b = * *a; *a = *aux; #endif }
JC Rgin - Intro C - L2I - 2011

Pointeur polymorphe (void (void*) )


1.165

#include <stdio.h> stdio.h #include "swapPoly1.h" #define imp(t, s1, s2, x, s3, y) \ printf("%s: %s = " t ", %s = " t "\n",s1, s2, x, s3, y) int main (int argc, char *argv[]) { int a = 3, b = 9; float x = 13, y = 19; double m = 23.45, n = 25.0; char h c1 1 = ' 'a', ' c2 2 = 'B' 'B'; imp("%d", "avant", "a", a, "b", b); Swap(&a, &b, sizeof(int)); imp("%d", "aprs", "a", a, "b", b); imp("%.2f", "avant", "x", x, "y", y); Swap(&x, &y, sizeof(float)); imp("%.2f", "aprs", "x", x, "y", y); imp("%.2f", "avant", "m", m, "n", n); Swap(&m, &n, sizeof(double)); imp("%.2f", p( , "aprs", p , "m", , m, , "n", , n); ) imp("%c", "avant", "c1", c1, "c2", c2); Swap(&c1, &c2, sizeof(char)); imp("%c", "aprs", "c1", c1, "c2", c2); return 0; }

JC Rgin - Intro C - L2I - 2011

Pointeur polymorphe (void (void*) )


1.166

#include <stdio.h> #include <stdlib.h> void Swap (void **a, void **b) { void *aux = malloc(sizeof(void *)); aux = *b; b; *b = *a; *a = aux; } int main (int argc, char *argv[]) { int a = 3 3, b = 4; int *x = &a, *y = &b; double *m = malloc(sizeof(double)); double *n = malloc(sizeof(double)); printf("av: a=%d, b=%d, x=%d, y=%d\n",a, b, *x, *y); Swap(&x, &y); printf("ap: a=%d, b=%d, x=%d, y=%d\n",a, b, *x, *y); *m = 3.456; *n = 1.2345; printf("av: *m=%f, p , *n=%f\n", , *m, , *n); Swap(&m, &n); printf("ap: *m=%f, *n=%f\n", *m, *n); return 0; }

JC Rgin - Intro C - L2I - 2011

Conversion de type
1.167

Une conversion est en fait un changement de reprsentation.


Un

entier en un double Un double en un entier Etc

Attention : le rsultat d'une conversion de type peut tre indtermin.


JC Rgin - Intro C - L2I - 2011

Conversions implicites
1.168

Elles sont provoques par des oprateurs arithmtiques, logiques et d'affectation, lorsque les types des oprandes sont diffrents mais comparables. Pour les expressions p arithmtiques q et logiques gq :
les

conversions sont effectues du type le plus faible vers le plus p us fort. o . (char (c a vers ve s int, ,s short o ve vers s int ) rsultat lt t d de l la partie ti d droite it est t converti ti dans d celui l id de l la partie gauche. (int x= ;)
JC Rgin - Intro C - L2I - 2011

Pour les affectations :


le l

Conversions explicites
1.169

Elles sont Ell tf faites it par l le t transtypage. t La valeur de l'expression ainsi construite est le rsultat de la conversion de l'expression dans le type. int i; double d; ; enum E {rouge=1, bleu=2, vert=3} couleur; ... d = 3; couleur = (enum E)((int) d); i = (int) couleur; (float) 3; /* \donc 3.0 */ (int) 5.1267e2; /* \donc 512 */
JC Rgin - Intro C - L2I - 2011

Ligne de commande
1.170

En fait, E f it l la f fonction ti main i a plusieurs l i paramtres t permettant tt t de faire le lien avec UNIX. Son prototype est :

int main (int argc, argc char *argv[]); argv[]);

On utilise par convention argc et argv (ce ne sont pas des identificateurs rservs).
Le paramtre argc (entier) indique le nombre de paramtres de la commande (incluant le nom de celle-ci). Le paramtre argv (tableau de chanes de caractres) contient la ligne de commande elle-mme:

argv[0] est le nom de la commande argv[1] [1] est le premier paramtre; etc argv[argc] == NULL.
JC Rgin - Intro C - L2I - 2011

Ligne de commande : exemple


1.171

$ commande d -option fic1 f 199 99 Dans le programme C


argc = 4 argv a 5 lments significatifs et on peut les reprsenter comme suit :

argv[0] : command command argv[1] : -option argv[2] : fic1 argv[3] : 199 argv[4] : NULL
JC Rgin - Intro C - L2I - 2011

Ligne de commande
1.172

#i l d < #include <stdio.h> tdi h> int main (int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) printf("*%s*\n", argv[i]); while (*++argv){ printf("*%s*\n", *argv); } return 0; }

JC Rgin - Intro C - L2I - 2011

Nombre variable de paramtres


1.173

La liste l variable bl d de paramtres est dnote d par ... derrire d le dernier paramtre fixe. Il y a au moins un paramtre fixe. fixe

int printf(const char *format, ... );

4 macros sont dfinies dans le fichier stdarg.h stdarg h


Le type va_list sert dclarer le pointeur se promenant sur la p pile d'excution. va_list ap; La macro va_start initialise le pointeur de faon ce qu'il pointe aprs le dernier paramtre nomm. void va_start (va_list ap, last);

JC Rgin - Intro C - L2I - 2011

Nombre variable de paramtres


1.174

La macro va_arg retourne la valeur du paramtre en cours, et positionne le pointeur sur le prochain paramtre. Elle a besoin du nom du type pour dterminer le type de la valeur de retour et la taille du pas pour passer au paramtre suivant. type yp va_arg _ g( (va_list _ ap, p type); yp ) La macro va_end va end permet de terminer proprement. proprement void va_end (va_list ap);
JC Rgin - Intro C - L2I - 2011

Nombre variable de paramtres


1.175

#include <stdio.h> #include <stdarg.h> void imp (int nb, ...) { int i; va_list p; va_start(p, t t( nb); b) for (i = 0; i < nb; i++) printf("%d ", va_arg(p, int)); fputc('\n', stdout); va_end(p); } int main (int argc argc, char *argv[]) argv[]) { imp(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); imp(5, 'a', 'b', 'c', 'd', 'e'); imp(2, 12.3, 4.5); return 0; 0 }

JC Rgin - Intro C - L2I - 2011

Nombre variable de paramtres


1.176

#include #i l d < <stdio.h> tdi h> #include <stdarg.h> int max (int premier, ...) { /* liste d'entiers / d entiers >= 0 termine par -1 1 */ / va_list p; int M = 0, param = premier; va a_sta start(p, t(p, p premier); e e ); while (param >= 0) { if (param > M) M = param; param = va_arg(p, int); } va_end(p); return M; } int main (int argc, char *argv[]) { printf("%d\n", max(12, 18, 17, 20, 1, 34, 5, -1)); printf("%d\n", max(12, 18, -1, 17, 20, 1, 34, 5, -1)); return t 0 0; } JC Rgin - Intro C - L2I - 2011

Entres/Sorties
1.177

Fichier Fi hi d de d dclarations l ti stdio.h tdi h E/S simples

criture d'un caractre sur la sortie standard

char c = '1'; putchar(c); t h ( ) putchar('\n');

Lecture d'un unique caractre sur l'entre standard

int c; c = getchar();
JC Rgin - Intro C - L2I - 2011

Entres/Sorties
1.178

En fin E fi d de fi fichier hi standard, t d d valeur l EOF criture d'une chane de caractres (avec retour la ligne) sur la sortie standard char *s = "coucou"; puts(s); puts( bonjour ); puts("bonjour"); Lecture d'une chane de caractres sur l'entre standard (jusqu' EOF ou \n) et \0 est t mis i l la fin fi char s[256]; printf("Nom? "); gets(s);
JC Rgin - Intro C - L2I - 2011

Entres/Sorties formates
1.179

it criture sur l la sortie ti standard t d d printf( dcimal = %d, printf("dcimal %d hexa = %x\n" %x\n , 100, 100 100); printf("nb rel = %f, %g\n", 300.25, 300.25); Lecture sur l'entre standard int i; double x; printf("i = ? "); scanf("%d", &i); printf("x = ? "); scanf("%lf", &x);
JC Rgin - Intro C - L2I - 2011

Entres/Sorties formates
1.180

it criture d dans une chane h de d caractres t char s[256]; sprintf(s, "%s", "il fait beau"); printf("*%s*\n", printf( %s \n , s); Lecture dans une chane de caractres int i; sscanf("123", "%d", &i); printf("%d\n", i);
JC Rgin - Intro C - L2I - 2011

Conversion de base : printf


1.181

caractre d,i o x,X u c s f e, E p %

type du d paramtre Nombre dcimal N b octal Nombre l non sign Nombre hexadcimal non sign N d Non dcimal i l non sign i Caractre isol Ch d Chane de caractres [-]m.dddddd [ ] dddddd /E+/ [-]m.dddddde/E+/-xx pointeur %
JC Rgin - Intro C - L2I - 2011

Conversion de base : scanf


1.182

caractre d, i, n o, u, x c s e, f, g %

Type de d largument l Entier dcimal Entier dcimal non sign caractre Chane de caractres Nombre en virgule flottante %

JC Rgin - Intro C - L2I - 2011

Entres/Sorties : fichier de caractres


1.183

FILE * est un descripteur de fichier Trois fichiers standard dclars dans stdio.h
FILE

*stdin stdin, *stdout stdout, *stderr; stderr;

Dclaration d'un descripteur de fichier


FILE

*fd;

JC Rgin - Intro C - L2I - 2011

Entres/Sorties : fichier de caractres


1.184

Ouverture d'un fichier (liaison entre le nom logique et le nom physique)


FILE

*fopen (const char *filename, const char *type);

"r" r pour lecture, "w" w pour criture et "a" a pour ajouter en fin de fichier, "b" la fin du mode pour les fichiers binaires Fermeture d'un ' fichier
int

fclose (FILE *stream);


JC Rgin - Intro C - L2I - 2011

Entres/Sorties : fichier de caractres


1.185

FILE *fl, *fl *fe; *f fl = fopen("../ficLec", "r"); /* si ../ficLec / / n'existe pas, fl == NULL sinon fl contient le descripteur de fichier correspondant au fichier physique de nom ../ficLec */ fe = fopen("ficEcr", "w"); /* si problme, fe == NULL sinon fe contient le descripteur de fichier correspondant au fichier physique de nom ficEcr; si ficEcr existe, effacement du contenu, sinon cration du fichier vide */
JC Rgin - Intro C - L2I - 2011

Ecriture dans un fichier


1.186

un caractre
int

fputc (int c, FILE *stream); int putc (int c, FILE *stream);

une chane
int

fputs p (const char *s, ( , FILE *stream); );

un peu plus compliqu


int

fprintf (FILE *stream, const char *format, ...);


JC Rgin - Intro C - L2I - 2011

Lecture dans un fichier


1.187

un caractre
int

fgetc (FILE *stream); int getc (FILE *stream);

une chane
char

*fgets g (char *s, ( , int n, , FILE *stream); );

un peu plus compliqu


int

fscanf (FILE *stream, const char *format, ...);


JC Rgin - Intro C - L2I - 2011

Commande cat (cat.c)


1.188

#include <stdio.h> void copy (FILE *f) { int c; while ((c = fgetc(f)) != ! EOF) fputc(c, stdout); } int main (int argc, char *argv[]) { FILE *f; if (argc == 1) copy(stdin); else { while (--argc) { if ((f = f fopen(*++argv, (* " "r")) ")) == NULL) ) { fprintf(stderr, "Ouverture impossible %s\n", *argv); return 1; } else { copy(f); fclose(f); } } } return 0; JC Rgin - Intro C - L2I - 2011 }

E/S sur fichiers quelconques


1.189

Ouverture fopen et fermeture fclose criture size_t fwrite (const void *ptr, size_t size, size t nitems, size_t nitems FILE *stream); stream);

JC Rgin - Intro C - L2I - 2011

E/S sur fichiers quelconques


1.190

Ouverture fopen et fermeture fclose Lecture size_t fread (void *ptr, size_t size, size t nitems, size_t nitems FILE *stream); stream);

JC Rgin - Intro C - L2I - 2011

E/S sur fichiers quelconques


1.191

/* fl ouvert en lecture, fe en criture */ [ ] = {1, { , 2, , 3, , 4, , 5, , 6, , 7, , 8, , 9, , 10}; }; int i[10] char c; f d(& sizeof(char), fread(&c, i f( h ) 1, 1 fl); fl) fwrite(&i, sizeof(int), 5, fe); fwrite(&i, sizeof(int), 1, fe); fwrite(&c, sizeof(int), 1, fe); fwrite(&i, sizeof(char), 10, fe);
JC Rgin - Intro C - L2I - 2011

E/S Positionnement
1.192

Dplacement en octets
int

fseek (FILE *stream, long offset, int ptrname);


ptrname

SEEK SET==0 SEEK_SET==0 SEEK_CUR==1 SEEK_END==2

Dbut de fichier Position courante Fin de fichier

JC Rgin - Intro C - L2I - 2011

E/S
1.193

Indication de position
long

ftell (FILE *stream);

Fin de fichier
int

feof (FILE *stream);

JC Rgin - Intro C - L2I - 2011

Fichiers
1.194

#include <stdio.h> FILE *ecrire (char *nom, int n) { int i; FILE *f = fopen(nom, "w"); for (i = 0; i < n; i++) fwrite(&i, sizeof(int), 1, f); fclose(f); return f; } FILE *lireEtAfficher (char *nom) { int i; FILE *f = fopen(nom, "r"); while (fread(&i, sizeof(int), 1, f)) printf("%d printf( %d ", , i); fputc('\n', stdout); fclose(f); return f; } i t main int i (i (int t argc, char h * *argv[]) []) { if (argc != 2) { fprintf(stderr, "%s filename\n", argv[0]); exit(2); } { ecrire(argv[1], 20); lireEtAfficher(argv[1]); } JC Rgin - Intro return 0; }

C - L2I - 2011

Structure des programmes


1.195

Deux types de dure de vie


statique

ou permanente (cest--dire la dure de vie est celle du programme) automatique ou dynamique (cest--dire la dure de vie est celle du bloc qui la dclare)

Trois types yp de porte p


bloc

(ou fonction) fichier (au sens .c c = fichier source) programme


JC Rgin - Intro C - L2I - 2011

Classes de variables
1.196

La classe l d de mmorisation est spcifie f par


auto extern static register. it

auto : pas ou plus utilis extern : variable i bl globale l b l dfinie dfi i d dans une autre fichier fi hi register : variable mise dans un registre static : variable dans un bloc conservant sa valeur dun appel lautre
JC Rgin - Intro C - L2I - 2011

Variables et dure de vie


1.197

Dfinition Dfi iti vs. d dclaration l ti Dfinition dune variable : Variable rellement cre, cre mmoire alloue { / /* bloc */ / int v; /* variable automatique */ /* dclare v et alloue la mmoire ncessaire au rangement t dun d entier ti */ } La dfinition est UNIQUE
JC Rgin - Intro C - L2I - 2011

Variables et dure de vie


1.198

Dclaration dune variable : Pas de mmoire alloue, juste la nature de la variable est donne. extern int v; /* dfinit v comme tant une variable / de type entier */ dclaration de rfrence : MULTIPLE
JC Rgin - Intro C - L2I - 2011

Variables internes
1.199

Paramtres Variables automatiques q (ou ( locales) ) : elles sont locales un bloc


naissent

lappel l appel de la fonction (ou lentre l entre dun d un bloc meurent lorsque la fonction se termine (ou quand on sort du bloc).

Classe auto

JC Rgin - Intro C - L2I - 2011

Variables externes
1.200

Elles servent la communication entre fonctions (comme les paramtres) :


visibles du point de dclaration jusqu la fin du fichier physique ; dfinies hors de toute fonction (niveau 0) ; ont des valeurs permanentes, durant lexcution du programme ; initialises lors de la dfinition.

Chaque fonction doit la dclarer si elle veut lutiliser :


de faon explicite, p , grce g extern. de faon implicite, par contexte (si la dclaration apparat avant son utilisation).

JC Rgin - Intro C - L2I - 2011

Variables static
1.201

Les variables L i bl internes i t statiques t ti sont t locales l l une fonction f ti particulire mais restent en vie dun appel sur lautre. Les variables externes statiques sont locales au fichier source (fichier physique). Cela permet de ne pas les exporter. void f(void) { static int S = 0; int L = 0; /* automatique */ L++; S++; printf(" L=%d , S=%d \n ", L, S); }
JC Rgin - Intro C - L2I - 2011

Variables registres
1.202

Cela permet dindiquer au compilateur que la variable va tre beaucoup utilise et que le compilateur va pouvoir la ranger dans un registre (car laccs un registre est plus rapide quun accs la mmoire). Seuls les variables automatiques et les paramtres formels dune d une fonction peuvent avoir cette caractristique. Lensemble des types autoriss varie. Il est impossible de connatre ladresse l adresse dune d une variable register.
JC Rgin - Intro C - L2I - 2011

Variables volatiles
1.203

Indiquer I di l loptimiseur ti i quune variable i bl peut t changer h d de valeur l mme si i cela l napparat pas explicitement dans le source du programme. i t main int i (i (int t argc, char h * *argv[]) []) { volatile int var = -1; int i = 1; while (i) i = var; /* sans volatile, cette instruction est supprime par loptimiseur */ return 0; } Variables susceptibles dtre d tre modifies indpendamment du droulement normal du programme : variable modifie sur rception dun signal ou dune interruption, variable implante une adresse directement utilise par la machine
JC Rgin - Intro C - L2I - 2011

Initialisation des variables


1.204

Si pas dinitialisation explicite, les variables static et extern sont initialises 0, les auto et register nimporte quoi. Si initialisation explicite, p , les variables static et extern doivent ltre avec une expression constante car initialisations labores la compilation. Les initialisations des variables auto et register sont labores chaque entre dans le bloc (excution) a , donc nimporte quelle expression est accepte.
JC Rgin - Intro C - L2I - 2011

Fonctions
1.205

Par dfaut, toute fonction est extern et elle est suppose rendre un int ou char sil ny a pas eu de dclaration explicite avant. Une fonction p peut tre static explicitement p (dans ( ce casl, on limite la porte de la fonction au fichier physique).

JC Rgin - Intro C - L2I - 2011

Domaine d dapplication application


1.206

Le domaine dapplication dune dclaration = rgion de texte du programme C dans laquelle cette dclaration est t active. ti
Variables

globale : Le domaine dapplication dun identificateur dclar dans une dclaration de plus haut niveau stend entre son emplacement de dclaration et la fin du fichier physique. p y q Paramtre formel : Le domaine dapplication dun identificateur dclar dans une dclaration de paramtre formel stend entre son emplacement de dclaration et la fin du corps de la fonction.
JC Rgin - Intro C - L2I - 2011

Domaine d dapplication application


1.207

Domaine dapplication
Variable

automatique : Le domaine dapplication dun identificateur dclar au dbut dun bloc stend entre son emplacement de dclaration et la fin du bloc. Etiquette dinstruction : Le domaine dapplication dune tiquette dinstruction englobe lensemble du corps de la fonction dans laquelle elle apparat. Macro : Le domaine dapplication dun nom de macro de prprocesseur stend entre #define et la fin du fichier physique ou jusqu un #undef correspondant.
JC Rgin - Intro C - L2I - 2011

Conseils
1.208

Avoir un seul emplacement de dfinition (fichier source) pour chaque variable externe (omettre extern et avoir un initialiseur).
int

cpt p = 0;

Dans chaque fichier source rfrenant une variable externe dfinie dans un autre module, utiliser extern et ne pas fournir dinitialiseur.
extern

int cpt;

JC Rgin - Intro C - L2I - 2011

Modularit
1.209

Forme trs simple l d de modularit d l reposant sur l la notion d de fichiers (et inclusion de fichiers). R Rappels l sur l les d dclarations l i d de variables i bl :
au dbut d'un bloc : locale, temporaire; au niveau i 0 : globale l b l au programme, permanente; t dclaration static : locale (fichier ou fonction), permanente; dclaration extern : rfrence une dfinition. dfinition

Rappel sur le mot-cl static : il permet de rendre une variable externe ou une fonction prive un fichier; il permet de dclarer des variables internes permanentes.
JC Rgin - Intro C - L2I - 2011

Pourquoi la modularit ?
1.210

Un module U d l est t une unit it d de programme, c'est--dire ' t di un ensemble bl de fonctions ralisant un mme traitement et un ensemble de variables utilises par ces fonctions. Le dcoupage d'un programme en modules est indispensable

la lisibilit; l maintenance; la i la r-utilisation

Dans un programme en langage C, on dfinira un module nom au moyen du couple de fichiers :


nom.c : le fichier d'implmentation contenant les dfinitions de toutes les fonctions et variables du module; nom.h : le fichier de dfinitions contenant les dclarations de types, de constantes, de variables et de fonctions (prototypes).
JC Rgin - Intro C - L2I - 2011

Rgles de modularit
1.211

Les fonctions et variables internes du module sont dclares locales ce module au moyen du mot-cl static. Un fichier de dclarations ne contient aucune dfinition de variable, mais seulement :
des dfinitions de types des dclarations de variables des dclarations de fonctions.

Le fichier de dclarations d'un module est inclus dans le source de ce module, afin de permettre un contrle des dclarations p par le compilateur. p
JC Rgin - Intro C - L2I - 2011

Exemple
1.212

#ifndef _GENERATOR_H #define _GENERATOR_H extern void generator_reset (int); extern int generator_current (void); extern int generator_next (void); #endif

JC Rgin - Intro C - L2I - 2011

Exemple
1.213

#i l d " #include "generator.h" t h" static int value = 0; void generator_reset (int beg) { value = beg; } int generator_current (void) { return value; } int generator generator_next next (void) { return value++; }
JC Rgin - Intro C - L2I - 2011

Modularit compilation
1.214

compilation il ti :

gcc -c -Wall -pedantic -ansi generator.c

Ne cre que le fichier objet et pas d'excutable. un fichier fi hi utilisateur ili main.c i :
#include <stdio.h> #include "generator.h" int main (int argc, char *argv[]) { printf("%d\n", generator_current()); generator_reset(4); printf("%d\n", p ( \ , g generator_next()); ()); printf("%d\n", generator_current()); return 0; }

Compilation :

gcc -Wall -pedantic -ansi generator.c main.c

Cre l'excutable a.out.


JC Rgin - Intro C - L2I - 2011

Options de compilations
1.215

G l ( Gnrales (principes i i gnraux mais i syntaxe t spcifique ifi gcc) )


-c : compile et assemble les fichiers sources et stoppe avant l'dition de liens ( (fichier .o ou .obj). j) -S : stoppe aprs la compilation propre; n'assemble donc pas (fichier .s). -E E : stoppe aprs le l passage du d prprocesseur (sur ( la l sortie i standard). -o file : ( (output) p ) redirige g la sortie sur le fichier file. -v : (verbose) option intressante, car liste toutes les commandes appeles par gcc.

Dmo Visual C++ (dfinir IDE, front end)


JC Rgin - Intro C - L2I - 2011

Options de compilations
1.216

Rpertoires
-I

dir : ajoute dir la liste des rpertoires o chercher les fichiers inclure. (i masjuscule) -L dir : ajoute dir la liste des rpertoires o chercher les bibliothques -l.

Pour dboguer g
-g

: met les informations ncessaires dans l'excutable pour le dbogueur. g -g format : pour un format prcis (gdb, coff, xcoff, dwarf).
JC Rgin - Intro C - L2I - 2011

Options de compilations
1.217

Optimisations
-O1,

-O2, -O3 : afin d'optimiser. -O0 : pour ne pas optimiser.

Cible
-b

machine : pour la cross-compilation. -V V version i : quelle ll version i utiliser tili ( (option ti utilise tili bien bi sr si i plusieurs versions sont installes).

JC Rgin - Intro C - L2I - 2011

Options de compilations
1.218

Avertissements
-w

: pour supprimer les avertissements du compilateur. -Wall : utiliser si on veut avoir des programmes vraiment propres. -pedantic ansi : pour tre sr de coller la norme ansi.

JC Rgin - Intro C - L2I - 2011

Outil make
1.219

Vocation de make = grer la construction de logiciels modulaires. Raliser des compilations (ou toute autre action) dans un certain ordre (compatible avec des rgles de dpendance) : fichier makefile. Dans le cas o make ralise des actions autres que la compilation, cet outil est quivalent un script SHELL, si ce nest quil y a la gestion des rgles de dpendance en plus. make ne produit les cibles que si les cibles dont elles dpendent p sont plus p rcentes quelles. q
JC Rgin - Intro C - L2I - 2011

Structure gnrale du makefile


1.220

Ce fichier C fi hi de d texte t t contient ti t une suite it dentres d t qui i spcifient ifi t les dpendances entre les fichiers. Il est constitu de lignes logiques (une ligne logique pouvant tre une ligne physique ou plusieurs lignes physiques spares par le signe barre lenvers). Les commentaires dbutent par le signe # et se terminent la fin de ligne. C t Contenu (ordre ( d recommand) d) :
dfinitions de macros rgles implicites rgles explicites ou entres

JC Rgin - Intro C - L2I - 2011

Rgles explicites
1.221

cible bl 1 ... cible bl m : dpendance d d d d 1 ... dpendance n action1 action2 ... actionp Traduction : mettre j jour les cibles : cible1 ... ciblem q quand les dpendances dpendance1 ... dpendancen sont modifies en effectuant les oprations action1,action2 ... action i p La premire entre est la cible principale
JC Rgin - Intro C - L2I - 2011

makefile : exemple
1.222

onyva : entiers.o ti matrices.o t i pal.o l @gcc -o onyva entiers.o matrices.o pal.o @echo "excutable $@ cr" entiers.o : entiers.h entiers.c @echo "compilation de $*.c..." @gcc -c -Wall -pedantic -ansi entiers.c matrices.o : matrices.h entiers.h elements.h matrices.c @echo "compilation p de $*.c..." @gcc -c -Wall -pedantic -ansi matrices.c pal.o : matrices.h pal.c @echo "compilation de $*.c..." @gcc -c c -Wall Wall -pedantic pedantic -ansi ansi pal pal.c c clean : -rm -f *.o; rm -f onyva; rm -f *~ print : a2ps entiers.h entiers.c | lpr a2ps matrices.h matrices.c | lpr a2ps elements.h pal.c | lpr
JC Rgin - Intro C - L2I - 2011

1.223

Si une action s'excute sans erreur (code de retour nul), make passe l'action suivante de l'entre en cours, ou une autre entre si l'entre en cours est jour. Si erreur (et - absent), make arrte toute excution. Les actions peuvent tre prcdes des signes suivants :
-

si l'action l action s s'excute excute avec un code de retour anormal (donc erreur), make continue @ l l'impression impression de la commande elle-mme est supprime @-, -@ pour combiner les prcdents
JC Rgin - Intro C - L2I - 2011

Commandes usuelles
1.224

Il est bien pratique d'avoir ' des entres d'impression, ' de nettoyage ou d'installation. impression : -lpr *.c *.h menage : @-rm @ rm *.o .o *.out .out core *~ install : mv a.out a out /usr/bin/copy chmod a+x /usr/bin/copy
JC Rgin - Intro C - L2I - 2011

Appel de make
1.225

make [-f f nom_du_makefile] f [options] [nom_des_cibles] Options :


-f

: si option manquante, make prendra comme fichier de commandes un des fichiers makefile, Makefile, s.makefile ous.Makefile M k fil (s'il ( 'il l le t trouve d dans le l rpertoire t i courant) t) -d : permet le mode Debug, c'est--dire crit les informations dtailles sur les fichiers examins ainsi que leur date -n n : imprime les commandes qui auraient d tre excutes pour mettre jour la cible principale (mais ne les excute pas).
JC Rgin - Intro C - L2I - 2011

Commandes usuelles
1.226

O Options ( (suite) ):
-p : affiche l'ensemble complet des macros connues par make, ainsi que la liste des suffixes et de leurs rgles correspondantes -s : n'imprime pas les commandes qui s'excutent; make fait son travail en silence -S : abandonne le travail sur l'entre courante en cas d'chec d'une des commandes relatives cette entre (L'option oppose est -k). k) -t : permet de mettre jour les fichiers cible nom_des_cibles d ibl : si i aucun nom n'est td donn, la l cible ibl principale i i l sera la premire entre explicite du makefile.

JC Rgin - Intro C - L2I - 2011

make : exemple d dappel appel


1.227

make make pal.o p make clean make k onyva make (@print@)

JC Rgin - Intro C - L2I - 2011

Makefile : Macros
1.228

Dfinition Dfi iti d de macros : Syntaxe

chaine1 = chaine2

chane2 est une suite de caractres se terminant au caractre # de dbut de commentaire ou au caractre de fin de ligne (s'il n'est ' pas prcd d d du caractre d'chappement d' h \) \). Dans la suite du makefile, chaque apparition de $(chane1) sera remplace par chane2. Exemples :

OBJETS=f1.o f2.o f3.o SOURCES=f1.h f1.c f2.h f2.c f3.h f3.c REPINST=/usr/bin
JC Rgin - Intro C - L2I - 2011

1.229

Remplacement dune sous-chane par une autre dans une chane : Syntaxe : $(chane:subst1=subst2)
subst1

est remplac par subst2 dans chane.

Exemples :
$(OBJETS:f2.o=) $(OBJETS f2 ) $(OBJETS:f2.o=fn.o) $(REPINST:bin=local/bin)

JC Rgin - Intro C - L2I - 2011

Macros internes
1.230

$* le nom de la cible courante sans suffixe $@ @ le nom complet p de la cible courante $< la premire dpendance $^ la l li liste t complte lt d des d dpendances d $? la liste des dpendances plus rcentes que la cible

JC Rgin - Intro C - L2I - 2011

1.231

Les variables bl d'environnement d' sont supposes tre des d dfinitions de macros. Par dfaut :
Les variables L i bl d'environnement d' i t l' l'emportent t t sur l les macros internes i t dfinies par dfaut. Les macros dfinies dans le makefile l l'emportent emportent sur les variables d'environnement. Les macros dfinies dans une ligne de commande l'emportent sur les macros dfinies dans le makefile.

L'option -e change tout a de telle faon que les variables d' i d'environnement l'emportent l' sur l les macros dfinies dfi i dans d le l makefile.
JC Rgin - Intro C - L2I - 2011

Exemple
1.232

CC=gcc CFLAGS=-Wall -pedantic -ansi OBJETS=entiers.o matrices.o pal.o SOURCES=*.h *.c Makefile ALIRE CARDIR=/usr/profs/Licence onyva : $(OBJETS) @$(CC) -o onyva $(OBJETS) @echo "$(USER), l'excutable $@ est cr" entiers.o : entiers.h entiers.c @echo "compilation de $*.c..." @$(CC) -c $(CFLAGS) entiers.c matrices.o : matrices.h entiers.h elements.h \ matrices.c @echo "compilation de $*.c..." @$(CC) -c $(CFLAGS) matrices.c pal.o : matrices.h pal.c @echo "compilation de $* $*.c..." c " @$(CC) -c $(CFLAGS) pal.c clean : -rm -f *.o; rm -f onyva; rm -f *~ print : a2ps entiers.h entiers.c | lpr a2ps matrices.h matrices.c | lpr a2ps elements.h pal.c | lpr copy : tar czf $(CARDIR)/binomes.tgz $(SOURCES) chmod o+r $(CARDIR)/binomes.tgz

JC Rgin - Intro C - L2I - 2011

Rgles implicites
1.233

Elles servent Ell td donner les l actions ti communes aux fichiers fi hi se terminant par le mme suffixe. .SUFFIXES: SUFFIXES: liste de suffixes .source.cible : actions Dans .SUFFIXES:, on dfinit les suffixes standard utiliss par pour identifier des types yp de fichiers particuliers. p les outils p Traduction : partir de XX.source, on produit XX.cible grce actions. Pour supprimer les rgles implicites par dfaut, appeler make avec l'option -r, ou crire .SUFFIXES: seulement.
JC Rgin - Intro C - L2I - 2011

Rgles implicites
1.234

Exemple : Pour tous les fichiers sources C (ayant comme suffixe .c), on appelle le compilateur C avec l'option -c. .SUFFIXES: SUFFIXES: .out out .o o .h h .c c .c.o: gcc -c -Wall -pedantic -ansi $*.c

JC Rgin - Intro C - L2I - 2011

Exemple : rgles implicites par dfaut


1.235

CC=gcc CC gcc CFLAGS=-Wall -pedantic -ansi OBJETS=entiers.o matrices.o pal.o SOURCES=*.h *.c Makefile ALIRE CARDIR=/usr/profs/Licence onyva : $(OBJETS) @$(CC) -o onyva $(OBJETS) @echo "$(USER), l'excutable $@ est cr" entiers.o : entiers.h entiers.c matrices.o : matrices.h entiers.h elements.h \ matrices.c pal.o : matrices.h pal.c clean l : -rm -f *.o; rm -f onyva; rm -f *~ print : p entiers.h entiers.c | lpr p a2ps a2ps matrices.h matrices.c | lpr a2ps elements.h pal.c | lpr copy : t tar czf f $(CARDIR)/bi $(CARDIR)/binomes.tgz t $(SOURCES) chmod o+r $(CARDIR)/binomes.tgz

JC Rgin - Intro C - L2I - 2011

1.236

Exemple : changement des rgles implicites par dfaut


CC=gcc g CFLAGS=-Wall -pedantic -ansi OBJETS=entiers.o matrices.o pal.o SOURCES=*.h *.c Makefile ALIRE CARDIR=/usr/profs/Licence .c.o: @echo "compilation de $*.c..." @$(CC) -c $(CFLAGS) $*.c onyva : $(OBJETS) @$(CC) -o $@ $(OBJETS) @echo "$(USER), l'excutable $@ est cr" entiers.o : entiers.h entiers.c matrices.o : matrices.h entiers.h elements.h \ matrices.c pal.o : matrices.h pal.c clean : -rm -f *.o; rm -f onyva; rm -f *~ print : a2ps entiers.h entiers.c | lpr a2ps matrices.h matrices.c | lpr a2ps elements.h pal.c | lpr copy : tar czf $(CARDIR)/binomes.tgz $(SOURCES) chmod o+r $(CARDIR)/binomes.tgz

JC Rgin - Intro C - L2I - 2011

Exemple : avec demande l lutilisateur utilisateur


1.237

SHELL=zsh CC=gcc CFLAGS= Wall -pedantic CFLAGS=-Wall pedantic -ansi ansi .c: @echo "avec Debug? " @-read -q REP; \ case $${REP} i in \ y) $(CC) $(CFLAGS) -g -o $@ $*.c;;\ n) $(CC) $(CFLAGS) -o o $@ $*.c;; $ .c;; \ esac
JC Rgin - Intro C - L2I - 2011

Autre exemple
1.238

SHELL=zsh CC=gcc CFLAGS=-Wall -pedantic -ansi .c.o: @print "compilation de $*.c..." @$(CC) $(CFLAGS) -c $* $*.c c all : # excution d'un script shell pour demander # l'utilisateur quelle implmentation il # dsire i @demande pileL : pileL.o pal.o @print "edl pour impl. liste..." @$(CC) -o p pileL p pileL.o p pal.o pileT : pileT.o pal.o @print "edl pour imp. tableau..." @$(CC) -o pileT pileT.o pal.o pileT.o : pileT.c pile.h pileL o : pileL pileL.o pileL.c c pile pile.h h pal.o : pal.c pile.h clean : -rm -f *~ core pileL pileT *.o print i t : a2ps pal.c pile.h pileT.c pileL.c | lpr

JC Rgin - Intro C - L2I - 2011

Autre exemple
1.239

echo -n "Liste ou tableau (L/T)? / " read rep case $rep in t|T) make pileT;; l|L) make pileL;; *) echo "pas possible...";; esac

JC Rgin - Intro C - L2I - 2011

make sous windows


1.240

Il existe i t un ou plusieurs l i utilisateurs tili t make k sous chaque h systme Attention : souvent pas compatible entre eux, eux mais fonctionnement commun make sous Windows = nmake Sous windows il faut excuter vcvars32 ou un quivalent
Allez dans dmarrer / Tous les programme / Microsoft Visual S d 2010 Studio 20 0 / Visual l Studio S d Tools l puis cliquer l sur un command d prompt V Vous p pouvez excuter nmake / /help p Ncessaire pour avoir plusieurs versions de compilateurs installes sur la mme machine

JC Rgin - Intro C - L2I - 2011

make
1.241

Les IDE crent des makefile. Visual Studio : p positionnez la souris sur un projet, p j , puis p faites un clique droit, puis Proprits. Dans la partie gauche sous C/C++ g / et Linker il y a une entre Command Line : elle permet de voir la commande qui est effectivement appele pour compiler et pour linker

JC Rgin - Intro C - L2I - 2011

Le prprocesseur
1.242

Fonctions du prprocesseur Il est appel avant chaque compilation par le compilateur. Toutes les directives commencent par un # en dbut de ligne.
Inclusion

textuelle de fichiers (#include) Remplacements textuels (#define)


Dfinition de constantes Dfinition de macros
Compilation C il ti

conditionnelle diti ll (#if #ifd #ifdef f #ifndef #if d f #else # l #endif) # dif)

Remarque : Rcursivit des dfinitions.


JC Rgin - Intro C - L2I - 2011

Dfinition des constantes


1.243

#define #d fi nom expression i #undef nom D Dans le l fi fichier hi concern, nom sera remplac l t textuellement t ll t par expression (sauf dans les chanes de caractres et les commentaires). ) Exemples :
#define #define #define #define #d fi #define

FALSE 0 TRUE 1 NULL ((char*) 0) T BUF 512 T_BUF T_BUFDBLE (2 * T_BUF)


JC Rgin - Intro C - L2I - 2011

Remarques
1.244

Certains prprocesseurs produisent un message d'avertissement s'il y a re-dfinition d'une macro, mais remplacent la valeur par la nouvelle. D'autres ont une p pile de dfinitions. La norme ansi ne permet pas l'empilement.

JC Rgin - Intro C - L2I - 2011

Inclusion de fichiers sources


1.245

#include # l d "nom_du_fichier" " d f h " #include <nom_du_fichier> Avec les <>, le prprocesseur ne va chercher que dans le ou les rpertoires standards.
/usr/include / / /include

Avec les A l guillemets, ill le l prprocesseur va chercher h h l' l'endroit d i spcifi, puis dans le ou les rpertoires standards. O peut On t passer une option ti au compilateur il t pour lui l i expliquer li o chercher (-I)
JC Rgin - Intro C - L2I - 2011

Dfinition de macros
1.246

#define #d fi nom(par ( 1, ..., parn) expression i Dans expression, il est recommand de parenthser les pari afin d'viter d viter des problmes de priorit lors du remplacement textuel des paramtres (rien voir avec le passage des paramtres lors d'un appel de sous-programme). Exemples :
#define getchar() getc(stdin) #define #d fi putchar(c) h ( ) putc(c, ( stdout) d ) #define max(a, b) (((a) > (b)) ? (a) : (b)) #define affEnt(a) fprintf(stdout, fprintf(stdout "%d" %d , a) #define p2(a) ((a) * (a))

JC Rgin - Intro C - L2I - 2011

Dfinition de macros
1.247

Une macro est dfinie partir du #define jusqu la fin de ligne Pour passer la ligne, sans utiliser une fin de ligne, on doit utiliser le caractre \ Exemple #d fi PRINT_TAB(tab,n)\ #define PRINT TAB(t b )\ int i;\ f (i 0 i< i++){ printf("%d for(i=0;i<n;i++){ i f("%d ", " tab[i]);}\ b[i]) }\ printf("\n");
JC Rgin - Intro C - L2I - 2011

Dfinition de macros
1.248

## va permettre de concatner Macro concat(a,b) ( , )j je veux concatner a et b ?


#define

concat(a,b) a##b

ATTENTION a la priorit des oprateurs : on parenthse


#define max(a,b) (a < b) ? b : a; #d fi max(a,b) #define ( b) (( ((a) ) < (b)) ? (b) : (a); ( )

ATTENTION les macros font du remplacement de texte


#define

max(a,b) ((a) < (b)) ? (b) : (a); max(i++,j++) : mauvais rsultat !


JC Rgin - Intro C - L2I - 2011

Macros prdfinies
1.249

__LINE__ ligne courante dans le fichier source __FILE__ nom du fichier source __DATE__ date de compilation du programme __HEURE__ HEURE heure h d de compilation il ti d du programme __STDC__ 1 si implmentation conforme ansi

JC Rgin - Intro C - L2I - 2011

Compilation conditionnelle
1.250

#if expression_constante p #ifdef expression_constante #ifndef expression_constante li t i t ti liste_instructions_ou_dclarations d l ti #else liste_instructions_ou_dclarations #endif

JC Rgin - Intro C - L2I - 2011

Compilation conditionnelle
1.251

Il est possible d'emboter des commandes de compilation conditionnelle. La compilation conditionnelle permet :
la

paramtrisation la compilation des structures de donnes; de gagner de la place en tant le code inutile l'excution; l excution; de prendre des dcisions la compilation plutt qu' l excution. l'excution

JC Rgin - Intro C - L2I - 2011

Exemple
1.252

#i l d <stdio.h> #include tdi h #if 0 /* partie ti d de programme en commentaires t i */ ... #endif int main (int argc, char *argv[]) { printf("%d\n", __STDC__); #if __STDC__ STDC printf("ansi\n"); #else printf("non ansi\n"); #endif return 0; }
JC Rgin - Intro C - L2I - 2011

Autres directives
1.253

#line fournit un numro de ligne #elif sinon si defined(nom) dtermine si nom est dfini comme une macro de prprocesseur #error "mess" arrte la compilation avec le message d'erreur d' #warning "mess" produit l'avertissement mess la compilation
JC Rgin - Intro C - L2I - 2011

Options du compilateur (trs utilises)


1.254

-Dmacro=defn dfinit la macro avec la chane defn comme valeur -Umacro pour ter la dfinition de la macro

JC Rgin - Intro C - L2I - 2011

Exemple
1.255

#i #ifndef _GENERATOR_H #define _GENERATOR_H extern void generator_reset (int); extern int generator_current (void); extern int i generator_next ( (void); id) #endif

JC Rgin - Intro C - L2I - 2011

Exemple
1.256

#include <stdio.h> #include <stdlib.h> #include "generator.h" static int value = 0; void generator_reset (int beg) { value = beg; } int generator_current generator current (void) { return value; } int generator_next (void) { return value++; } #ifdef SELFEXEC int main (int argc, char *argv[]) { generator reset(argv[1] != NULL ? generator_reset(argv[1] atoi(argv[1]) : 0); do { printf("%d\n", generator_current()); } while (generator_next() < 10); return t 0 0; } #endif JC Rgin - Intro C - L2I - 2011

Assert et NDEBUG
1.257

#include <assert.h> ( int exp p ); void assert( La macro assert L t est t utilis tili pour t tester t d des erreurs. Si exp est valu 0, alors assert crit des informations sur la sortie ti erreur standard t d d (stderr). ( td ) Si la macro NDEBUG est dfinie alors assert est ignore

JC Rgin - Intro C - L2I - 2011

Assert et NDEBUG
1.258

Code C d x = t[i] +2; Dangereux si i n nest est pas dans les bornes (i >=0 et i < n) Problme tester coute cher Solution assert assert(i >=0 && i < n); x = t[i] [ ] +2; ; Avec NDEBUG dfinie (Not Debug) ne fait rien du tout = cout nul Avec NDEBUG non dfinie, alors on teste les valeurs et si erreur alors l message d du type

Assertion failed in line XXX


JC Rgin - Intro C - L2I - 2011

Edition de liens
1.259

Ldition de lien permet de constituer un module binaire excutable partir de bibliothques et de fichiers objets compils sparment, en rsolvant les rfrences (externes) qui nont pas t rsolues lors des passes prcdentes du processus de compilation. Elle extrait des bibliothques les modules utiles aux fonctions effectivement utilises. Chaque objet externe doit avoir une et une seule dfinition dans lensemble des modules assembler.
JC Rgin - Intro C - L2I - 2011

Bibliothque (library)
1.260

Cest un f C fichier h un peu spcial l contenant l la version objet b dune fonction ou de plusieurs traitant dun sujet particulier (ou la version objet d dun un module ) ). Sous UNIX, les rpertoires standard des bibliothques sont /lib ou /usr/lib. /usr/lib La bibliothque darchives standard C est en fait le fichier /usr/lib/libc.a, et elle contient entre autres fprintf.o, atoi.o, strncat.o, etc. La bibliothque darchives d archives mathmatique est en fait le fichier /usr/lib/libm.a, contenant entre autres e_pow.o, s_sin.o, etc
JC Rgin - Intro C - L2I - 2011

Utilisation explicite dune d une bibliothque


1.261

#include #i l d <stdio.h> di h #include <math.h> #define #d fi d dem(n, ( v) ) printf(n i f( " = ? ");\ ") \ fscanf(stdin, "%d", &v) i int main i (i (int argc, char h * *argv[]) []) { int x, y; dem("x", d (" " x); ) dem("y", y); printf("%d^%d = %.2f\n", x, y, pow(x, y)); return 0; 0 }

JC Rgin - Intro C - L2I - 2011

Compilation et dition de liens


1.262

gcc -Wall -pedantic -ansi -c power.c gcc p g power.o : ERROR ...: In function 'main': ...: : undefined reference to 'pow pow ...: ld returned 1 OK :
gcc

power.o lm gcc power.o /usr/lib/libm.a gcc power.o /usr/lib/libm.so


JC Rgin - Intro C - L2I - 2011

Edition de liens statique


1.263

Elle extrait le code de la fonction f et le recopie dans le fichier binaire. Tout est donc contenu dans le fichier binaire, ce qui permet une excution directe du programme. Inconvnients :
Problme

de mmoire : le code de la fonction est charg en mmoire autant de fois qu'il ' y a de processus l'utilisant. ' Problme de version : si la bibliothque change, les applications li ti dj construites t it continueront ti t d'utiliser d' tili l'ancienne l' i version...
JC Rgin - Intro C - L2I - 2011

Edition de liens statique


1.264

gcc power.o -static /usr/lib/libm.a


taille

de a.out = 1656301 octets de a a.out out = 1656301 octets

gcc power.o -static -lm


taille

JC Rgin - Intro C - L2I - 2011

Edition de liens dynamique


1.265

Dans ce cas, l'diteur de liens ne rsout plus totalement les rfrences, mais construit une table de symboles non rsolus contenant des informations f permettant de localiser ultrieurement les dfinitions manquantes. Les rsolutions sont alors seulement faites lors de lexcution.
liaison dynamique immdiate (lors du chargement du programme); liaison dynamique diffre ( la premire rfrence d'un objet).

Inconvnient : ralentissement du chargement du programme.


JC Rgin - Intro C - L2I - 2011

Edition de liens dynamique


1.266

Les bibliothques b bl h de d fonctions f reliables, l bl d dynamiquement sont appeles


objets bj t partags t (fi (fichiers hi .so) ) bibliothques partages (fichiers .sl) Dynamic link library (dll) sous Windows

gcc power.o /usr/lib/libm.so / /lib/lib

taille de a.out = 14298 octets taille de a.out = 14298 octets


JC Rgin - Intro C - L2I - 2011

gcc power.o -lm l

Options de compilation
1.267

Tous l T les fichiers fi hi dont d tl les noms n'ont ' t pas de d suffixe ffi connus sont considrs par gcc comme des fichiers objets (et sont donc relis p par l'diteur de liens). ) -lnom_de_biblio : l'diteur de liens va chercher, dans la liste des rpertoires standard des bibliothques, la bibliothque nom_de_biblio d bibli , qui i est en fait f i un fi fichier hi nomm lib (nom_de_biblio.a ou .so et .sl si dynamique). -L Lnom_de_chemin nom de chemin : ajoute nom_de_chemin nom de chemin la liste des rpertoires standard des bibliothques. -static : sur les systmes y acceptant p l'dition de liens dynamique, elle permet d'viter l'dition de liens avec des bibliothques partages.
JC Rgin - Intro C - L2I - 2011

Options de compilation
1.268

Pour Windows : "nom_de_biblio.lib" : l'diteur de liens va chercher, , dans la liste des rpertoires standard des bibliothques, la bibliothque q nom_de_biblio, q qui est en fait un fichier nomm lib /LIBPATH:"nom_de_chemin /LIBPATH: nom de chemin" : ajoute nom_de_chemin nom de chemin la liste des rpertoires standard des bibliothques. /MT : dition di i de d lien li statique i /MD : dition de liens dynamique
JC Rgin - Intro C - L2I - 2011

Construction de bibliothques
1.269

Il est ncessaire de fournir un (ou des) .h, qui servira d'interface avec la bibliothque :
dfinitions

de constantes symboliques et de macros; dfinitions de types; yp ; dclarations de variables globales externes; dclarations de fonctions (en fait, fait leur prototype) prototype).

Et bien sr, il y a le (ou les) .c, qui dfinit les variables et l fonctions les f ti dclares d l dans d le l (ou ( les) l ) .h, h et t autres t objets privs.
JC Rgin - Intro C - L2I - 2011

Cration de bibliothques
1.270

Aprs A la l mise i au point i t de d la l fonction f ti ou du d module, d l il suffit ffit de d crer la bibliothque : Bibliothque d d'archives archives : runir un ensemble d'objets d objets en une seule bibliothque d'archives, en vue de leur reliure statique.

ar [options] archive fichiers -t : affiche le contenu de l'archive -r r : remplace ou ajoute le(s) fichier(s) dans l l'archive archive -q : ajoute le(s) fichier(s) la fin de l'archive (sans contrler leur existence) -d d : supprime i le(s) l ( ) fichier(s) fi hi ( ) spcifi(s) ifi( ) d de l' l archive hi -x : extrait le(s) fichier(s) de l'archive sans que le contenu de l'archive soit modifi
JC Rgin - Intro C - L2I - 2011

O i Options :

Exemples
1.271

ar -r lib/libdiv.a generator.o ar -t lib/libdiv.a / generator.o ar -r lib/libdiv.a lib/libdi pow.o ar -t lib/libdiv.a generator.o pow.o

JC Rgin - Intro C - L2I - 2011

Bibliothque partage
1.272

Bibliothque partage (produite par gcc ou ld) Exemple p : gcc -c -shared -o pow.so pow.c gcc power.o pow.so

JC Rgin - Intro C - L2I - 2011

1.273

JC Rgin - Intro C - L2I - 2011

TODO
1.274

Apres slide A l d 160 (oparcours ( d chaines des h de d caracteres) ) faire f le l detail des boucles Progressivement on retire tout tout: on commence par strlen et compter le nombre de caracteres avec une boucle i, puis des [] etc.. Expliquer le probleme avec les strlen dans les autres appels: c cest est important pour ceux qui viennent du Java Ensuite faire le imp p Puis montrer le strcpy() Expliquer que ch= toto ne peut pas marcher Expliquer p q que q ch== toto ne fait q que comparer p des pointeurs p
JC Rgin - Intro C - L2I - 2011

TODO
1.275

Pour les pointeurs reprendre lexemple donn en TP avec Tous les p passages g de paramtres p Voir le petit enonce TODO leur donner la signature de qsort (voir wikipedia) et leur demander de trier un tableau en appelant qsort Leur demander de faire une fonction map p

JC Rgin - Intro C - L2I - 2011