Cours Prog1 VF R SAIDI
Cours Prog1 VF R SAIDI
Cours Prog1 VF R SAIDI
1. Projection des notions dalgorithmique vers un langage de programmation 2. 2 Prise en main des lments de base du Langage C
Bibliographie
Langage C
Brian W. Kernighan, Dennis M. Ritchie : Le langage C : Norme ANSI ditions Dunod, S t b 2004 D d Septembre Robert Sedgewick : Algorithmes en langage C dition DUNOD, 2005
Exercices en C
C. Delannoy : Programmer en langage C avec exercices corrigs, 5e dition 2009
Chapitre 3 Quelques fonctions particulires 3Les Entres (Input) Les Sorties (Output)
Prliminaire
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 d l rsoudre l l ith i i t de le d
Algorithme : squence doprations visant la rsolution dun problme en un p temps fini
Historique du langage C
1972 : Dennis Ritchie (chercheur dans les laboratoires Bell) a conu le langage C pour dvelopper une version portable du systme dexploitation UNIX 1978 : une 1re dfinition du langage est apparue avec louvrage de Ritchie et K i h Th C programming l t Kernighan The i language Annes 80 : le langage C est devenu de plus en plus populaire que ce soit dans l monde acadmique que celui d professionnels d le d d i l i des f i l 1983 : lorganisme ANSI American National Standards Institute chargeait une commission d mettre au point une dfi iti h it i i de tt i t dfinition explicite et li it t indpendante de la machine pour le langage C 1989 : dfi iti d l norme ANSI C dfinition de la ANSI-C
Une fois lalgorithme et les structures de donnes dfinis, on les code en un g g g langage informatique et on obtient un programme
Programme : suite dinstructions permettant de raliser une ou plusieurs tches, de rsoudre un problme, de manipuler des donnes
Caractristiques du langage C
Universel : C n'est pas orient vers un domaine d'applications spciales Proche de la machine : il offre des oprateurs qui sont trs proches de ceux du langage machine (ex. la gestion de la mmoire) Rapide : car trs proche du langage machine Indpendant de la machine : il peut tre utilis sur n'importe quel systme en possession d'un compilateur C d un Portable : en respectant le standard ANSI-C, il est possible d'utiliser le mme programme sur tout autre systme (autre hardware autre systme hardware, d'exploitation) Extensible : le langage est anim par des bibliothques de fonctions extensibles
tapes de la programmation en C
C est un langage compil ( par opposition aux langages interprts). Un programme C est dcrit par un fichier texte, appel fichier source traduit en langage machine (langage binaire). Cette opration est effectue par le compilateur C La compilation se dcompose en 4 phases successives : Prprocesseur : transformation purement textuelle (inclusion dautres fichiers sources) Compilation : t d it l fi hi pour C il ti traduit le fichier 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
10
Fin du programme
12
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 deux types de base : C,
les entiers les l l rels
Types simples
Type Entiers char int short [int] [int] long [int] [int] Rels float double long double Description caractres entiers entiers courts entiers longs nombres dcimaux nombres dcimaux de prcision suprieure nombres dcimaux encore plus prcis Octets 1 2 ou 4 2 4 4 8 10 ou 12
Remarques
Un caractre (char) 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 short, ou long Si l'on ajoute le prfixe unsigned l'une de ces variantes, alors on manipule des entiers non signs ti i
13 14
Type
Conditionne le format de la variable en mmoire
Valeur
Peut voluer pendant l'excution initialisation grce l'oprateur d'affectation (=)
18
Relationnels
<, <= , > , >= , != , == (galit) , =(affectation), ! (ngation), || (ou logique), && ou (et logique),%(reste de la division) t le rsultat de la comparaison est un entier valant
0 si le rsultat de la comparaison est faux 1 si le rsultat de la comparaison est vrai
Exemple
a = 2+3 a = 3%2 a = (6 5) (6==5) a = (2!=3) a = (6<=3) a =((3==3) || (6<=3)) a =((3==3) && (6<=3)) valeur de a : 5 valeur de a : 1 valeur de a : 0 valeur de a : 1 valeur de a : 0 valeur de a : 1 valeur de a : 0
19
Pr-incrmentation ++<var>; quivalente <var>=<var>+1; Pr-dcrmentation --<var>; quivalente <var>=<var>-1; Dans une expression, la valeur de la variable <var> est d'abord incrmente (ou dcrmente), puis utilise
20
21
22
Exercice 1
Donner la valeur de i, j, n aux endroits demands
#include<stdio.h> main() { int i, j, i t i j n; i=0;n=i++; A:i=?n=? i=10; n=++i; B:i=?n=? i=20; j=5; n=i++ * ++j; C:i=?n=? i=15; n=i+=3; D:i=?j=?n=? i=3; j=5; n=i*=--j; E:i=?j=?n=?
23
Priorit 1 2 3 4 5 6 7
Associativit
24
Exercice 2
Donner la valeur de n, p, q, r aux endroits demands #include<stdio.h> #include<stdio h>
main() { int n=10, p=5, q=10, r; ,p ,q , ; r=n== (p=q); A:n=? p=? q=?r=? n= p=q=5; n+=p+=q; B: n = ? p = ? q = ? q q=n<p ? n++ : p ; p p++; C: n = ? p = ? q = ? q= n>p ? n++ : p++; D: n = ? p = ? q = ? }
25 26
Priorit 1 2 3 4 5 6 7
Associativit
28
Exemples
printf("%f" , x ); printf("%3d" , n ); n = 20 n=3 n = 2358 n = -5200
29
x = 1.2345 x = 12.3456789
1.234500 12.345678
Exemple
32
Exercice
Ecrire un programme qui permute et affiche les valeurs de trois variables A, B, C de type entier saisis par le clavier( A-->B, B-->C, C-->A) Correction
#include<stdio.h> main() { int A, B, C i t A B C; int AIDE; p printf("Entrer la valeur de A, B et C :\t"); ( , ); scanf("%d %d %d", &A,&B,&C); printf("A=%d \t B=%d\t C=%d\n",A,B,C); AIDE= A; A=C; C=B; B=AIDE; printf("A=%d \t B=%d\t C=%d\n",A,B,C);
33
34
Des instructions de branchement conditionnel : if .else Des instructions de branchement multiple : switch
35
36
Exercice 1
Ecrire un programme qui affiche le plus grand de trois entiers saisis au clavier (A,B,C) Correction
#include<stdio.h> main() { int A,B,C, Max; p printf("entrer les valeurs des trois entiers (A, B, C) : "); ( e e es a eu s ose e s( , , ); scanf("%d %d %d",&A,&B,&C); if(A>B) Max = A; else Max = B; if(C>Max) Max = C; printf("le max de %d,%d et %d est : %d\n",A,B,C,Max); }
ou
if( expression) { Instruction1; } else { instruction2; }
expression : expression quelconque. p , , Aprs valuation, si elle est vraie, alors le 1er bloc dinstructions est excut, sinon cest le 2me bloc qui est excut bloc dinstructions : peut dsigner une suite dinstructions dlimites par d instructions des accolades ou une seule instruction
Max =(A>B?A:B)>C?(A>B?A:B):C;
Exemple
if (a == b) a=1; //si a gal b jaffecte 1 a a 1; j affecte if (a == b) a=1; else a=0; //si a gal b jaffecte 1 a sinon jaffecte 0 a
37
38
Exercice 2
Ecrire un programme qui rsout l'quation AX+B=0
Bien videmment, on n'oubliera pas tous les cas particuliers (notamment les cas "tout x est solution" et "pas de solution")
Structures de choix(3/3)
Branchement multiple : Switch Syntaxe
switch (expression) { case constante_1 : [ suite_d'instructions_1 ] ; case constante_2 : [ suite_d'instructions_2 ]; .............. case constante_n : [ suite_d'instructions_n ]; default : suite_d'instructions ; } Teste si une expression prend une p valeur parmi une suite de constantes, et effectue le branchement correspondant si cest le cas
Correction
#include<stdio.h> main() { float A,B; printf("Tapez la valeur de A :"); scanf("%f",&A); printf("Tapez la valeur de B :"); scanf("%f",&B); if(!A) /* if(A==0)*/ if(A 0)*/ { if(!B) /* if(B==0) */ printf("Tout X est solution"); else printf("Pas de solution"); } else printf("Une seule solution : %f", -B/A); }
39
Exemple
int a; switch ( ) it h (a) { case 7 : a=2; //si a gal 7 jaffecte 2 a case 4 : a=3; //si a gal 4 jaffecte 3 a a 3; j affecte default : a=0; //sinon jaffecte 0 a }
40
Exemple
int a=0; while(a<4) //tant que a<4 jexcute les instructions suivantes { a++; printf ("La valeur de a :%d \n", a); }
Exemple
int a=0; do //faire les instructions suivantes { a++; // jincrmente a d 1 ji t de printf ("La valeur de a :%d \n", a); } while(a<4); //tant que a<4 hile(a<4) q e
41 42
Structures itratives(3/3)
Instructions itratives : for
for( exp1 ; exp2 ; exp3 ) { instructions; }
Exercice 1
Ecrire un programme qui calcule n! dun entier saisi par le clavier. Utiliser une boucle while puis une boucle for Correction
// Avec la boucle while #include <stdio.h> main() { int n,i=1,fact= 1; printf("ENTRER UN ENTIER : "); //Avec la boucle for #include <stdio.h> main() { int n,i,fact= 1; printf("ENTRER UN ENTIER: "); scanf("%d",&n); for (i=1;i<=n;i++) fact fact= fact * i; printf("\nn = %d n! = %d",n,fact); }
exp1 : effectue les initialisations ncessaires avant lentre dans la boucle exp2 : est le test de continuation de la boucle ; le test est valu avant lexcution du corps de la l excution boucle exp3 : est excute la fin du corps de la boucle
Exemple
int a; for( a=0; a<4 ; a++ ) { printf ("L valeur de a :%d \ " a); i f ("La l d %d \n", ) }
Remarques : R En pratique, exp1 et exp3 contiennent souvent plusieurs initialisations spares par des virgules Les expressions exp1 et exp3 peuvent tre absentes (les points virgules doivent ( p g cependant apparatre) : for (;exp2;)
43
scanf("%d",&n); f("%d" & ) while (i<=n) { fact= fact * i; i++; } printf("\nn = %d n! = %d",n,fact); }
44
Exercice 2
Ecrire un programme qui affiche tous les diviseurs dun entier n saisi par le clavier. Utiliser la boucle dowhile Correction
#include <stdio.h> main() { int div=1,n; printf("ENTRER UN ENTIER: "); scanf("%d",&n); printf("\nLISTE DES DIVISEURS DE %d :",n); do { if(n%div==0) printf("\t%d",div); div++; } while(div<=n); }
45
Exemple int i, j ; for (i = 1 ; i<=10 ; i++) { for (j = 1 ; j<=10 ; j++) { if(j == 5) break ; printf("%d\t", i * j) ; } printf("\n") ; }
46
Exercice 1
Que fait ce programme?
#include <stdio.h> main() { int n=0; do { if(n%2==0) { printf("%d est pair \n ",n); n+=3; continue; } if(n%3==0) { printf("%d est multiple de 3 \n ",n); n+=5; 5 } if(n%5==0) { printf("%d est multiple de 5 \n ",n); break; break } n+=1; } while(1); }
Exemple int i, j ; //Initialisations for ( ; i>0 && j>0; i--,j--) { if(i == 5) continue; printf("i : %d et j : %d\n", i, j) ; if(j == 5) break ; }
Affichage i : 2 et j : 3 i : 1 et j : 2 i : 6 et j : 3 i : 4 et j : 1 i : 3 et j : 5
47
48
Exercice 2
crire un programme qui fournit la liste des nombres premiers infrieurs 50 Correction
#include <stdio.h> main() { int n; /* variable destine contenir les entiers infrieurs 50 */ int i; printf("1, 2"); /* Les deux premiers nombres premiers sont affichs */ /* Pour les entiers entre 3 et 50, on vrifie s'ils ont un diviseur autre que 1 */ for (n = 3; n <= 50; n+=2) { for f (i = 2; i*i <= n; i ) 2 i++) if (n%i==0) break; if (i*i > n) printf(", %d", n); } }
49 50
Dfinition
Ensemble de variables de mme type, de mme nom caractrises par un index La dclaration dun tableau rserve un espace de mmoire contigu dans lequel les lments du tableau peuvent tre rangs Exemple
Exemples
char X[80]; // Tableau de caractres de dimension 80 int T[10]; // Tableau dentiers de dimension 10
3 7 98 5 63 8 77
76
34
97
54
32
13
25
51
52
Remarques
Si la dimension n'est pas indique explicitement lors de l'initialisation, alors l ordinateur l'ordinateur rserve automatiquement le nombre d'octets ncessaires d octets
Exemple
0 9
1 8
2 10
3 6
. .
Valeur
int A[ ] = {10, 20, 30, 40, 50}; //taille en octet de (int)*nombre dlments Si la liste de constantes ne contient pas assez de valeurs pour tous les lments, les lments restants sont initialiss zro
Exemple
int A[5] = {10, 20, 30}; // quivalent : int A[5] = {10, 20, 30, 0,0}; Si le nombre de constantes est suprieur la dimension du tableau, le compilateur dclare une erreur
Exemple
53
54
Exercice 1
crire un programme qui calcule la moyenne de toutes les valeurs dun tableau de 4 rels {2.0, 16.5, 58.56, 19.92} Correction #include <stdio h> <stdio.h> main() { int i = 0; float moyenne sommeTotale = 0.0; moyenne, 0 0; /* On initialise notre tableau avec 4 valeurs de type float*/ float T[4] = {2.0, 16.5, 58.56, 19.92}; for f (i = 0 i < 4 i ) 0; 4; i++) { printf("Valeur de T[%d] = %f\n", i, T[i]); sommeTotale += T[i]; //Calcul de la somme des valeurs } moyenne = sommeTotale / 4; //Calcul de la moyenne y ; y printf("\n Moyenne des valeurs du tableau : %f", moyenne); }
55
Exercice 2
Ecrire un programme qui lit la dimension N d'un tableau T de type int (dimension maximale : 50), remplit le tableau par des valeurs entres au clavier et affiche l t bl l i t ffi h le tableau Effacer ensuite toutes les occurrences de la valeur 0 dans le tableau T et tasser l l t les lments restants. Affi h l t bl t t t Afficher le tableau rsultant lt t
Structure du programme
//Dclaration des variables // //Lecture de la dimension du tableau //Lecture des valeurs du tableau //Affichage d valeurs d t bl //Affi h des l du tableau //Suppression des zros //Affichage des valeurs du tableau rsultat
56
Exercice 2 : Correction
#include <stdio.h> main() {int N,i,j, T[50]; // Dclaration des variables //Lecture de la dimension du tableau printf("Donner la dimension du tableau (<50) :"); scanf("%d",&N); //Lecture des valeurs du tableau for(i=0;i<N;i++) { printf("T[%d] :", i); scanf("%d",&T[i]); } //Affichage des valeurs du tableau for(i=0;i<N;i++) f (i 0 i N i ) { printf("%d\t", T[i]); } //Suppression des zros for(i=0;i<N;i++) { if(T[i]==0) { for(j=i;j<N-1;j++) { T[j]=T[j+1]; } // Dcalage des lments du tableau N--; i--; } } //Affichage des valeurs du tableau rsultat rsultat. ..suite du programme
57
Si t[k] = x, alors recherche termine avec SUCCS Si t[k] x, alors passer llment suivant, sil y en a un ! l lment s il Sinon recherche termine avec CHEC
58
/* Dclarations */
Exemple
15
/* Recherche de la position de la valeur */ POS = -1; OS ; for(i=0 ; (i<N)&&(POS==-1) ; i++) if(A[i]==VAL) POS=i; / /* Edition du rsultat */ / if (POS==-1) printf("La valeur recherche ne se trouve pas dans le tableau.\n"); else printf("La valeur %d se trouve la position %d. \n", VAL, POS);
59 60
62
63
66
Exemple
Soit A, le tableau suivant :
8, 4, 19, 2, 7, 13, 5, 8 4 19 2 7 13 5 16
Aprs le tri croissant, A devient :
2, 4, 5, 7, 8, 13, 16, 19
67 68
10 10 3 3 3 3
3 3 10 9 9 9
25 25 25 25 10 10
9 9 9 10 25 18
2 18 18 18 18 25
70
3 3 10 9 9 9
25 25 25 25 10 10
9 9 9 10 25 18
2 18 18 18 18 25
Structure du programme /* Dclarations */ /* Saisie des donnes */ /* Affichage du tableau T */ /* Tri par slection*/ */ /* Affichage du tableau tri*/
72
18 25 18 25 18 18 9 9 9 9 18 2 2 2
10 18 10 18 10 10 10 9 9 9 2 3 9 9 9 10 2 2 9 9
18 25 18 25 18 25
10 18 25 10 18 25 10 18 25 10 18 25
73
Structure du programme / /* Dclarations */ / /* Saisie des donnes */ /* Affichage du tableau T */ / /* Tri bulles*/ bulles / /* Affichage du tableau tri*/
74
77
78
Exercice 1
Ecrire un programme C qui transfre une matrice M deux dimensions L et C (dimensions maximales : 10 lignes et 10 colonnes) dans un vecteur V une di dimension L*C i Exemple : abcd ef gh ==> (a b c d e f g h i j k l)
Exemples
int T[2][2]; int mat[6][10]; char X[100][60][80]; [ ][ ][ ];
Indice Valeur 0 12
0 1 73 0 48
1 1 59
Initialisation
int T[2][2]={{12,73},{48,59}};
i j k l
Structure du programme : /* Dclarations */ D l ti /* Saisie des donnes */ /* Affichage du tableau 2-dim */ /* Transfert des lments ligne par ligne */ /* Affichage du tableau 1-dim */
79 80
Correction
/* Dclarations */ int M[10][10]; /* tableau 2 dimensions */ int V[100]; /* tableau 1 dimension */ int L C; L, / /* dimensions */ / int I, J,k=0; /* indices courants */ /* Saisie des donnes */ printf("Nombre de lignes (max.10) : "); scanf("%d", &L ); printf( Nombre printf("Nombre de colonnes (max 10) : "); scanf("%d", &C ); (max.10) ); scanf( %d for (I=0; I<L; I++) for (J=0; J<C; J++) {printf("M[%d][%d] : ",I,J); scanf("%d", &M[I][J]);} /* Affichage du tableau 2-dim */ ff printf("\nTableau origine :\n\n"); for (I=0; I<L; I++) { for (J=0; J<C; J++) ( ) printf("\t%d", M[I][J]); printf("\n"); } / /* Transfert des lments ligne par ligne */ / for (I=0; I<L; I++) for (J=0; J<C; J++) {V[k] = M[I][J];k++;} /* Affichage du tableau 1 dim */ 1-dim printf("\nTableau resultat : "); for (I=0; I<L*C; I++) printf("%d ", V[I]);
Exercice 2
Ecrire un programme qui effectue la transposition tA d'une matrice A de dimensions L et C en une matrice de dimensions C et L
La matrice transpose sera mmorise dans une deuxime matrice B La matrice A sera transpose par permutation des lments
a b c d Exemple p e f i
Structure d programme St t du /* Dclarations */ /* S i i d d Saisie des donnes */ /* Affichage de la matrice */ /* Transposition de la matrice A */ /* Affichage du rsultat */
81
a ==> b c
e f g
i j k l
g h k l
d h
82
Correction
/* Affectation de la matrice transpose B */ for (I=0; I<L; I++) for (J=0; J<C; J++) B[J][I]=A[I][J]; /* Edition du rsultat, L et C sont inverses */ printf("\nMatrice resultat :\n\n"); for (I=0; I<C; I++) (I 0; { for (J=0; J<L; J++) printf("%d", B[I][J]); printf("\n"); } /* Transposition de la matrice A par permutation des lments [I][J] gauche de la diagonale principale avec les lments [J][I] droite de la diagonale*/ DMAX = (L>C) ? L : C; ( ) for (I=0; I<DMAX; I++) for (J=0; J<I; J++) { AIDE = A[I][J]; A[I][J] = A[J][I]; A[J][I] = AIDE; }
83 84
Dfinition et intrts
Dfinition
Un pointeur est une variable qui contient ladresse dune autre variable
l pointeur pointe sur l variable le i t i t la i bl le pointeur fait rfrence la variable pointe
p
Intrts
Allouer de la mmoire dynamique, ce qui permet la gestion de structures de ( ) taille variable (ex. tableau de taille variable) Permettre le passage par rfrence pour des paramtres des fonctions (chapitre 7) Raliser des structures de donnes rcursives (listes et arbres) ...
Initialisation I iti li ti
Syntaxe : <identificateur_pointeur> = & <identificateur_variable> Exemple : p int A=2; int *p; p A p = &A; printf( \nA :%d, printf("\nA :%d Adresse de A:%x", A p); A:%x A,p); // A : 2, Adresse de A : 22ff74
Lors de linitialisation, le pointeur reoit ladresse de la variable pointer. Cela se , p p fait par le paramtre dadressage (&) Un pointeur est toujours li un type de donnes. Il ne peut pas recevoir ladresse dune variable de type diffrent 86
85
Exemples
Exemple 1
int i=10, j=50; int *p = NULL; p=&i; j=* *p; *p = j+2;
p = NULL
j =50 | 4F i =10 | 3F 10
Oprateurs & et *
Loprateur <*> dsigne le contenu de la variable adresse/pointe L oprateur Loprateur <&> est un oprateur unair qui fournit ladresse de son oprande l adresse Exemples :
int *p = NULL; int i 3; i=3;
Adresse F33 Valeur i=3
Exemple 2
float a , *p; /*supposons que ces variables sont reprsentes en mmoire partir de ladresse 01BF*/ p = &a; printf("Entrer une valeur :"); scanf("%f",p); // on saisie la valeur 1.4 printf("\nAdresse d a = % C t i tf("\ Ad de %x Contenu d a = %f" * ) de %f",p,*p); *p += 0.4; printf("\na = %f *p = %f ", a,*p);
Adresse de a = 01BF Contenu de a= 1.400000
87
p
*p = 5; //modifier la valeur de la variable pointe par p
Adresse F33
Valeur i=3
Adresse F33
Valeur i=5
a=1.800000 *p=1.800000
88
Exercice
Trouvez les erreurs dans les suites dinstructions suivantes : a) i t * , x = 34 * = x; ) int *p 34; *p *p = x est incorrect parce que le pointeur p nest pas initialis b) double *q; int x = 17 , *p = &x; q = p; q = p est incorrect. q et p deux pointeurs sur des types diffrents c) int x, *p; &x = p; &x = p incorrect. &x nest pas une variable qui peut figurer gauche dune affectation
px
py
Exp2
y = x+1 x = x+2 x /=3 x++ x x-nombre doctets entre les 2 adresses p comparaison dadresses px et py pointent sur la mme donne
90
Pointeurs et tableaux 1D
Un tableau est une zone de mmoire rfrence par ladresse de son premier lment qui peut tre dsign par un pointeur
Le L nom T du t bl d tableau est un pointeur constant sur l premier l t i t t t le i lment d t bl t du tableau T et &T[0] contiennent ladresse du premier lment du tableau
Exercice
Ecrire un programme qui vrifie si un tableau de caractres CH est un palindrome en utilisant des pointeurs au lieu des indices numriques
Un li d U palindrome est un mot qui reste l mme qu'on l li d gauche d it ou d d it t t i t le ' le lise de h droite de droite gauche : . . Exemples : PIERRE ==> n'est pas un palindrome
Exemple p
int *p, T[10]; p = T //quivalent p = &T[0] Expression E i *(p+i) (p+i) p = &T[i] p p++ p+=n T+i *(T+i) T=p
T==&T[0]
0 9
1 8
2 10
3 6
Exp2 Dsignation D E 2ti i contenu de la case T[i] adresse de la case T[i] (&T[i]) p pointe sur le ime lment du tableau p pointe sur llment T[i+1] du tableau p pointe sur llment T[i+1+n] du tableau Adresse du ime lment du tableau T contenu de la case T[i] Erreur! T est un pointeur constant
91
/* Dclarations */
char CH[101]; /* chane donne */ char *P1,*P2; /* pointeurs d'aide */ int PAL; /* indicateur logique vrai si CH est un palindrome */
Structure du programme
/* Saisie des donnes */ / /* Contrler si CH est un palindrome */ / /* Affichage du rsultat */
92
Correction
/* Saisie des donnes */ printf("Entrez une ligne de texte (max.100 caracteres) :\n"); gets(CH); /* Placer P2 sur la dernire lettre de la chane */ for (P2=CH; *P2; P2++) ; P2--; / /* Contrler si CH est un palindrome */ / PAL=1; for (P1=CH ; PAL && P1<P2 ; P1++,P2--) if (* != * ) PAL=0; f (*P1 *P2) /* Affichage du rsultat */ if (PAL) printf("\nLa chaine \"%s\" est un palindrome.\n", CH); else printf( \nLa printf("\nLa chaine \"%s\" n'est pas un palindrome \n", CH); \ %s\ n est palindrome.\n
T et T[0] contiennent la mme adresse mais leur manipulation nest pas la mme puisquils ne reprsentent pas le mme type de pointeur
Exemple
int *p T[10][10]; p, p = T[0] //quivalent p = &T[0][0]
93
94
Exercice
p p+1
0 0 1 C-1 9 15 6 8 /* Dclarations */ int Suites[4][4]; i t S it [4][4] /* matrice d'entiers */ t i d' ti int AIDE; int *P1, *P2; 10 13 4 99 int i,j; /* pour la permutation des chiffres*/ /* pointeurs d'aide */ /* indices courants */ 12 3
Ecrire un programme qui lit 4 suites d'une longueur gale 4 et les mmorise dans une matrice Suites. Inverser l'ordre des chiffres l'intrieur des 4 suites l'aide de deux pointeurs P1 et P2 Afficher les suites inverses P2.
p+C
1
0 1 C-1
/* Structure du programme */ /* Saisie des donnes */ /* Inverser l'ordre des chiffres l'intrieur des suites */ /* Affichage des suites inverses */
96
p+i*C+j
T T=
Correction
/* Saisie des donnes */ printf("Entrez 4 suites \n"); for (i=0; i<4; i++) { printf("\nsuite %d (max.4 chiffres) : ", i); for(j=0;j<4;j++) scanf("%d",(Suites[i]+j)); } /*Affichage de la matrice*/ for (i=0; i<4; i++) { for(j=0;j<4;j++) printf("%d\t", *(Suites[i]+j)); printf("\n"); } } /* Affichage des suites inverses */ for (i=0; i<4; i++) { for (j=0;j<4;j++) printf("%d\t", *(Suites[i]+j)); printf("\n"); }
97
Tableau de pointeurs
Syntaxe = <type> *identificateur_tableau [taille]
Dclare un tableau de [taille] pointeurs de type <type> Exemple c a p[30]; ab eau char *p[30]; // tableau de 30 pointeurs de type char po eu s ype c a
Pointeur de tableaux
Syntaxe = <type> (*identificateur_pointeur) [taille]
Dclare un pointeur identificateur_pointeur sur des tableaux de [taille] lments de type <type> Exemple int (*p)[30] ; // pointeur sur des tableaux de 30 lments de type int
Pointeur de pointeurs
Syntaxe = <type> **identificateur pointeur identificateur_pointeur
Dclare un pointeur identificateur_pointeur qui pointe sur des pointeurs de type <type> E Exemple l int **p ; // pointeur sur des pointeurs de type int
98
Allocation de mmoire
Lallocation de la mmoire pour un pointeur peut se faire
En transmettant ladresse dune variable (p=&a); En allouant un espace mmoire laide de la fonction malloc qui se trouve dans la librairie <stdlib.h> : Allocation dynamique
Exemple
int *p,i; p = (int*) calloc (5, sizeof(int)); // Allocation de 20 octets initialiss 0 et affecter ladresse du dbut p;
for (i=0;i<5;i++) printf("\nEntier : %d ADRESSE: %x",*(p+i),p+i);
Exemple
char *c; c = (char*) malloc(20); // Allocation de 20 octets et affecter ladresse du dbut c;
99
100
Cas de : ptr = (int*)realloc(ptr, 20 * sizeof(int)); si realloc choue, la valeur de ptr est alors nulle, et on aura perdu la rfrence vers l'espace de taille 10 * sizeof(int) qu'on a dj allou. Ce type d'erreur s'appelle une fuite mmoire
102
Libration de mmoire
La fonction free permet de librer lespace mmoire allou dynamiquement au pointeur Syntaxe : free(<identificateur_pointeur>); pointeur>=NULL; //pour viter les erreurs ; p <identificateur_p
Exercice 1
Saisir un texte. Ranger les caractres en mmoire en utilisant un pointeur. Lire le contenu de la mmoire en utilisant le mme pointeur et y compter le nombre d espaces d'espaces et de lettres e e
/*Dclarations*/ char *adr_deb; // Adresse mmoire de rangement des caractres char c; //Caractre lu int i,imax; //Indices courants int compt_e = 0,compt_esp = 0; //Compteurs / Structure /*Structure du programme */ / /* Saisie et rangement du texte en utilisant un pointeur */ /* Lecture et affichage des adresses des caractres lus en comptant les 'e' et les ' ' */ /* Affichage des rsultats */
Exemple
char *c; c = (char*) malloc(20); . free(c); c=NULL;
103
104
Correction
char *adr_deb,c; int i,imax,compt_e = 0,compt_esp = 0; adr_deb = (char*) malloc(30);/* texte d'au plus 30 caractres */ /* Saisie et rangement du texte */ printf( \n printf("\n ADRESSE DU TEXTE: %x (ATTRIBUEE PAR LE COMPILATEUR)",adr_deb); COMPILATEUR) adr deb); printf("\n ENTRER UN TEXTE: "); for (i=0;((c=getchar())!='\n');i++) *(adr_deb + i) = c; imax = i;/* borne superieure */ /* Lecture de la mmoire pour compter les 'e' et les ' ' */ for (i=0;i<imax;i++) (i 0;i<imax;i++) { c = *(adr_deb+i); printf("\nCARACTERE: %c ADRESSE: %x",c,adr_deb+i); if ( (c=='e') compt_e++; ' ') if (c==' ') compt_esp++; } /* Affichage du rsultat */ printf("\nNOMBRE DE e: %d \nNOMBRE d'espaces: %d\n",compt_e,compt_esp); free(adr_deb);
Exercice 2
crire un programme qui remplit un tableau dynamique dentiers 2 dimensions (3,3) /*Dclarations*/ int L=3, C=3; //dimensions de la matrice int **M; //matrice dynamique int i,j; //Indices courants /*Structure d programme */ /*St t du /*Allocation de la mmoire*/ /* Saisie et rangement des lments de la matrice */ /* Affichage de la matrice lue */
105
106
Correction
int L=3, C=3,i,j; int **M; M = (i t**) ll (L * sizeof(int*)); (int**)malloc(L i f(i t*)) for (i = 0; i < L; i++) M[i] = (int*)malloc(C * sizeof(int)); //*(M+i) = (int*)malloc(C * sizeof(int)); for (i = 0; i < L; i++) for (j = 0; j < C; j++) {p {printf("\nM[%d][%d]:",i,j); ( [ ][ ] , ,j); scanf("%d",M[i]+j); // scanf("%d",&M[i][j]); } printf( \n printf("\n-----------------Affichage Matrice------------\n"); Affichage Matrice \n ); for (i = 0; i < L; i++) { for (j = 0; j < C; j++) printf( %d\t (M[i]+j)); //printf( %d\t M[i][j]); printf("%d\t",*(M[i]+j)); //printf("%d\t",M[i][j]); printf("\n"); } for f (i = 0 i < L i ) 0; L; i++) free(M[i]); free(M);
107
108
Introduction
Une fonction ou procdure ou encore sous programme est une suite d'instructions lmentaires qui reprsente une seule action. Elle est la base d l b des langages structurs t t Ralisation d'un algorithme : dcomposition en une suite de fonctions simples pouvant raliser une ou plusieurs f i l t li l i fonctions b ti beaucoup plus l compliques Une fonction est caractrise par un appel et un retour : U f ti t t i l t t
L'appel est effectu par le programme principal main() ou une autre procdure Le retour s'effectue aprs la dernire action de la fonction appele s effectue
Programme p principal p
Il est interdit de dfinir des fonctions lintrieur dune autre fonction ( (comme en Pascal) ) En principe, lordre des dfinitions de fonctions dans le texte du programme ne joue pas de rle, mais chaque fonction doit tre dclare ou dfinie j p , q avant dtre appele : L'appel d'une fonction doit tre situ aprs sa dfinition ou son prototype L'ordre, le type et le nombre des arguments doivent tre respects lors de l'appel de la fonction
111 112
Exercice
Ecrire une fonction Premier ayant en argument un entier et qui renvoie par un return un boolen : 1 si l'entier est premier 0 sinon. Tester cette fonction Ecrire une fonction NPremier ayant comme paramtre un entier N et qui renvoie le N-ime nombre premier. Tester cette fonction
Correction
int Premier(int x) { int r=1, d=2; while(r && d*d<=x) if(x%d==0) r=0; else d++; return r; } int Npremier(int N) { int nb=0, i=2; while(nb!=N) { if(Premier(i)) nb++; i++; } return i-1; } main() { int a, N; printf("Tapez a :"); scanf("%d",&a); if(Premier(a)) printf("%d est premier",x); else p printf("%d n es pas p e e , ); ( %d est premier",x); printf("\nTapez la valeur de N :"); scanf("%d",&N); printf( \n printf("\n le %d eme nombre premier est : %d", N,Npremier(N)); }
113
114
Exemple
int a, b; main() { int a = 1, b = 2; a++, b++; printf("\n1er bl a : %d\tb : %d" b) i tf("\ 1 bloc %d",a,b); { char b = 'A'; a++, b++; printf("\n2eme bloc a : %d\tb : %c",a,b); { int a = 100; a++, b++; printf( \n3eme printf("\n3eme bloc a : %d\tb : %c ,a,b); %c" a b); } } }
116
La dure de vie d'une variable est le temps pendant lequel cette variable a une d une existence en mmoire. En C 3 catgories de variables :
variables statiques (permanentes) : occupent un espace mmoire durant toute l'excution du programme (segment de donnes) Elles sont initialises zro par le compilateur et donnes). elles sont caractrises par le mot-clef static variables automatiques (temporaires) : se voient allouer un espace mmoire de faon dynamique ( d i (segment d pile). Ell t de il ) Elles ne sont pas i iti li t initialises. L Leur espace mmoire est i t libr la fin d'excution de la fonction secondaire et elles sont caractrises par le motclef auto variables dynamiques : alloues et libres explicitement par le programmeur, l'aide des fonctions malloc (calloc / realloc) et free
- En l'absence des mots cls static et auto, la variable sera prise par dfaut de type automatique - Une variable globale est par dfaut static 117
n est initialise 0 par le compilateur pp appel numero 1 appel numero 2 appel numero 3 appel numero 4 appel numero 5
118
Il est possible de dclarer une variable locale de classe statique qui reste locale une fonction mais sa valeur est conserve d'un appel au suivant oca e u e o ct o as a eu co se e d u appe su a t
120
Exercice
Dterminer le maximum d'un tableau T de N entiers de trois faons diffrentes :
la fonction MAX1(i t T b[N]) retourne l valeur maximale l f ti MAX1(int Tab[N]) t la l i l la fonction MAX2(int Tab[N]) retourne l'indice de l'lment maximal la fonction MAX3 (int Tab[N]) retourne l'adresse de l'lment maximal la fonction Echange(int Tab[N]) change le maximum avec le premier lment du tableau
Correction
#define N 10 /*Fonction qui retourne l'adresse /*Fonction qui retourne la valeur du maximum*/ maximum / maximum*/ int int* MAX3(int Tab[N]) int MAX1(int Tab[N]) { { int *max=NULL,i; int max=Tab[0],i; max Tab[0],i; max Tab;//OU max &Tab[0]; max=Tab;//OU max=&Tab[0]; for(i=0;i<N;i++) for(i=0;i<N;i++) if(Tab[i]>max) max=Tab[i]; if(Tab[i]>*max) max=&Tab[i]; ; ; return max; return max; } } /*Fonction Echange*/ /*Fonction qui retourne l'indice du void Echange(int Tab[N]) maximum*/ { int MAX2(int Tab[N]) int temp; { int imax = MAX2(Tab); int i=0,ind=0; temp=Tab[0]; for(i=1;i<N;i++) Tab[0]=Tab[imax]; if(Tab[ind]<Tab[i]) Tab[imax]=temp; ind=i; i d i } return ind; } du
Exemple dexcution
121
122
main()
int x=3; int y =5; printf("Avant :\nx=%d\ty=%d ",x,y); permutter(&x,&y); printf( \nApres printf("\nApres :\nx=%d\ty=%d ",x,y); x y);
Exercice 1
Donner la squence des affichages produits par l'excution du programme suivant : p ( , ;} int f1 ( int n ) { printf("%d\n",n == 0 ); return n;} int f2 ( int n ) { printf("%d\n",n = 0 ); return n;} void f3 ( int *n ) { *n = *n + 1; } int f4 ( int *n ) { (*n)++ ; return *n ; } () main() { int a =1, b = 2; a = f1( a ) ; b = f2( 1 ) ; ( ) printf("a = %d , b = %d\n", a , b ); f3( &a ) ; b = f4( &a ) ; printf("a = %d , b = %d\n ", a , b ); }
127
128
Exercice 1
Ecrire une fonction, nomme VerifierRelationR, qui retourne 1 si le tableau dentiers T reu en paramtre vrifie la relation (R), 0 sinon. Les paramtres de la fonction sont le tableau T et sa taille N Un tableau T vrifie la relation (R) si chaque lment de T sauf le premier est la somme dun certain nombre dlments conscutifs qui le prcdent d un d lments immdiatement, cest--dire : Soit k tel que 1 <= k <= N -1, il existe i , 0 <=i <= k -1 tel que T[k] = T[k -1] + ... + T[i +1] + T[i]
(R)
soit les diffrents tableaux qui lui sont passs en paramtre effectif ont tous la q p p mme taille, et dans ce cas la taille peut apparatre dans le type du paramtre effectif : #define N 10 void initialisation (int tab[N]){}
0 Ex : si T = 2
1 2
2 4
3 6
4 10
5 24
6 34
7 34
8 68
alors T vrifier la relation (R). En effet : T[1]=T[0] ; T[2]=T[1]+T[0] ; T[3]=T[2]+T[1] ; T[4]=T[3]+T[2] ; T[5]= T[4]+T[3]+T[2]+T[1]+T[0] ; T[6]=T[5]+T[4] ; T[7]=T[6] ; T[8]=T[7]+T[6] ;
129 130
Correction
int VerifierRelationR (int T[ ] , int N) { int i,k,som; for(k=1;k<N;k++) { som=0; for(i=k-1;i>=0;i--) { som+=T[i]; if ( (som==T[k]) b T[k]) break; k if(som>T[k])return 0; if(i==0 && som<T[k]) return 0; ( [ ]) ; } } return 1 1; }
131
On donne : //retourne 1 si x est premier et 0 sinon int Premier(int x) { int r=1, d=2; while(r && d*d<=x) if(x%d==0) r=0; else d++; return r; }
132
Correction (1/3)
int Premier(int x) { int r=1, d=2; while(r && d d<=x) d*d<=x) if(x%d==0) r=0; else d++; return r; } { int i,k=0; for(i=2;i<=N;i++) if((N%i)==0 && Premier(i)) { facteur[k]=i; k++; N=N/i; i--; } *taille=k; } } } { int T[100], L, N; printf( NOMBRE printf("NOMBRE A DECMPOSER :"); : ); scanf("%d", &N); decompose(T,N,&L); Affiche(T, L) Affi h (T L); void decompose(int facteur[ ], int N, int *taille) main() void Affiche(int T[ ], int L) { int i; printf("\n TABLEAU DE DECOMPOSITION \n "); for (i=0; i<L; i++) printf ( % \ f ("%d\t",T[i]); )
Correction (2/3)
void decompose_ptr (int *facteur, int N, int *taille) { int i k=0; i,k=0; for(i=2;i<=N;i++) if((N%i)==0 && Premier(i)) { *(facteur+k)=i; k++; N=N/i; i--; } *taille=k; } } main() { int L N; L, int *P; printf("NOMBRE A DECMPOSER :"); scanf("%d", & ) f( % &N); P=(int*) malloc (20*sizeof(int)); decompose_ptr(P,N,&L); Affiche(P, L); free(P);
133
134
main() { int L N; L, int *P; printf("NOMBRE A DECMPOSER :"); scanf("%d", & ) f( % &N); decompose_ptr(&P,N,&L); Affiche(P, L); }
Exercice
Ecrire une fonction, nomme EstTriangulaireSuperieure, qui retourne 1 si la matrice carre dentiers A (de 30 colonnes au maximum) reue en paramtre est triangulaire suprieure 0 sinon Les paramtres de la fonction sont la matrice suprieure, sinon. carre A, le nombre des lignes et des colonnes L Matrices triangulaires suprieures sont des matrices carres dont les valeurs sous la diagonale principale sont nulles Pour tout i>j aijj=0
138
Correction
int EstTriangulaireSuperieure(int A[ ][30] , int L) void Affiche(int A[ ][30], int L) { int i , j ; for( i = 1 ; i < L ; i++ ) for(j=0 ; j<i ; j++) if( A[i][j] != 0 ) return 0 ; return 1 ; } void Saisie(int A[ ][30], int L) { int i , j ; for( i = 0 ; i < L ; i++ ) for(j=0 ; j<L ; j++) { printf ( \ % % f ("\nA[%d][%d]:", i, j); ) scanf("%d", &A[i][j]); } } }
139
Le langage C offre la possibilit de passer une fonction comme paramtre d'une autre fonction. On utilise un mcanisme de pointeur Un pointeur sur une fonction ayant pour prototype
Type fct (type-1,,type-n);
est de type
Type (*)(type-1,,type-n); yp ( )( yp , , yp );
140