Cour Langage C
2011/2012
2011/2012
Sommaire du cours :
Elments de base du langage C Les structures Les pointeurs Les fonctions Les fichiers Lallocation dynamique de la mmoire Lallocation dynamique de tableaux Les listes chanes
Bibliographie :
TURBO C G. Le Blanc, Editions Eyrolles Programme en langage C J.M Rigaud et A. Sayah, Editions Berti C par exemple C. Belon, Sybex, 1992 Apprendre C sous Turbo Borland C++ C. Delannoy, Edition Eyrolles. Tous manuel de programme en langage C et C++ peut constituer une rfrence utile.
Web graphie :
http://www.ltam.lu/cours-c/prg-c_c.htm http://www.2shared.com/document/W_WC2ern/LangageC.html http://www.2shared.com/document/scm_uy5e/LangageC2.html http://www.siteduzero.com/tutoriel-3-14189-apprenez-a-programmer-en-c.html http://c.developpez.com/
Chapitre III
Introduction
2011/2012
1. Prliminaire :
Une des branches de linformatique consiste crire des programmes pour rsoudre des problmes. Avant la phase dcriture dun programme et de son implmentation, il faut dabord bien dfinir le problme (et les donnes associes) et cest lalgorithmique qui permet de le rsoudre. Un algorithme est une squence doprations visant la rsolution dun problme en un temps fini. La conception dun algorithme se fait par tapes de plus en plus dtailles. La premire version de lalgorithme est autant que possible indpendante de son implmentation, la reprsentation des donnes nest donc pas fixe. A ce niveau, les donnes sont considres de faons abstraites. Une fois lalgorithme et les structures de donnes dfinis, on les code en un langage informatique et on obtient un programme qui est dfini comme une suite dinstructions permettant de raliser une ou plusieurs taches, de rsoudre un problme, de manipuler des donnes. On parle de source (au masculin). Il sagit en fait du texte source du programme, texte original dun programme, dans le langage informatique comprhensible par un tre humain, donc destin tre traduit (ou compil). Quand on vous demande dimplmenter un algorithme bien spcifi, il sagit dcrire le programme correspondant. La compilation est le passage du code source dun programme un excutable laide du logiciel appropri (le compilateur). Lexcutable est le programme en code binaire directement comprhensible par le processeur. Le langage de base comprhensible par un ordinateur, appel langage machine est constitu dune suite de 0 et de 1. Cest du binaire, bien dur pour un tre humain. Le langage le plus proche est lassembleur, pour lequel les instructions sont celles de la machine, mais des mnmoniques sont utilises la place du code binaire. Pour le confort du programmeur, de nombreux langages de plus haut niveau ont t dfinis. On peut citer diffrents styles de programmation, avec pour chacun deux, un ou des langages particulirement adapts : la programmation structure (C, Pascal, ) la programmation fonctionnelle (Lisp,) la programmation logique (Prolog, ) La programmation scientifique (Maple, Matlab,) la programmation objet (Smalltalk, Eiffel, C++, Java, ) Tout code crit dans lun de ces langages doit tre traduit pour tre compris de la machine. Cest le rle des interprteurs et compilateurs. Un compilateur est un logiciel de traduction qui traduit les textes sources en langage binaire excutable.
Chapitre III
Introduction
2011/2012
2. Historique du langage C :
En 1972, Ritchie (chercheur dans les laboratoires Bell) a conu le langage C pour dvelopper une version portable du systme dexploitation UNIX. En 1978, le duo Ritchie / Kernighan a publi la dfinition classique du langage C dans le livre The C programming language , Dans les annes 80, le langage C est devenu de plus en plus populaire que ce soit dans le monde acadmique que celui des professionnels. Apparition des versions du langage C comportant des extensions particulires, En 1983, lorganisme ANSI American National Standards Institute chargeait une commission de mettre au point une dfinition explicite et indpendante de la machine pour le langage C. Ce travail sachve en 1989 par la dfinition de la norme ANSI-C.
3. Caractristiques du langage C :
C est un langage : Universel : permet aussi bien la programmation systme que la programmation de divers applications (scientifique, de gestion, ) De haut niveau : C est un langage
structur (offre plusieurs structures de contrle), typ (dclarations obligatoires), modulaire (fonctions et compilation spare) et Compil (par opposition aux langages interprts)
Portable : en respectant le standard ANSI-C, il est possible dutiliser le mme programme source sur dautres compilateurs.
- Prprocesseur : transformation purement Textuelles (inclusion dautres fichiers sources) - Compilation : Traduit le fichier pour gnrer un code en assembleur - Assemblage : transforme le code assembleur en un fichier binaire (fichier objet) - Edition de liens : liaison des diffrents fichiers objets et production de lexcutable
Page 2 Mahdia AZZOUZ
Chapitre III
Introduction
2011/2012
Dfinition d'une fonction en C : <Type_Rsultat> <Nom_fonction> ( <Type_Par1> <Nom_Par1> , ) { <dclarations locales> ; <instructions> ; }
En C, une fonction est dfinie par : 1. une ligne dclarative qui contient :
- <Type_Rsultat> : type de rsultat de la fonction - <Nom_fonction> : nom de la fonction - <Type_Par1> <Nom_Par1>, : types et noms des paramtres de la fonction
2. un bloc d'instructions dlimit par les accolades {}, contenant :
- <instructions> : liste des instructions qui dfinit l'action qui doit tre excute. - Remarque : En C, toute instruction simple est termine par un point virgule ( ; ).
Page 3 Mahdia AZZOUZ
Chapitre III
Introduction
2011/2012
La fonction main:
- Une fonction et une seule s'appelle main( ). C'est la fonction principale des programmes en C ; elle
se trouve obligatoirement dans tous les programmes.
L'excution d'un programme entrane automatiquement l'appel de la fonction main( ). Le type du rsultat de main est par dfaut int (entier). L'instruction return 0 ; indique l'environnement que le programme s'est termin avec succs. le type de main sera void dans le cas o aucun rsultat nest retourn. Les variables : Contiennent les donnes manipules pendant l'excution du programme. Les noms des variables sont des identificateurs quelconques. Toute variable doit tre dclare avant les instructions et son type spcifi ds la dclaration. Les diffrents types de variables simples seront discuts dans le chapitre suivant. Les identificateurs :
- Les noms des fonctions et des variables en C sont composs d'une suite de lettres et de chiffres,
plus le caractre soulign ( _ ).
- Le caractre soulign est aussi considr comme une lettre. - Ces identificateurs sont rservs :
int double auto static break else long struct case enum register switch char extern return typedef const float short union continue for signed unsigned default goto sizeof void do if while volatile
- Le langage C distingue les minuscules et les majuscules. PGCD et Pgcd sont deux identificateurs
diffrents. Les commentaires :
un commentaire multi lignes commence par les caractres /* et se termine par */. A lintrieur de ces dlimiteurs, vous avez droit toute suite de caractres (sauf videmment */).
Sont utiliss pour rendre un programme plus comprhensible. Sont ignors par le compilateur un commentaire sur une ligne commence par les caractres //.
Chapitre III
Introduction
2011/2012
Exemple dun programme C # include<stdio.h> int main () { /*ce programme affiche un message*/ printf ("Bonjours aux tudiants") ; getchar() ; return 0 ; }
- main indique quil sagit dun programme principal /* et */ sont utiliss pour dlimiter des
commentaires.
- printf est une fonction du langage C, utilise pour laffichage lcran ( voir plus loin). - les accolades { et } sont utilises pour dsigner le dbut et la fin dun programme (ou dun bloc
dinstructions), elles jouent le tle de Dbut et Fin de lALGORITHME.
Chapitre IV
2011/2012
1. Types simples :
Un type dfinit l'ensemble des valeurs que peut prendre une variable, le nombre d'octets rserver en mmoire et les oprateurs que l'on peut appliquer dessus. En C, il n'y a que trois types de base : Les entiers Les caractres Les rels. 1.1 Type entier : Il existe 3 variantes d'entiers : entiers courts (short int), entiers longs (long int) et entiers standards (int). - Caractristiques : Type Int short int long int Unsigned unsigned long Signification Entier standard Entier court Entier long Entier non sign Entier long non sign Valeur minimale -32768 -32768 - 2147483648 0 0 Valeur maximale 32767 32767 2147483647 65535 4294967295 Nombre doctets 2 ou 4 2 4 2 ou 4 4
1.2 Type caractre : Un caractre est un nombre entier (il s'identifie son code ASCII). Par consquent, une variable de type char peut contenir une valeur entre -128 et 127 et elle peut subir les mmes oprations que les variables du type short, int ou long. - Caractristiques : Type Char Signification Caractre Valeur minimale -128 Valeur maximale 127 Nombre doctets 1
1.3 Type rel : Il existe trois types de rels : rels simple prcision (float), rels double prcision (double) et rels trs grande prcision (long double).
Type Signification Rpartition des bits Valeur approximative Nombre doctets
M 23 52 64 8
4 8 10 ou 12
Chapitre IV
2011/2012
Longueur des types de base sur quelques machines Type Anne char short Int long float double PDP 11 1970 8 bits 16 bits 16 bits 32bits 32 bits 64 bits PC 486 1989 8 bits 16 bits 16 bits 32 bits 32 bits 64 bits SUN4 1993 8 bits 16 bits 32 bits 32 bits 32 bits 64 bits Alpha 1994 8 bits 16 bits 32 bits 64 bits 32 bits 64 bits
- sous forme hexadcimale, en faisant prcder le nombre par 0x ou 0X : 0x64, 0Xff Remarque : Le type attribu une constante est automatique (C choisit la solution la plus conomique partir du type int). b. Les constantes relles : - en notation dcimale : 123.4 - en notation exponentielle : 1234e-1 (ou bien 1234E-1) 12.34e1 (ou bien 12.34E1)
Page 2 Mahdia AZZOUZ
Chapitre IV
2011/2012
Remarque : Par dfaut, les constantes relles sont du type double. c. Les constantes caractres : Sont toujours indiqus entre apostrophes ' '
Exemples : 'a' ; 'b' ; 'A' ; '+' ; ',' ; La valeur d'un caractre constant est son code ASCII. Les caractres constants peuvent donc apparatre dans des oprations arithmtiques ou logiques. Ainsi, l'expression : 'a' + '?' vaut 160 (le code ASCII de 'a' est gal 97 alors que celui de '?' est 63). Pour distinguer certains caractres spciaux (les caractres de contrle ou caractres non
imprimables), on utilise le signe \ (antislash). Caractre \n \t \b \a \\ \ \" \v \0 \r \? \f Saut de ligne Tabulation: pousser de 5 caractres Effacer un caractre (backspace) Alerte: bip sur le haut parleur Imprime le caractre backslash Imprime lapostrophe Imprime le caractre guillemet Tabulation verticale Caractre nul Retour en arrire Point dinterrogation Saut de page Signification
d. Les constantes chanes de caractres : Une chane de caractres est une suite de caractres (ventuellement vide). Sont reprsentes entre guillemets " ". Exemples : "Ceci est une chane de caractres", "", "a" Le compilateur C rajoute la fin de toute chane de caractres le caractre nul '\0' pour indiquer sa fin. Dans une chane de caractres, on peut utiliser les squences dchappement. Linstruction suivante : printf("Bonjour, \n\tcomment vas-tu?\n A bientt\a") produit la sortie : Bonjour, comment vas-tu? A bientt e. Initialisation des variables et des constantes : - En C, il est possible d'initialiser les variables la dclaration.
Page 3 Mahdia AZZOUZ
Chapitre IV
2011/2012
Exemples : int max = 1023 ; char tabulation = '\t' ; - En utilisant l'attribut const, la valeur d'une variable ne change pas au cours de lexcution du programme . Exemples : const int MAX = 767 ; const char NEWLINE = '\n' ; - La directive #define permet de donner un nom une constante. Dans ce cas le prprocesseur effectue le remplacement correspondant avant la compilation. Exemples : #define TVA 1.7 #define Max_Tableau 100 #define PI 3.14159
b. Dclaration dun tableau deux dimensions (matrice) : type nom de tableau [nombre de lignes] [nombre de colonnes]; Exemples : int A[10][20] ; // A est une matrice dentiers 10 lignes et 20 colonnes. char M[30][10] ; // M est une matrice de caractres 30 lignes et 10 colonnes.
c. Accs aux lments dun tableau une dimension : se fait de la faon suivante : nom de tableau [indice de llment] Exemples : - t[5] // lindice est une constante entire - t[i] // lindice est une variable entire - t[2*i] // lindice est une expression d. Accs aux lments dun tableau deux dimensions : se fait de la faon suivante : nom de tableau [indice de la ligne][indice de la colonne] Exemples : - a[5] [3] // lindice de ligne et de colonne sont des constantes entires - a[i][j] // lindice de ligne et de colonne sont des variables entires - a[2*i][3*j] // lindice de ligne et de colonne sont des expressions Remarque : En langage C, lindice du premier lment dun tableau une dimension est 0 (zro) donc, pour un tableau t de 10 lments t[0] reprsentera le premier lment de t et t[9] dsigne le dernier lment ( le
Page 4 Mahdia AZZOUZ
Chapitre IV
2011/2012
dixime lment). Le mme raisonnement est appliqu aux tableaux de deux dimensions (matrices), pour une matrice m[5][10] on a m[0][0] reprsentera le premier lment de m et m[4][9] dsigne le dernier lment.
On peut affecter les valeurs de la manire suivante : - t[0]= a` ; t[1]= x` ; t[2]= E` ; t[3]= #` ; t[4]= F` ; - A[0][0]=1 ; A[0][1]=2 ; A[1][0]=5 ; A[1][1]=8 ; A[2][0]=0 ; A[2][1]=-1 ; 3.2 Chane de caractres : Une chane de caractres est compose de caractres, cest un cas particulier de tableau de caractres (elle est dclare de la mme faon). Un caractre spcial (`\0, compos de 8 zros binaires dsigne la fin de la chane). La taille de la chane doit tre suffisante pour contenir ce caractre : une chane dclare par char ch[10] ne pourra contenir que 9 caractres au maximum. Exemples : char ch[10]="LANGAGE" ; On aura en fait : L` A` N` G` A` G` E` \0` Remarque : Il faut noter la diffrence entre A` et "A", en fait le premier A est un caractre il occupe un octet en mmoire, et le second est une chane de caractres qui occupe deux octets puisquelle est automatiquement termine par `\0.
Chapitre IV
2011/2012
Une expression peut comporter des constantes, des variables et des appels de fonctions combins entre eux par des oprateurs et former ainsi une expression complexe. Toute expression suivie d'un point virgule devient une instruction. Une instruction en C est un ordre qui sera traduit (par le compilateur) en un ou plusieurs instructions machine. 4.1 Oprateurs classiques : a. Oprateur d'affectation simple = Syntaxe de dclaration <variable> = <expression> ;
L'expression est value puis le rsultat est affect la variable. En C, le terme gauche de loprateur daffectation est appel lvalue et doit tre une rfrence un emplacement mmoire dont on pourra effectivement modifier la valeur (Variable, Elment dun tableau, Champ dune structure,). Exemples : - const int LONG = 141 ; /* affectation de valeurs constantes */ - char NATION = 'M' ; - short val, resultat ; - char lettre ; - val = LONG ; /* affectation de valeurs de variables */ - lettre = NATION ; - resultat = 45 + 5 * val ; /* affectation de valeurs d'expressions */ Remarque : Les affectations sont aussi interprtes comme des expressions. L'oprateur d'affectation retourne la valeur affecte. On peut enchaner des affectations. L'valuation commence de la droite vers la gauche. Exemples : b=(a = 5 + 3)+1 avec rsultats a = 8 et b = 9 a = b = c = d quivalente : a = (b = (c = d))
b. Oprateurs arithmtiques + * / % Remarque : L'oprateur / retourne un quotient entier si les deux oprandes sont entiers. Il retourne un quotient rel si lun au moins des oprandes est un rel.
Page 6 Mahdia AZZOUZ
Chapitre IV
2011/2012
c.
Remarque : S'appliquent des expressions boolennes (0 si faux et valeur non nulle si vrai) ET retourne la valeur 1 si les deux oprandes sont non nuls, et 0 sinon. OU retourne la valeur 1 si au moins un des oprandes est non nul, et 0 sinon. Exemples : L'expression : 32 && 40 vaut 1 L'expression : !65.34 vaut 0 L'expression : !(!0-1) vaut 1
d. Oprateurs de comparaison
== != < <= > >= Egalit Diffrence plus petit plus petit ou gal plus grand plus grand ou gal
Exemples : - short a = 2 , b = 5 ; (a < 10.5) || (b = 4) retourne la valeur 1 et b = ?. - 0 || !(32 > 12) retourne la valeur 0. 4.2 Oprateurs particuliers de C : a. Oprateurs d'affectation tendue Pour la plupart des expressions de la forme : lvalue = lvalue OPrateur (expr2) Il existe une formulation quivalente utilisant un oprateur daffectation tendue: lvalue OP= expr2 Oprateurs d'affectation utilisables : Oprateur += -= *= /= %= a+=b a-=b a*=b a/=b a%=b
Page 7 Mahdia AZZOUZ
Equivalent
Chapitre IV
2011/2012
b. Oprateurs d'incrmentation (++) et de dcrmentation (--) Post-incrmentation <var>++; quivalente <var>=<var>+1; Post-dcrmentation <var>--; quivalente <var>=<var>-1; Remarque : Dans une expression, la valeur de la variable <var> est d'abord utilise telle quelle, puis incrmente (ou dcrmente). Pr-incrmentation ++<var>; quivalente <var>=<var>+1; Pr-dcrmentation --<var>; quivalente <var>=<var>-1; Remarque : Dans une expression, la valeur de la variable <var> est d'abord incrmente (ou dcrmente), puis utilise. Exemple dillustration : Avant chaque opration, i et j contiennent respectivement 3 et 15. Opration i++; ++j; i=++j; (pr-incrmentation) i=j++; (post-incrmentation) j = --i +5 ; j = i-- + 5 ; i = i++ ; c. Oprateur squentiel ( , ) - Syntaxe : <expr1>, <expr2>,, <exprN> Exprime des calculs successifs dans une mme expression Le type et la valeur de l'expression sont ceux du dernier oprande. Exemples : Lexpression : x = 5 , x + 6 a pour valeur 11 d. Oprateur conditionnel (? :) - Syntaxe : <expression> ? <expr1> : <expr2> <expression> est value. Si sa valeur est non nulle, alors la valeur de <expr1> est retourne. Sinon, c'est la valeur de <expr2> qui est renvoye. Exemples : c = a > b ? a : b Si a est le plus grand, alors affectation c le contenu de a sinon affectation c le contenu de b. e. Oprateurs sizeof - Syntaxe : sizeof(<type>) ou sizeof(<variable>) Retourne le nombre d'octets occups en mmoire par le type de donnes ou la variable spcifis. Exemples : - int x ; - sizeof(x) /* retourne la valeur 2*/ - sizeof(long double) /* retourne la valeur 10 */
Page 8 Mahdia AZZOUZ
Equivalent i=i+1 ; j=j+1 ; j=j+1 ; i=j ; i=j ; j=j+1 ; i=i-1 ; j=i+5 ; j=i+5 ; i=i-1 ; i=i ; i=i+1 ;
Rsultat i=4 et j=16 i=16 et j=16 i=15 et j=16 i=2 et j=7 i=2 et j=8 i=4
Chapitre IV
2011/2012
Exemples : Prenons a = 3 et b = 4, lexpression a *= b += 5 s'value : - a *= ( b += 5 ) - a *= ( b = b + 5 ) - a *= ( b = 9 ) - a *= 9 - a=a*9 - a = 27 Prenons a = 1 et b = 4, lexpression !--a == !b++ s'value : - ( ! ( --a ) ) == ( !(b ++) ) - ( ! ( a=a-1 ) ) == ( !4 ) ) et b = b+1 - ( ! ( a=0 ) ) == ( 0 ) ) et b = 5 ( ! 0 ) == ( 0 ) 1 == 0 0
Chapitre IV
2011/2012
p
int int
6.2 Conversion force( cast) Le type d'une expression peut tre forc, en utilisant l'oprateur cast : - Syntaxe : (<type>) <expression> Exemples : - char a = 49; // 49 est le code ASCII du caractre '1' - int b = 4 ; - float c , d , e ; - c = (float) a / b; d = a / b; e = (float) ( a / b ) - Quelle sont les valeurs de c , d et e ? - c = 12.25 , d = 12.0 et e = 12.0
Chapitre IV
2011/2012
6.3 Tableau rcapitulatif pour la conversion de type lors de laffectation : De char int int long int unsigned int float float double int char long int int long float int double float Vers Effet Le char se retrouve dans loctet le moins significatif de lentier Perte de loctet le plus significatif Expansion du bit du signe Perte des deux octets les plus significatifs Les deux octets les plus significatifs du long sont mis 0 Partie dcimale gale 0 Perte de la partie dcimale, en plus un entier ext limit 32767 alors quun float peut prendre des valeurs plus grandes Aucun problme Perte de prcision
Chapitre V
Instructions en C
2011/2012
Remarque : La fonction printf est dfinie dans le fichier stdio.h de la bibliothque du langage C donc tout programme qui utilise cette fonction doit tre prcde de la directive #include<stdio.h> Exemples: #include<stdio.h> int main() { int i=5 ; float x ; char c=z; char ch[8]="USDB"; x=1.5; /* le caractre \n est utilis pour sauter la ligne*/ printf("la valeur de i est : %d\n la valeur de x est : %f\n", i, x) ; printf("la valeur de x est : % 3.2f\n", x) ; printf("la valeur de c est : %c\n la valeur de ch est : %s\n", c, ch) ; return 0 ; } Le programme affichera : la valeur de i est : 5 la valeur de x est : 1.500000 la valeur de x est : 1.50
Page 1 Mahdia AZZOUZ
Chapitre V
Instructions en C
2011/2012
Exemples: #include<stdio.h> int main() { int i ; float x ; char ch[10]; printf(" donner la valeur de i :") ; scanf("%d",&i) ; printf(" donner la valeur de x :") ; scanf("%f",&x) ; printf("entrer une chane de caractres de longueur max=9 :") ; scanf("%s",ch) ; return 0 ;} Le programme affichera : donner la valeur de i : 30 /* lutilisateur fait entrer la valeur 30 et valide*/ donner la valeur de x : 12.75 /* lutilisateur fait entrer la valeur 12.75 et valide*/ entrer une chane de caractres de longueur max=9 : salut /* lutilisateur tape la chane et valide*/ Remarque : Lors de l'valuation des donnes, scanf s'arrte si la chane de format a t travaille jusqu' la fin ou si une donne ne correspond pas au format indiqu. scanf retourne comme rsultat le nombre d'arguments correctement reus et affects. Exemples: - int jour, mois, annee; - scanf("%d %d %d", &jour, &mois, &annee) ; - printf("%d %d %d", jour, mois, annee) ;
Donnes introduites 12 4 1992 12/4/1992 12.4 1992 12 4.1992 Affichage lcran jour 12 12 12 12 mois 4 indfini indfini 4 annee 1992 indfini indfini indfini
Chapitre V
Instructions en C
2011/2012
Elle reoit comme argument la valeur d'un caractre convertie en entier. Exemples: - char a = 63 ; - char b = '\n' ; - int c = '\a' ; - putchar('x') ; /* affiche la lettre x */ - putchar('?') ; /* affiche le symbole ? */ - putchar(b) ; /* retour la ligne */ - putchar(65) ; /* affiche le caractre de code ASCII = 65 c.--d. la lettre A */ - putchar(a) ; /* affiche le caractre de code ASCII = 63 c.--d. le symbole ? */ - putchar(c) ; /* beep sonore */ Remarque : putchar retourne la valeur du caractre crit toujours considr comme un entier, ou bien la valeur -1 (EOF) en cas d'erreur.
Chapitre V
Instructions en C
2011/2012
ou plusieurs lignes de texte (p.ex. des phrases) termines par un retour la ligne. Le retour la ligne sera remplac par le caractre de fin \0`. syntaxe: gets(nom de la chane) ;
b. puts : la fonction printf avec le spcificateur de format %s permet d'intgrer une chane de caractres dans une phrase. La fonction puts est idale pour crire une chane constante ou le contenu d'une variable dans une ligne isole. Le retour la ligne se fait automatiquement. syntaxe: puts(nom de la chane) ;
6. Structures de contrle
On appelle structure de contrle toute instruction qui permet de contrler le fonctionnement d'un programme. Parmi les structures de contrle, on distingue : structures de choix et structures rptitives
6.1 Structures de choix Les structures de choix permettent de dterminer quelles instructions seront excutes et dans quel ordre. En langage C, les structures de choix peuvent tre exprimes par : - Linstruction de branchement conditionnels : ifelse - Linstruction de branchement multiple : switch a. Branchement conditionnel ( if else) - : if (expression) bloc-instruction-1 else bloc-instruction-2 O - expression : est une expression quelconque. Aprs valuation, si elle est vraie, alors le 1er bloc d'instructions est excut, sinon c'est le 2me bloc qui est excut. - bloc d'instructions : peut dsigner une suite d'instructions dlimites par des accolades ou une seule instruction suivie par un point virgule. Remarque : On notera que l'expression conditionnelle doit tre entre parenthses. La partie else est optionnelle : if (expression) bloc-instruction ( le if tranqu) Lorsque plusieurs instructions if sont imbriques, il est convenu que chaque else se rapporte au dernier if qui ne possde pas de partie else. Un programmeur expriment utilisera toujours un maximum de else Exemples: Voici un exemple qui illustre le rle de lutilisation des else. Etant donn deux entiers x et y
Page 4 Mahdia AZZOUZ
Chapitre V
Instructions en C
2011/2012
Au lieu dcrire
if( x>=0 && y>=0 ) inst1; if( x<0 && y>=0 ) inst2; if( x>=0 && y<0 ) inst3; if( x<0 && y<0 ) inst4; 4 tests en total
if(x>=0) if(y>=0) inst1; else inst3; else if(y>=0) inst2; else inst4; 2 tests en total
Eviter le pige de confondre le test dgalit (==) laffectation (=) Au lieu dcrire if( a == 0 ) inst; On crit if( a = 0 ) inst; b. Branchement multiple ( switch )
Elle ralise un aiguillage vers diffrentes instructions en fonction de la valeur dune variable de contrle appele selecteur - Syntaxe: switch ( slecteur ) { case val1 : { instructions 1 ; break ;} case val2 : { instructions 2 ; break ;}... case valN : { instructions N ; break ;} default : { instructions x ; break ;} } Remarque : Le fonctionnement de cette instruction est le suivant : - s'il existe un nonc case avec une constante qui gale la valeur de slecteur, le contrle est transfr l'instruction qui suit cet nonc; - si un tel case n'existe pas, et si nonc default existe, alors le contrle est transfr l'instruction qui suit l'nonc default ; - si la valeur de expression ne correspond aucun nonc case et s'il n'y a pas d'nonc default, alors aucune instruction n'est excute. Attention. Lorsqu'il y a branchement russi un case, toutes les instructions qui le suivent sont excutes, jusqu' la fin du bloc ou jusqu' une instruction de rupture (break). Exemples: Programme qui simule une calculatrice 4 oprations #include <stdio.h> int main() { short a,b , char operateur ; printf("Entrez un oprateur (+, -, * ou /) : ") ; scanf("%c", &operateur) ; printf("Entrez deux entiers : ") ; scanf("%hd %hd", &a,&b) ; switch (operateur)
Page 5 Mahdia AZZOUZ
Chapitre V
Instructions en C
2011/2012
{case '+' : printf("a + b = %d\n",a+b) ; break ; case '-' : printf("a - b = %d\n",a-b) ; break ; case '*' : printf(" a * b = %d\n",a*b) ; break ; case '/' : {if(b!=0) printf("a / b = %d\n",a/b) ; else printf(",Division par zero\n",); break ;} default : printf("oprateur inconnu\n") ; } return 0 ; } 6.2 Structures rptitives (Boucles ) Les structures rptitives (ou Boucles) permettent de rpter une srie dinstructions tant quune certaine condition reste vraie. On appelle parfois ces structures instructions ditrations. En langage C, les structures rptitives peuvent tre exprimes par : - les instructions while et do while - linstruction for a. while et do while
Les instructions while et do while reprsentent un moyen d'excuter plusieurs fois la mme srie d'instructions. - Syntaxe:
while ( condition ) { liste d'instructions } do
{
liste d'instructions
}
while ( condition );
Dans la structure while on vrifie la condition avant dexcuter la liste dinstructions, tandis que dans la structure do while on excute la liste dinstructions avant de vrifier la condition Exemples: 1. Code C pour imprimer les entiers de 1 9: #include <stdio.h> int main() { int i; i = 1; while (i < 10) {printf("\n i = %d",i); i++; } return 0 ;} 2. Code C pour contrler la saisie au clavier dun entier entre 1 et 10 : #include <stdio.h> int main() { int a; do {printf("\n Entrez un entier entre 1 et 10 : "); scanf("%d",&a);} while ((a <= 0) || (a > 10)); return 0 ;}
Page 6 Mahdia AZZOUZ
Chapitre V
Instructions en C
2011/2012
b. For A linstar des instructions while et do while, linstruction for permet d'excuter plusieurs fois la mme srie d'instructions. Syntaxe:
for ( expression1 ; expression2 ; expression3 ) { liste d'instructions }
Dans la construction de for : expression1 : effectue les initialisations ncessaires avant lentre dans la boucle ; expression2 : est le test de continuation de la boucle ; Si le test est valu en vrai alors excution du corps de la boucle sinon on quitte la structure for;
- expression3 : est value la fin du corps de la boucle. Remarque : En pratique, expression1 et expression3 contiennent souvent plusieurs initialisations spares par des virgules. Les expressions expression1 et expression3 peuvent tre absentes (les points-virgules doivent cependant apparatre). Par exemple : for ( ; expression2 ; ) Lorsque expression2 est absente [ for( ; ; ) ], l'expression correspondante est considre comme vraie. Dans ce cas, il faut prvoir linstruction break au sein du bloc de for pour viter une boucle infinie. Par dfinition, la construction de for
for ( expression1 ; expression2 ; expression3 ) { liste d'instructions }
Exemples:
1. Code en C pour calculer et afficher la somme de 1 n : #include <stdio.h> int main() { int i, total , n, total; Scanf("%d",&n); for ( total = 0, i = 1 ; i<=n ; i++ ) total += i ; printf("La somme des nombres de 1 %hd est %hd\n", n,total) ; return 0; }
Chapitre V
Instructions en C 2. Code en C pour calculer et afficher la factorielle dun entier n : #include <stdio.h> int main() { int i, fact , n; Scanf("%d",&n); for ( i = 1, fact = 1 ; i <= n ; i++) fact *= i; printf("%d ! = %d \n",n,fact); return 0; }
2011/2012
6.3 Instructions break et continue a. Linstruction break On a vu le rle de l'instruction break; au sein d'une instruction de branchement multiple switch. L'instruction break peut, plus gnralement, tre employe l'intrieur de n'importe quelle boucle (for ; while ; do while ). Elle permet labandon de la structure et le passage la premire instruction qui suit la structure. En cas de boucles imbriques, break fait sortir de la boucle la plus interne. b. Linstruction continue L'instruction continue peut tre employe l'intrieur dune structure de type boucle (for ; while ; do while). Elle produit labandon de litration courante et fait passer directement litration suivante dune boucle. En cas de boucles imbriques, linstruction continue concerne la boucle la plus proche. Exemples: Que fait ce programme? int main() { int i , j ; printf("donner la valeur de I et j"); scanf("%d%d",&j,&j); for ( ; i>0 && j>0 ; i--, j-- ) { if ( i == 5 ) continue ; printf("i : %d et j : %d\n, i, j) ; if ( j == 5 ) break ; } return 0 ; }
Affichage i: 2 et j : 3 i: 6 et j : 3 i: 4 et j : 1 i: 3 et j : 5
Chapitre V
Instructions en C
2011/2012
6.4 Instruction goto (aller ) Elle permet de se brancher une instruction donne (dsigne par une tiquette) du programme - Syntaxe: goto etiquette ; Remarque : - linstruction goto peut se placer aprs ou avant linstruction de branchement; #include<stdio.h> int main { etiq: inst1 ; inst2 ; : instn ; condition goto etiq ; return 0 ; } #include<stdio.h> int main { condition goto etiq ; : etiq : inst1 ; inst2 ; : instn ; return 0 ; }
Exemples: Que fait ce programme? int main() { int x,y; x=5 ; etiq : y=x/2 ; x-- ; printf(" %d%d",x,y) ; if (x>0) goto etiq; printf(" %d%d",x,y) ; return 0 ; }
Actions dclarations x=5 ; y=x/2 ; x-- ; y=x /2 ; x-- ; y=x/2 ; x-- ; y=x/2 ; x-- ; y=x/2 ; x-- ; x ? 5 5 4 4 3 3 2 2 1 1 0 ? ? 2 2 2 2 1 1 1 1 0 0 y
Mthodes de Tri
2011/2012
Introduction
Les tableaux permettent de stocker plusieurs lments de mme type au sein d'une seule entit, Lorsque le type de ces lments possde un ordre total, on peut donc les ranger en ordre croissant ou dcroissant. Trier un tableau c'est donc ranger les lments d'un tableau en ordre croissant ou dcroissant Dans ce cours on ne fera que des tris en ordre croissant. Il existe plusieurs mthodes de tri qui se diffrencient par leur complexit d'excution et leur complexit de comprhension pour le programmeur. Nous allons explorer dans ce cours trois mthodes de Tri Tri par insertion Tri par recherche de minimum (par slection) Tri par bulle
Mthodes de Tri
2011/2012
Programme : /* Tri par insertion */ #include <stdio.h> #include <stdlib.h> int main() { int t[100],tt[100],n,i,j,l,k=0; // lecture de la taille n avec vrification do {printf("Donner la valeur de n:"); scanf("%d", &n); } while(n<0 || n>100); // lecture des lments de tableau de t for(i=0;i<n; i++) {printf("Donner t[%d] :",i); scanf("%d",&t[i]); } tt[0]=t[0]; for(i=1; i<n;i++) { //recherche dans le vecteur tt j=0; while(j<=k && tt[j]<t[i]) j++; if(j>k) {k++; tt[k]=t[i]; } else {//effectuer des dcalages vers la droite k++; for(l=k; l>=j; l--) tt[l]=tt[l-1]; tt[j]=t[i]; } } // affichage de t for(i=0;i<n;i++) printf("%5d",t[i]); printf("\n"); // affichage de tt for(i=0;i<n;i++) printf("%5d",tt[i]); printf("\n"); system("PAUSE"); return 0; }
Mthodes de Tri
2011/2012
Ensuite, on recommence parcourir le tableau partir de l'indice 1 pour trouver la plus petite valeur que l'on stocke l'indice 1. Et ainsi de suite pour l'indice 2, 3 jusqu' n - 2. Le tableau suivant montre comment l'algorithme fonctionne sur un tableau de 5 lments. Etat initial de T Permutation 1 Permutation 2 Pas Permutation Permutation 3 T Tri Programme : /* Tri par recherche de minimum */ #include <stdio.h> #include <stdlib.h> int main() { int t[100],n,i,j,posmin,x; // lecture de la taille n avec vrification do {printf("Donner la valeur de n:"); scanf("%d", &n); } while(n<0 || n>100); // lecture des lments de tableau de t for(i=0;i<n; i++) {printf("Donner t[%d] :",i); scanf("%d",&t[i]); } for(i=0; i<n-1;i++) {posmin=i; for(j=i+1;j<n;j++) if(t[posmin]>t[j]) posmin=j; if(i!=posmin) {//permutation x=t[i]; t[i]=t[posmin]; t[posmin]=x; } } // affichage de t for(i=0;i<n;i++) printf("%5d",t[i]); printf("\n"); system("PAUSE"); return 0;}
Page 3 Mahdia AZZOUZ
5 1 1 1 1 1
1 5 2 2 2 2
4 4 4 4 4 4
8 8 8 8 5 5
2 2 5 5 8 8
Mthodes de Tri
2011/2012
Mthodes de Tri
2011/2012
Programme : /* Tri par bulles */ #include <stdio.h> #include <stdlib.h> int main() { int t[100],n,i,x, esttrie=0; // lecture de la taille n avec vrification do { printf("Donner la valeur de n:"); scanf("%d", &n); } while(n<0 || n>100); // lecture des lments de tableau de t for(i=0;i<n; i++) { printf("Donner t[%d] :",i); scanf("%d",&t[i]); } // Affichage de T avant le tri printf(" Le tableau T non tri\n"); for(i=0;i<n;i++) printf("%5d",t[i]); printf("\n"); // Tri par bulles while (esttrie==0) {esttrie=1; for (i=0;i<n-1;i++) if (t[i]>t[i+1]) { x=t[i]; t[i]=t[i+1]; t[i+1]=x; esttrie=0; } } // affichage de t aprs le tri printf(" Le tableau T tri\n"); for(i=0;i<n;i++) printf("%5d",t[i]); printf("\n"); system("PAUSE"); return 0; }
Mthodes de Tri
2011/2012
Conclusion (Complexit)
Complexit de la mthode de Tri par Slection : Le pire cas, le plus mauvais cas et le cas moyen sont pareils. Pour trouver le plus petit lment, (n-1) itrations sont ncessaires, pour le 2me plus petit lment, (n-2) itrations sont effectues Pour trouver le dernier plus petit lment, 0 itration sont effectues. Le nombre ditrations que lalgorithme effectue est donc: 1
Complexit de la mthode de Tri par Insertion : Comme nous navons pas ncessairement scanner toute la partie dj trie, le pire cas, le meilleur cas et le cas moyen peuvent diffrer entre eux. Meilleur cas: Chaque lment est insr la fin de la partie trie. Dans ce cas, nous navons dplacer aucun lment. Comme nous avons insrer (n-1) lments, chacun gnrant seulement une comparaison, la complexit est en . Pire cas: Chaque lment est insr au dbut de la partie tri. Dans ce cas, tous les lments de la partie trie doivent tre dplacs chaque itration. La ime itration gnre (i-1) comparaisons et changes de valeurs: 1 2 1 2 2
Complexit de la mthode de Tri par Bulles : Il y a au maximum n boucles while et dans chaque boucle while un parcours de tous les lments du tableau et des oprations en O(1). La complexit est donc en O(n2).
Chapitre VI
Structures En C
2011/2012
1. Dfinition:
Une structure est une collection de donnes regroupes dans une entit logique. Ces donnes appeles aussi champs peuvent tre de mme type ou de type diffrents ; Il peut sagir de donnes simple (int, float, long, char, ...), des tableaux, des chanes de caractres ou mme des donnes qui sont elles mme des structures. pour dfinir une structure en C, il faut suivre cette syntaxe. Prototype : struct nom de la structure Exemples : ; ;; ; ;
1- Au lieu de dclarer trois variables indpendantes pour rfrencer une date, on dfinit une structure qui regroupe 3 champs de type entier de la manire suivante : struct date ; ; ; ; ou bien struct date , , ; ;
2- on peut regrouper les informations dcrivant un tudiant dans une structure comme suit : struct etudiant ; , ; _ ; ;
1- struct date X ;
X est une variable qua la structure date ; Cette variable occupe un espace de 6 octets en mmoire centrale.
X 24 2- struct etudiant E ;
02
2012
E est une variable qua la structure tudiant ; Cette variable occupe un espace de 45 octets en mmoire centrale.
08
1992
Chapitre VI
Structures En C
2011/2012
2- On peut faire en mme temps la dfinition dune structure et la dclaration dune variable. struct date ou encore struct , , , , ; X; ; X;
1- Pour mettre la valeur 24 fvrier 2012 dans la variable X de lexemple prcdent, on crira :
X.jour=24 ; X.mois=2 ; X.annee=2012 ; 2- Introduire les informations dun tudiant par saisie au clavier : #include <stdio.h> int main() { struct date { int jour, mois, annee;}; struct etudiant { long int matricule ; char nom[20],prenom[15]; struct date date_naiss ;} E; printf("Donner le matricule de l'tudiant :") ; scanf("%ld", &E.matricule) ; printf("Donner le nom et le prnom de l'tudiant :") ; scanf("%s%s", &E.nom, &E.prenom) ; printf("Donner la date de naissance de l'tudiant :") ; scanf("%d%d%d", &E.date_naiss.jour, &E.date_naiss.mois, &E.date_naiss.annee) ; getchar(); return 0 ; } 3- Un nombre complexe peut tre reprsent par une structure deux champs : la partie relle et la partie imaginaire. Ecrire un programme C qui permet de lire deux nombres complexes nb1 et nb2 donns et calcule leur somme, leur produit, la norme de nb1 et affiche les rsultats trouvs. (Les nombres complexes obtenus seront affichs sous la forme a+bi si b>0, ou a-bi si b<0).
Chapitre VI
Structures En C
2011/2012
#include <stdio.h> #include <stdlib.h> #include <math.h> int main() {struct complexe {float reel, imaginaire;}nb1, nb2, S, P; double N ; printf("Donner le premier nombre complexe :\n") ; printf("Donner la partie relle:") ; scanf("%f", &nb1.reel) ; printf("Donner la partie imaginaire:") ; scanf("%f", &nb1.imaginaire) ; printf("Donner le deuxime nombre complexe :\n") ; printf("Donner la partie relle:") ; scanf("%f", &nb2.reel) ; printf("Donner la partie imaginaire:") ; scanf("%f", &nb2.imaginaire) ; // calcul de nb1+nb2 S.reel=nb1.reel+nb2.reel; S.imaginaire=nb1.imaginaire+nb2.imaginaire ; // calcul de nb1*nb2 P.reel=nb1.reel*nb2.reel-nb1.imaginaire*nb2.imaginaire; P.imaginaire=nb1.reel*nb2.imaginaire+nb1.imaginaire*nb2.reel; // calcul de norme nb1 N=sqrt(pow( nb1.reel,2)+pow(nb1.imaginaire,2)); // Affichage des rsultats sous la forme a+bi if (nb1.imaginaire>0) printf("Le premier nombre complexe nb1=%.2f+%.2fi sa norme N=%.2lf\n", nb1.reel, nb1.imaginaire, N) ; else printf("Le premier nombre complexe nb1=%.2f-%.2fi sa norme N=%.2lf\n", nb1.reel, fabs(nb1.imaginaire), N) ; if (S.imaginaire>0) printf("La somme S=%.2f+%.2fi\n", S.reel, S.imaginaire) ; else printf("La somme S=%.2f-%.2fi\n", S.reel, fabs(S.imaginaire)) ; if (P.imaginaire>0) printf("Le produit P=%.2f+%.2fi\n", P.reel, P.imaginaire) ; else printf("Le produit P=%.2f-%.2fi\n", P.reel, fabs(P.imaginaire)) ; system("PAUSE"); return 0 ; } 4- Etant donne lheure actuelle en H, M, S ; Ecrire un programme C qui calcule lheure aprs S secondes.
Page 3 Mahdia AZZOUZ
Chapitre VI
Structures En C
2011/2012
#include <stdio.h> #include <stdlib.h> int main() {struct temps {int heure, minute, seconde;}X; int S ; do {printf("Donner l'heure actuelle :\n") ; printf("Donner l'heure:") ; scanf("%d", &X.heure) ; printf("Donner les minutes:") ; scanf("%d", &X.minute) ; printf("Donner les secondes:") ; scanf("%d", &X.seconde) ; } while ((X.heure<0) || (X.heure>24) || (X.minute<0) || (X.minute>59) || (X.seconde<0) || (X.seconde>59)) ; printf("Donner les secondes :") ; scanf("%d", &S) ; X.seconde=X.seconde+S ; X.minute= X.minute+S%60; X.seconde=X.seconde/60; X.heure=(X.heure+X.minute/60)%24; X.minute=X.minute/60 ; printf("L'heure aprs %d est %d :%d :%d",S, X.heure, X.minute, X.seconde ) ; system("PAUSE"); return 0 ; }
1- typedef int entier ; 2- typedef struct {int heure, minute, seconde} temps ;
Page 4 Mahdia AZZOUZ
Chapitre VI
Structures En C
2011/2012
Pour dclarer une variable X de type temps on crira temps X ; Pour manipuler X : X.heure=10 ; X.minute=10 ; X.seconde=5 ; On pourra crire sizeof(X) ; ou bien sizeof(temps) ; Lcriture temps T[10] correspond la dclaration dun tableau structur ou chaque lment correspond une variable de type temps. Heure T: Minute 11 12 7 12 30 50
Soit une chane de caractres ch de longueur <= 80, crire un programme C qui construit un vecteur dans lequel on sauvegarde, pour chaque caractre de la chane, sa frquence dapparition.
#include <stdio.h> #include <stdlib.h> int main() {typedef struct {char car ; int freq;}ST; char ch[81] ; ST T[80] ; int i,j, BS=-1 ; printf("Donner la chaine ch:" ) ; gets(ch); for(i=0; ch[i]!='\0'; i++) { // vrifier si la caractre ch[i] n'existe pas dans T for(j=0;j<=BS&&ch[i]!=T[j].car; j++); if(ch[i]==T[j].car)T[j].freq++; else { BS++; T[BS].car=ch[i]; T[BS].freq=1; } } for(i=0; i<=BS; i++) printf("le caractre c=%2c et son frquence freq=%2d\n", T[i].car, T[i].freq); system("PAUSE"); return 0 ; }
Chapitre VII
Pointeurs
2011/2012
1. Dfinition:
Un pointeur cest une variable qui contient ladresse mmoire dune autre variable. Une valeur particulire des pointeurs dfinie dans le fichier <stdio.h> indique le pointeur ne contient aucune adresse valide (correcte), il sagit de la valeur nulle NULL . Exemple : P 200 200 x - P : est un pointeur. - x est une variable dadresse 200 - On dit que P pointe sur x. - P contient ladresse de la variable x.
3. Oprateurs de base:
Lors du travail avec des pointeurs, nous avons besoin : - Dun oprateur adresse de : & : est appel oprateur de calcul dadresse, il permet davoir ladresse dune variable en mmoire. - Exemple : int x ; int *p ; p=&x ; (dans p on aura ladresse de x) - Et dun oprateur contenu de : * : il permet davoir le contenu dune case mmoire pointe par un pointeur.
Chapitre VII
Pointeurs
2011/2012
Exemples de manipulation de pointeurs : Exemple 1 : #include <stdio.h> int main() { int x, y, *p ; x=10 ; p=&x ; y=*p+5 ; printf("La valeur de p est %p\n",p); printf("La valeur de x est %d\n",x); printf("La valeur de x est %d\n",*p); p++ ; printf("La valeur de p est %p\n",p); printf("La valeur de y est %d\n",y); return 0 ; } Remarques 1- A la rencontre de linstruction p++, le systme incrmente p de nombre doctets correspond la variable pointe. 2- Aprs linstruction p=&x, les expressions suivantes sont quivalentes : y=*p+1 *p=*p+10 *p+=2 ++*p (*p)++ y=x+1 x=x+10 x+=2 ++x x++
Pour la dernire instruction, les parenthses sont ncessaires, comme les oprateurs * et ++ sont valus de droit vers la gauche, sans les parenthses p serait incrment, non pas lobjet sur le quel pointe p.
Chapitre VII
Pointeurs
2011/2012
Exemple 2 : #include <stdio.h> int main() { int A = 1; int B = 2; int C = 3; int *P1, *P2; P1=&A; P2=&C; *P1=(*P2)++; P1=P2; P2=&B; *P1-=*P2; ++*P2; *P1*=*P2; A=++*P2**P1; P1=&A; *P2=*P1/=*P2; return 0 ;} Compltez le tableau pour chaque instruction du programme ci-dessus.
Dclaration P1=&A P2=&C *P1=(*P2)++ P1=P2 P2=&B *P1-=*P2 ++*P2 *P1*=*P2 A=++*P2**P1 P1=&A *P2=*P1/=*P2 A 1 1 1 3 3 3 3 3 3 24 24 6 B 2 2 2 2 2 2 2 3 3 4 4 6 C 3 3 3 4 4 4 2 2 6 6 6 6 P1 ? &A &A &A &C &C &C &C &C &C &A &A P2 ? ? &C &C &C &B &B &B &B &B &B &B
Chapitre VII
Pointeurs
2011/2012
Cette instruction ch= "Blida" ; se traduit par 1- chercher une zone mmoire libre qui peut centenaire la chane (au moins 6 Octets). 2- crire dans lespace mmoire la chane "Blida". 3- mettre ladresse de premier lment de la chane dans le pointeur ch.
ch 100
100 B` l` i`
d`
a`
\0`
ch est utilis comme nom de la chane et comme un pointeur. On pourra crire : - printf("Ladresse de la chane ch est %p",p) ; - printf("Le contenu de la chane ch est%s",ch) ; Si on crira par la suite de programme ch="Londres"; on aura :
ch 600
100 B` l` i`
d`
a`
\0`
600 L`
o`
n`
d`
r`
e`
s`
\0`
Exercice : crire un programme C qui lit un entier entre 1 et 7 et affiche le jour de la semaine. utiliser un tableau de pointeurs vers des chanes de carctres. Solution : #include <stdio.h> int main() { char *p[7]={"Samedi", "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi"} int i ; do{printf("donner la position de jour") ; Scanf("%d",&i) ; } while(j<1 || j>7) ; puts(p[i-1]) ; return 0 ;} Schma : P[0] 100 100
"Samedi"
Chapitre VII
Pointeurs
2011/2012
Remarque char *ch ; Incorrecte gets(ch) ; Cette suite dinstructions est incorrecte parce que ce quon a rserv est 2 Octets pour le pointeur. Donc si la taille de la chane lue par la fonction gets dpasse 2 octets, on aura un crasement de mmoire (perte de donnes au niveau de mmoire). 4.3 Pointeurs et tableau une dimension (vecteurs): A la dclaration dun vecteur le systme alloue automatiquement un espace de 2 octets contenant ladresse de premier lment de vecteur. En plus la dclaration dun espace contigu pour les lments de vecteurs. Le pointeur de vecteur aura le nom dclar pour le vecteur. En effet, la dclaration float t[10] se traduit par : - Rservation dun espace mmoire contigu de taille 40 Octets pour les lments de t. - Rservation dun espace de 2 Octets supplmentaire pour sauvegarder ladresse de premier lment de t. t
200
200
*(t+1) *(t+i)
Exercice : Drouler le programme suivant : #include <stdio.h> int main() { int a[4]={11, 22, 33, 44}, *p, x; p=&a[0]; p++; x=*p; x=*p+1; x=*(p+1); x=*++p; x=*p++; x=++*p; return 0 ;}
Page 5 Mahdia AZZOUZ
Chapitre VII
Pointeurs
2011/2012
Exercice : Remplir les lments de vecteur t[4] par des multiples de 5. Solution 1: #include <stdio.h> int main() { int t[4], i; for(i=0;i<4; i++) *(t+i)=i*5; return 0 ;} Solution 2: #include <stdio.h> int main() { int t[4], i, *p; for(p=t, i=0;i<4; i++, p++) *p=i*5; return 0 ;} Le pointeur p pointe vers le dernier lment. 4.4 Pointeurs et tableau deux dimensions (matrice): La dclaration dune matrice A[n][m] en C se traduit par la rservation de 3 espaces en mmoire. - Un espace contigu de taille n*m*sizeof(type des lments) pour contenir les lments de la matrice. Les lments de la matrice sont rangs ligne par ligne en mmoire do un espace contigu de n pointeur forme un vecteur ou chaque lment de ce vecteur pointe vers le premier lment de chaque ligne de la matrice. Un espace de 2 Octets appel A contenant ladresse de dbut de vecteur de pointeur. Schma : Vecteur de pointeurs pour n lignes Matrice A
Pointeur dentre A Exercice : Ecrire un programme C qui remplit une matrice m[4][3] par clavier puis laffiche en utilisant le formalisme pointeur . Ladresse de dbut dune ligne i de la matrice est m[i] (le vecteur de pointeur). On m[i]=*(m+i)=&m[0][0]. Pour accder un lment de ligne i et colonne j on fait un saut au jme colonne do &m[i][j]=*(m+i)+j et m[i][j]=*(*(m+i)+j) ;
Chapitre VII
Pointeurs
2011/2012
Solution: #include <stdio.h> int main() { int m[4][3], i, j; //Lecture for(i=0;i<4; i++) for (j=0; j<3; j++) {printf("donner m[%d][%d]",i, j); scanf("%d",*(m+i)+j); } //Affichage for(i=0;i<4; i++) {for (j=0; j<3; j++) printf("%5d",*(*(m+i)+j)); printf("\n"); } system("PAUSE"); return 0 ;}
4.5 Pointeurs et structures: Soit les deux types structurs dfinis comme suit : typedef struct{int j, m, a ;} date ; typedef struct{char nom[20]; char prenom[15]; date date_naiss;} Personne; Personne X ; // X est une variable structure de type personne ; Linitialisation de X se fait comme suit : X.nom="MILAOUI" ; X.prenom="Amel" ; X.date_naiss.j=24 ; X.date_naiss.m=10 ; X.date_naiss.a=1992 ; - Linstruction suivante personne *P ; est interprte comme suit : P est un pointeur vers la structure personne. - Linstruction p=&X ; sinterprte comme suit : P contient ladresse mmoire de la variable structure X. - Laccs aux diffrents champs de la variable X peut se faire par pointeur et on crira : P nom="MILAOUI" ; P prenom="Amel" ; P date_naiss.j=24 ; P date_naiss.m=10 ; P date_naiss.a=1992 ;
Page 7 Mahdia AZZOUZ
Chapitre VIII
Fonctions
2011/2012
1. Dfinition:
Une fonction est un sous programme crit une seule fois et pouvant tre appel plusieurs fois. En modifiant les paramtres dappel. Une fonction peut tre appele par le programme principal (main) ou par une autre fonction. Elle peut admettre ou non des paramtres dans son nom. Une fonction peut renvoyer ou non un rsultat dans son nom. Une fonction peut avoir des variables propres elle (dites variables locales). Une fonction un seul point dentr et peut avoir plusieurs points de sorties (par linstruction return ou automatiquement aprs la dernire instruction). Remarques : - Le langage C ne fait pas la diffrence entre procdure et fonction. une procdure est une fonction qui ne retourne aucun rsultat dans son nom. - Le langage C ne permet pas la dclaration dune fonction dans une autre fonction.
float *f2() : {
:
Remarque : Dans le cas ou une fonction ne renvoie pas de rsultats dans son nom elle aura le type void (procdure).
Page 1 Mahdia AZZOUZ
Chapitre VIII
Fonctions
2011/2012
Chapitre VIII
Fonctions
2011/2012
#include <stdio.h> #include <stdlib.h> // le prototype de la fonction float moyenne(int X, int Y); int main() {int A, B, C, D; float M1, M2; printf("Donner A et B: "); scanf("%d%D",&A,&B); M1=moyenne(A,B); printf("La moyenne de A=%d et B=%d est M1=%.2f\n",A,B,M1); printf("Donner C et D: "); scanf("%d%D",&C,&D); M2=moyenne(C,D); printf("La moyenne de C=%d et D=%d est M2=%.2f\n",C,D,M2); system("PAUSE"); return 0; } // le corps de la fonction moyenne float moyenne(int X, int Y) {float Z; Z=float(X+Y)/2; // ou bien Z=(x+y)/2.0; return Z; }
Chapitre VIII
Fonctions
2011/2012
Exemples : #include <stdio.h> #include <stdlib.h> void carre(int X) { X=X*X ; } int main() { int A=15; Carre(A); printf("Le carr de A est %d\n",A); system("PAUSE"); return 0; }
15
15
15 225
Remarque : Dans ce mode de transmission le compilateur fait une copie de la valeur de paramtre dappel dans une zone mmoire propre la fonction. Toutes les modifications se feront dans cette zone mmoire qui sera dtruite la sortie de la fonction. 4.2 Mode de transmission par variable (adresse): Ce mode permet la fonction appele de modifier une ou plusieurs variables de la fonction appelante. En ce mode de transmission se fait en utilisant les pointeurs. En moment de lappel il faut transmettre ladresse de la variable modifier. Exemples : #include <stdio.h> #include <stdlib.h> void carre(int *X) { *X=(*X)*(*X) ; } int main() { int A=15; Carre(&A); printf("Le carr de A est %d\n",A); system("PAUSE"); return 0;}
Mmoire Centrale Zone de donnes programme appelant 100 A 15 225 Zone de donnes fonction 100
Chapitre VIII
Fonctions
2011/2012
Exercice : Soit une suite de valeurs entires, crire une fonction qui calcule le nombre de valeurs positives et le nombre de valeurs ngatives. Solution : a- Premier prototype : int compte(int n, int *nbneg) ; ( dans le nom de la fonction on retourne le nombre de valeurs positives et par adresse on retourne le nombre de valeurs ngatives). b- Deuxime prototype : void compte(int n, int *nbpos, int *nbneg) ; ( on fait retourner les deux compteurs des valeurs positives et ngatives par adresse et la fonction est de type void). a- Premier prototype : #include <stdio.h> #include <stdlib.h> int compte(int n, int *nbneg) { int x, i,nbpos=0; *nbneg=0; for(i=0; i<n; i++) { printf("Donner une valeur: "); scanf("%d", &x); if(x<0) (*nbneg)++; else if(x>0) nbpos++; } return nbpos; } int main() {int n, nbpos, nbneg; printf("Donner le nombre de valeur : "); scanf("%d", &n); nbpos=compte(n,&nbneg); printf("Le nombre de valeurs positives est %d\n",nbpos); printf("Le nombre de valeurs negatives est %d\n",nbneg); system("PAUSE"); return 0; }
Chapitre VIII
Fonctions
2011/2012
b- Deuxime prototype : #include <stdio.h> #include <stdlib.h> void compte(int n, int *nbneg, int *nbpos) { int x, i; *nbneg=*nbpos=0; for(i=0; i<n; i++) { printf("Donner une valeur: "); scanf("%d", &x); if(x<0) (*nbneg)++; else if(x>0) (*nbpos)++; } } int main() {int n, nbpos, nbneg; printf("Donner le nombre de valeur: "); scanf("%d", &n); compte(n,&nbneg,&nbpos); printf("Le nombre de valeurs positives est %d\n",nbpos); printf("Le nombre de valeurs negatives est %d\n",nbneg); system("PAUSE"); return 0; }
Chapitre VIII
Fonctions
2011/2012
Solution : #include <stdio.h> #include <stdlib.h> void const_tab(int *T) { int x, i,j=-2,k=-1; for(i=0; i<10; i++) { printf("Donner une valeur: "); scanf("%d", &x); if(x%2==0) { j+=2; T[j]=x; } else { k+=2; T[k]=x; } } } int main() {int T[20], i; //Initialisation de T 0 for(i=0; i<20; i++) T[i]=0; const_tab(T); //Affichage de T aprs construction for(i=0; i<20; i++) printf("%5d",T[i]); system("PAUSE"); return 0; }
Chapitre VIII
Fonctions
2011/2012
2. crire une fonction qui compare deux mots m1 et m2 de longueurs<=30et retourne : 0 1 2 1 1 2 1 1 2 Et dans le programme principal on aura laffichage suivant 1 1 1 2 2 2
Solution :
#include <stdio.h> #include <stdlib.h> int compare(char *m1, char *m2) {int i=0; while(m1[i]!='\0' && m2[i]!='\0'&& m1[i]==m2[i]) i++; if(m1[i]<m2[i]) return -1; else if(m1[i]>m2[i]) return 1; else return 0;} int main() {char m1[31], m2[31]; printf("Donner le premier mot: "); gets(m1); printf("Donner le second mot: "); gets(m2); if(compare(m1,m2)==0) printf("Les deux mots sont gaux\n"); else if(compare(m1,m2)==1) printf("m1 est le suivant m2\n"); else printf("m1 est avant m2\n"); system("PAUSE"); return 0; } Remarque : cette fonction est dfinie dans le fichier <string.h>. Cest la fonction strcmp : strcmp(<s>, <t>): compare <s> et <t> lexico graphiquement et fournit un rsultat: - ngatif si <s> prcde <t> - zro si <s> est gal <t> - positif si <s> suit <t> Tel que : Les symboles <s> et <t> peuvent tre remplacs par : - Une chane de caractres constante. - Le nom d'une variable dclare comme tableau de char. Un pointeur sur char.
Page 8 Mahdia AZZOUZ
Chapitre VIII
Fonctions
2011/2012
2011/2012
Explication fournit la longueur de la chane sans compter le '\0' marque de fin de la chane copie <t> vers <s> ajoute <t> la fin de <s> compare <s> et <t> lexico graphiquement et fournit un rsultat: - ngatif si <s> prcde <t> - zro si <s> est gal <t> - positif si <s> suit <t> copie au plus <n> caractres de <t> vers <s> ajoute au plus <n> caractres de <t> la fin de <s>
2011/2012
Les fonctions de conversion suivantes fournissent une valeur du type int qui peut tre reprsente comme caractre; la valeur originale de <c> reste inchange: Fonction tolower(<c>) toupper(<c>) Explication retourne <c> converti en minuscule si <c> est une majuscule retourne <c> converti en majuscule si <c> est une minuscule