LIF 1 TP 3 : Passage de paramètres / Tableaux 1D

Dimension: px
Commencer à balayer dès la page:

Download "LIF 1 TP 3 : Passage de paramètres / Tableaux 1D"

Transcription

1 LIF 1 TP 3 : Passage de paramètres / Tableaux 1D Objectifs : Traduction d algorithmes en langage C Mode de passage des paramètres : données, données/résultats (cas particulier des tableaux). Utilisation des tableaux : déclaration, initialisation, remplissage, calcul à partir de tableaux, Le sujet est disponible sur le site du cours : rubrique Supports de TP. 1. Kezako (Compréhension : fonction/procédure, paramètres et appels): a) Que fait le programme ci-dessous? Réfléchissez et écrivez le texte que vous pensez voir apparaître à l'exécution de ce programme : <<endl; #include <stdlib.h> void proc_mult(int a, int b, int& ab) cout << "execution de la procedure proc_mult" << endl; ab = a*b; int fonc_mult(int a, int b) cout << "execution de la fonction fonc_mult" << endl; return a*b; void kezako(int x, int y, int r1, int& r2) proc_mult( x, y, r1); r2 = fonc_mult(x,y); cout << "A la fin de kezako r1=" << r1 << " r2=" << r2 <<endl; int main(void) int a, y, res1, res2; a = 5; y = 4; res1 = 0; res2 = 1; cout << "Dans main avant kezako res1=" << res1 << " res2=" << res2 kezako( a, y, res1, res2); cout << "Dans main apres kezako res1=" << res1 << " res2="<< res2 << endl; return EXIT_SUCCESS; Faites un copier/coller du programme Kezako afin de vérifier si votre idée est correcte. Sinon demandez une explication à votre encadrant de TP.

2 #include <stdlib.h> void proc_mult(int a, int b, int& ab) 5 cout << "execution de la procedure proc_mult" << endl; 6 ab = a*b; int fonc_mult(int a, int b) 8 cout << "execution de la fonction fonc_mult" << endl; 9 return a*b; void kezako(int x, int y, int r1, int& r2) 4 proc_mult( x, y, r1); 7 9 r2 = fonc_mult(x,y); 10 cout << "A la fin de kezako r1=" << r1 << " r2=" << r2 <<endl; 1 int main(void) int a, y, res1, res2; a = 5; y = 4; res1 = 0; res2 = 1; 2 cout << "Dans main avant kezako res1=" << res1 << " res2=" << res2 <<endl; 3 kezako( a, y, res1, res2); 11 cout << "Dans main apres kezako res1=" << res1 << " res2="<< res2 << endl; 12 return EXIT_SUCCESS; Exécution du programme : 1 Le programme commence toujours par la fonction main. Les variables sont crées et prennent leur valeur initiale. a=5, y=4, res1=0, res2=1 2 Le programme affiche la première ligne : Dans main avant kezako res1=0 res2=1 3 Appel à la fonction kezako en passant a pour x(x=5),y pour y(y=4),res1 pour r1(r1=0) et res2 pour r2(r2=res2=1). Le passage par référence se fait entre res2 et r2. 4 Appel à la fonction proc_mult en passant x pour a(a=5), y pour b(b=4),r1 pour ab (ab=r1=0). Le passage par référence se fait entre r1 et ab. 5 Dans proc_mult, une ligne est affichée : execution de la procedure proc_mult 6 Dans proc_mult, ab prend pour valeur a*b (5*4=20), ab=20. A la fin de proc_mult, ab=20 donc r1=20. 7 Dans kezako, appel à la fonction fonc_mult en passant x pour a (a=5) et y pour b(b=4) 8 Dans fonc_mult, une ligne est affichée : execution de la fonction fonc_mult 9 fonc_mult renvoie a*b=5*4=20. Dans kezako, r2 prend pour valeur Dans kezako, une ligne est affiché : A la fin de kezako r1= 20 r2= 20 A la fin de kezako, r2=20, donc res2 = Dans main, la dernière ligne est affichée : Dans main apres kezako res1=0 res2=20 res1 reste inchangé mais res2 a comme valeur Fin de programme.

3 2. Reprise des TD : passage de paramètres Programmez les exercices suivants vus en TD (ou CM) : a) Permutation circulaire void permutationcirculaire(int &a, int &b, int &c) int tampon; tampon=c; c=b; b=a; a=tampon; int main (void) int v1,v2,v3; cout<<"donnez la premiere valeur"; cin>>v1; cout<<"donnez la deuxieme valeur"; cin>>v2; cout<<"donnez la troisieme valeur"; cin>>v3; permutationcirculaire(v1,v2,v3); cout<<"apres permutation : nouvelles valeurs"<<v1<<" "<<v2<<" "<<v3; b) Division Euclidienne #include<iostream.h> void divisioneuclidienne(int a, int b, int &q, int &r) q=0; r=a; while(r>=b) q=q+1; r=r-b; int main() int a, b, q, r; a=30; b=4; q=0; r=0; divisioneuclidienne(a, b, q, r); cout << "Quotient: " << q << " et reste: " << r <<endl;

4 c) Nombre de combinaisons (fonction ET procédure) int factorielle (int n) int fact=1; for(int i=2 ; i<=n ; i++) fact*=i; return fact; int combinaisonf(int n, int p) return factorielle(n)/(factorielle(p)*factorielle(n-p)); void combinaisonp(int n, int p, int &combp) combp=factorielle(n)/(factorielle(p)*factorielle(n-p)); int main (void) int n,p,cp; cout<<"donnez la valeur de n"; cin>>n; cout<<"donnez la valeur de p"; cin>>p; cout<<factorielle(n); cout<<combinaisonf(n,p); combinaisonp(n,p,cp); cout<<cp; d) Résolution d une équation du second degré (dans CM 2) #include <math.h> int resolution (int c1,int c2, int c3, double &sol1, double &sol2) int delta; delta=c2*c2-4*c1*c3; if (delta<0) return -1; else sol1=-c2-sqrt(delta)/(2*c1); sol2=-c2+sqrt(delta)/(2*c1);

5 int main (void) int a,b,c,res; double r1,r2; cout<<"donnez la valeur de a"; cin>>a; cout<<"donnez la valeur de b"; cin>>b; cout<<"donnez la valeur de c"; cin>>c; res=resolution(a,b,c,r1,r2); if (res==0) cout<<"les racines reelles sont : "; cout<<r1<<" "<<r2; else cout<<"pas de racines réelles!!"; Écrivez à chaque fois le programme principal permettant de tester vos sous-programmes. 3. Entre passage de paramètres et tableaux A partir de la fonction écrite en 2.c) écrivez un sous programme permettant de remplir un tableau contenant la nième ligne du triangle de Pascal. void tabcombin(int tab_pascal[10],int n) int i; for(i=0;i<=n;i++) tab_pascal[i]=combinaisonf(n,i); void affiche(int tab_pascal[10],int n) int i; for(i=0;i<=n;i++) cout<<tab_pascal[i]<<" "; int main (void) int n,p,cp; int tp[10]; cout<<"donnez la valeur de n (<10)"; cin>>n;

6 tabcombin(tp,n); affiche(tp,n); 4. Les tableaux à une dimension a) Écrivez une procédure tabremplir qui remplit un tableau de taille TAILLE en demandant à l'utilisateur les valeurs. On définira TAILLE comme une constante au début du programme : // En ALGO Constante : TAILLE : Entier = 5 Procédure tabremplir(t : donnée-résultat Tab[TAILLE] d'entier) // En C const int TAILLE=5; void tabremplir(... b) Écrivez une procédure tabaff qui affiche sur la sortie standard le contenu d'un tableau d'entiers : Proc tabaff(t : donnée tab[taille]) // En ALGO c) En C, un tableau ne peut avoir une taille variable : sa taille doit être une constante. Pour pouvoir gérer un tableau de taille quelconque une manière de faire est de définir une grande valeur pour TAILLE et d'utiliser une valeur taillet pour indiquer la taille réellement utilisée du tableau : // En ALGO Constante : TAILLE : Entier = 100 Proc tabaff(t : donnée Tab[TAILLE] d'entier ; taillet :donnée Entier) // En C const int TAILLE=100; void tabaff(int T[TAILLE], int taillet)... Modifiez les procédures des questions a) et b) pour prendre en compte cette amélioration. d) Écrivez une fonction tabsomme qui renvoie la somme de tous les entiers contenus dans un tableau T Fonct tabsomme(t : donnée Tab[TAILLE] d'entier ; taillet : donnée Entier) : Entier e) Écrivez une fonction tabrechposmin qui recherche le plus petit entier d'un tableau T entre la case debut et la case fin. Cette fonction renvoie directement la position de ce minimum et renvoie par l'intermédiaire d'un paramètre donnée-résultat la valeur du minimum. // Renvoie la position du minimum

7 Fonct tabrechposmin( T : donnée tab[taille] d'entier; debut, fin : donnée Entier; min : donnée-résultat Entier) : Entier f) Écrivez une procédure tabpermute qui permute deux valeurs d'indices a et b d'un tableau T Proc tabpermute(t : donnée-résultat tab[taille] d'entier; a,b : Entier) g) En utilisant les questions e) et f), écrivez une procédure TriMin qui trie les entiers contenus dans un tableau T. Indication : rechercher le minimum du tableau entre les cases 0 et taillet-1, permuter ce minimum avec la case 0 du tableau puis recommencer avec le sous-tableau allant de la case 1 à la case taillet-1... ainsi de suite jusqu'à ce que la zone de recherche du minimum soit de taille 1. Amélioration : ajoutez un paramètre à cette procédure pour pouvoir choisir entre un tri par ordre croissant et un tri par ordre décroissant, par exemple avec un caractère : 'c' pour croissant et 'd' pour décroissant. h) Écrivez la fonction principale sous forme de menu proposant à l utilisateur de tester chacun des sous-programmes écrits précédemment. // tableau1d.cpp // La taille maximale d'un tableau const int TAILLE=100; // Ex.4c // Demander a l'utilisateur de remplir un tableau ayant taillet elements void tabremplir(int T[TAILLE], int taillet) int i; for (i=0; i<taillet; i++) cout << "tab["<<i<<"] = "; cin >> T[i]; // Ex.4c // Afficher tous les elements d'un tableau ayant taillet elements void tabaff(int T[TAILLE], int taillet) int i; for (i=0; i<taillet; i++) cout << "Tableau ["<<i<<"] = " << T[i] << endl; // Ex.4d // Calculer la somme des taillet elements d'un tableau int tabsomme(int T[TAILLE], int taillet) int somme=0, i; for (i=0; i<taillet; i++) somme= somme+t[i];

8 return somme; // Ex.4e // Rechercher la position de la valeur minimale dans un tableau // a partir de la position debut jusqu'a la position fin // La (premiere) valeur minimale trouvée est stockée dans le parametre min int tabrechposmin(int T[TAILLE], int debut, int fin, int& min) int pos, i; pos = debut; min = T[debut]; for (i=debut; i<=fin; i++) if (T[i]<min) pos = i; min = T[i]; return pos; // Ex.4f // Permuter deux éléments à la position a et b dans le meme tableau void tabpermute(int T[TAILLE], int a, int b) int c; c=t[a]; T[a]=T[b]; T[b]=c; // Ex.4g // Trier un tableau ayant taillet elements: Méthode : recherche des minima void TriMin(int T[TAILLE], int taillet) int i, posmin; int min; for (i=0; i<taillet-1; i++) posmin = tabrechposmin(t,i,taillet-1,min); if ( posmin!=i ) tabpermute(t,i,posmin); // Ex. questions subsidiaires // Faire la somme des elements des 2 tableaux de taille taillet // et garder le resultat dans le 2e tableau void tabsommet2(int t1[taille], int t2[taille], int taillet) int i; for (i=0; i<taillet; i++) t2[i]=t1[i]+t2[i]; // Ex. questions subsidiaires // Fusionner les 2 tableaux triés // Le tableau résultat (tr) est trié aussi, tt = la taille du tableau tr

9 void tabfusion(int t1[taille],int taillet1, int t2[taille],int taillet2, int tr[taille], int &tt) int i, i1, i2; tt=taillet1+taillet2; // la longueur du tableau résultat // Laisser tomber les elements qui depassent la longuer maximale du tableau if (tt>taille) tt=taille; i1=0; i2=0; // le début des deux indices for (i=0;i<tt;i++) if (i1<taillet1 && i2<taillet2) // chosir un element de T1 ou de T2 (le plus petit) if (t1[i1]<t2[i2]) tr[i]=t1[i1]; i1=i1+1; else tr[i]=t2[i2]; i2=i2+1; else if (i1>=taillet1) // il ne reste que T2 à traiter tr[i]=t2[i2]; i2=i2+1; else if (i2>=taillet2 ) // il ne reste que T1 à traiter tr[i]=t1[i1]; i1=i1+1; int menu(void) int ch; cout<<"vous avez les choix suivants"<<endl; cout<<"0 : QUITTER "<<endl; cout<<"1 : Remplir le tableau"<<endl; cout<<"2 : Afficher le contenu du tableau"<<endl; cout<<"3 : Somme des éléments du tableau"<<endl; cout<<"4 : Rechercher la position du minimum dans le tableau"<<endl; cout<<"5 : Permuter deux éléments du tableau"<<endl; cout<<"6 : Trier le tableau"<<endl; cout<<"7 : Concatene deux tableaux"<<endl; cout<<"8 : Fusion de deux tableaux"<<endl; do cout<<"quel EST VOTRE CHOIX?"; cin>>ch; while ((ch<0) (ch>8)); return ch; int main(void) int T[TAILLE], taillet, somme; int posmin,valmin, a,b; int choix;

10 cout << "Entrez la taille du tableau = "; cin >> taillet; if (taillet<1 taillet>taille) cout <<"Erreur! La taille autorisee est compris entre 1 et " << TAILLE <<endl ; return -1; // Ex.3c do choix=menu(); switch (choix) case 0: cout<<"a bientot"; case 1: cout << "Remplir le tableau" << endl ; tabremplir(t,taillet); case 2: cout << "Afficher le tableau" << endl ; tabaff(t,taillet); case 3: // Ex.4d somme = tabsomme(t,taillet); cout << endl <<"La somme du tableau = " << somme << endl ; case 4:// Ex4 posmin = tabrechposmin(t,0,taillet-1,valmin); cout << endl <<"La valeur minimale = " << valmin ; cout << " se trouve a la position " << posmin << endl ; case 5:// Ex.4f a=0; b=posmin; tabpermute(t,a,b); cout << "Apres la permutation de T["<< a << "] et T["<< b <<"]" << endl; tabaff(t,taillet); case 6: // Ex.4g TriMin(T,tailleT); cout << "Apres le tri " << endl; tabaff(t,taillet); case 7:// Ex. 4h int T2[TAILLE]; cout << "Remplir le 2eme tableau" << endl ; tabremplir(t2,taillet); cout << "Afficher le 2eme tableau" << endl ; tabaff(t2,taillet); tabsommet2(t,t2,taillet); cout << "La somme des deux tableaux" << endl ; tabaff(t2,taillet); case 8: // Ex.4i cout << endl << "Le 1er tableau est trie" << endl; tabaff(t,taillet); cout << "Le 2eme tableau est trie" << endl ; TriMin(T2,tailleT); tabaff(t2,taillet);

11 int fusiont[taille]; int taillefinale; tabfusion(t,taillet,t2,taillet,fusiont, taillefinale); cout << "La fusion des tableaux tries" << endl ; tabaff(fusiont,taillefinale); default : cout<<"choix erronné"; while (choix!=0); 5. Questions subsidiaires a- écrire un programme permettant de trier un tableau de 15 éléments en utilisant le principe du tri à bulles. Principe du tri à bulles : - fonctionne par comparaisons successives de tous les éléments adjacents d un tableau - on échange les deux éléments comparés si le premier est supérieur au second - on recommence l opération tant que tous les éléments ne sont pas triés Exemple : b- transformez votre programme de manière à compter le nombre d affectations effectuées pour trier ce tableau de 15 éléments. Essayez d augmenter progressivement le nombre d éléments dans le tableau à trier et concluez sur l efficacité de cet algorithme de tri. c- Reprenez la question 4g) et ajoutez un paramètre à cette procédure pour pouvoir choisir entre un tri par ordre croissant et un tri par ordre décroissant, par exemple avec un caractère : 'c' pour croissant et 'd' pour décroissant. d- Écrivez une procédure qui manipule deux tableaux t1 et t2 (de même taille) et qui modifie t2 en ajoutant à chaque élément de t2 la valeur de l'élément correspondant dans t1. Par exemple, si t1 = [ ] et t2 = [ ], alors après l'appel de la procédure, t1 sera inchangé et on aura t2 = [ ] e- Écrivez une procédure qui effectue la fusion de deux tableaux triés de tailles quelconques (toujours à l'aide du paramètre taillet) Par exemple : Fusion de t1=[ ] et t2=[ ] donnera tr=[ ] Que fait votre programme si la longueur de t1+t2 est plus grande que TAILLE?