École préparatoire aux sciences et techniques, Annaba Année universitaire 2013/2014 Module : Informatique 2 Série de TD n o 5 : Fonctions Rappel sur les fonctions 1. Une fonction est un bloc d instructions qui accepte des valeurs en entrée appelées paramètres et fournit une valeur en sortie en utilisant le mot clé return. 2. Donner la syntaxe d une déclaration d une fonction. type nom_de_la_fonction(type param1, type param2,...) { corps de la fonction 3. Comment appele-t-on une instruction dans le programme qui utilise une fonction? Un appel de fonction 4. Donner la syntaxe d un appel de fonction. nom_de_la_fonction(valeur1, valeur2,...); 5. Quel type de retour est utilisé quand une fonction ne retourne aucune valeur? void 6. Quels sont les deux modes de transmission de paramètres à une fonction? Par valeur et par variable (ou référénce). 7. Quel symbole doit précéder le nom d un paramètre transmis par variable (ou référénce)? & 8. Quand un paramètre est transmis par variable (a) La fonction travaille avec une copie de la variable transmise. (b) La fonction travaille avec la variable transmise elle-même. 9. Une valeur par défaut d un paramètre est utilisée par la fonction quand le programme appelant ne fournit pas une valeur pour ce paramètre. 1
10. Les paramètres par défaut doivent figurer en dernier dans la déclaration d une fonction. 11. Lors d une surcharge de fonction, les paramètres de des surcharges doivent différer en nombre et/ou en type. 12. Comment appelle-t-on une fonction qui fait appel à elle-même? Une fonction récursive. Exercice 1 Ecrire une fonction distance ayant comme paramètres 4 doubles xa,ya et xb,yb qui réprésentent les coordonnées de deux points A et B et qui renvoie la distance AB. Tester cette fonction dans un programme principal. #include<iostream.h> #include<math.h> double distance(int xa, int xb, int ya, int yb) { return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb)); int main() { cout << distance(2,2,4,4); Exercice 2 Ecrire une fonction swap ayant en paramètres 2 entiers a et b et qui échange les contenus de a et de b. Tester cette fonction dans un programme principal. #include<iostream.h> void swap(int & a, int & b) { int c = a; a = b; b = c; int main() { int a = 5; int b = 3; swap(a,b); cout << a; cout << b; 2
Exercice 3 1. Ecrire une fonction AND qui permet de calculer le ET (.) logique de deux booléens. 2. Ecrire une fonction OR qui permet de calculer le OU (+) logique de deux booléens. 3. Ecrire une fonction NOT qui permet de calculer le NON logique d un booléen. 4. En utilisant les fonctions AND, OR et NOT, écrire une fonction XOR ( )qui permet de calculer le XOR de deux booléens. (Rappel : A B = A. B + Ā.B) //1 bool AND(bool a, bool b) { return a && b; //2 bool OR(bool a, bool b) { return a b; //3 bool NOT(bool a) { return!a; //4 bool XOR(bool a, bool b) { return OR(AND(a,NOT(b)),AND(not(a),b)); Exercice 4 Le factoriel d un nombre n, noté n!, est le produit des nombres entiers strictement positifs inférieurs ou égaux à n. Le factoriel peut être formellement défini de deux manières : n n! = i = 1 2 3... (n 1) n (1) i=1 { 1 si n {0, 1 n! = n (n 1)! sinon 1. En utilisant la formule (1), écrire une fonction itérative qui calcule le factoriel d un nombre. int factoriel(int n) { int s = 1; for (int i=2;i<=n;i++) s*=i; return s; (2) 3
2. En utilisant la formule (2), écrire une fonction récursive qui calcule le factoriel d un nombre. int factorielr(int n) { if (n==0 n==1) return 1; return n * factorielr(n-1); 3. Quelle version est plus efficace en terme de temps? La version itérative 4. Quelle version est plus efficace en terme d espace mémoire? Exercice 5 La version itérative 1. Ecrire une fonction existe qui teste si une valeur existe dans un tableau. La fonction retourne true si elle trouve la valeur et false sinon. bool existe(int tab[], int taille, int val) { int i = 0; while (i<taille && tab[i]!=val) i++; if (i<taille) return true; return false; 2. Ecrire une version récursive de la fonction existe. bool existe(int tab[], int debut, int taille, int val) { if (debut==taille-1) if (tab[debut]==val) return true; return false; return existe(tab,debut+1,taille,val); 3. Ecrire une fonction somme qui calcule et retourne la somme des éléments d un tableau. 4
int somme(int tab[], int taille) { int s = 0; for (int i=0;i<taille;i++) s+=t[i]; return s; 4. Ecrire une version récursive de la fonction somme int somme(int tab[], int debut, int taille) { if (debut==taille-1) return t[debut]; return t[debut]+somme(tab,debut+1,taille); 5. Ecrire une fonction tri qui trie dans l ordre croissant un tableau. void tri(int t[], int taille) { for (int i=0;i<taille-1) { int min = t[i]; int imin = i; for (int j=i+1;j<taille;j++) if (t[j]<min) { min = t[j]; imin = j; int c = t[i]; t[imin] = t[i]; t[i] = c; 6. Ecrire une version récursive de la fonction tri. void tri(int t[], int debut, int taille) { if (debut!=taille-1) { int min = t[debut]; int imin = debut; for (int i=debut+1;i<taille;i++) if (t[i]<min) { min = t[i]; imin = i; int c = t[debut]; t[debut] = t[imin]; t[imin] = c; 5
tri(t,debut+1,taille); Exercice 6 Soit les deux surcharge d une fonction appelée somme : int somme(int i, int j) { cout << "somme int"; return i + j; double somme(double i, double j) { cout << "somme double"; return i + j; Que se passe-t-il lorsqu on fait chacun des appels suivants dans un programme : 1. somme(2,4) affiche "somme int" 2. somme(2.0,4.0) affiche "somme double" 3. somme(2.0,4) Erreur, le compilateur ne trouve pas une surcharge qui respecte le type des paramètres Exercice 7 Ecrire une fonction minmaxmoy qui accepte en entrée un tableau d entiers ainsi que sa taille et qui renvoie le maximum, le minimum et la moyenne des valeurs du tableau. La fonction doit être de type void. Utiliser le type de transmission approprié pour chaque paramètre. void minmaxmoy(int t[], int taille, int & min, int & max, int & moy) { double s = 0; min = t[0]; max = t[0]; for (int i = 0;i<taille;i++) { if (t[i]<min) min = t[i]; if (t[i]>max) max = t[i]; 6
s+=t[i]; s/=taille; Problème 1 : Chiffrement par décalage En cryptographie, le cryptage ou chiffrement par décalage, aussi connu comme le chiffre de César, est une méthode de chiffrement très simple utilisée par Jules César dans ses correspondances secrètes (cf. wikipedia). Le texte crypté s obtient en remplaçant chaque lettre du texte original par une lettre à distance fixe. Pour les dérnieres lettres de l alphabet, on reprend au début. Par exemple si la distance choisie est de 3, on a : texte original : ECOLE PREPARATOIRE AUX SCIENCES ET TECHNIQUES texte crypté : HFROH SUHSDUDWRLUH DXA VFLHQFHV HW WHFKQLTXHV 1. Ecrire une fonction crypter qui permet de crypter un message en utilisant le chiffrement par décalage. La fonction accepte en entrée un tableau de caractères ainsi que la distance choisie. void crypter(char t[], int taille, int distance) { for (int i=0;i<taille;i++) if (t[i]!= ) t[i] = A + (t[i]- A + distance) % 26; 2. Ecrire une fonction decrypter qui permet de décrypter un message. La fonction accepte en entrée un tableau de caractères ainsi que le distance. void decrypter(char t[], int taille, int distance) { for (int i=0;i<taille;i++) if (t[i]!= ) t[i] = A + (26 + t[i] - A - distance ) % 26; Problème 2 : Carré rebondissant Un objet de forme carré se déplace sur une grille de 10x10 cases. L objet se déplace d une case à chaque mouvement vers une direction qui peut être : nord-est, nord-ouest, sud-est ou sud-ouest. L objet rebondit quand il touche l une des paroies de la grille. En supposant que les constantes ne, no, se et so sont déclarée et de type int, écrire une fonction deplacer(int & x, int & y, int & direction) qui calcule les nouvelles coordonnées de l objet ainsi que sa nouvelle direction en cas de rebondissement. 7
void deplacer(int & x, int & y, int & direction) { switch (direction) { case ne: if (x==9 && y==0) { x--; y++; direction = so; if (x==9) { x--; y--; direction = no; if (y==0) { x++; y++; direction = se; { x++; y--; break; case no: if (x==0 && y==0) { x++; y++; 8
direction = se; if (x==0) { x--; y++; direction = so; if (y==0) { x++; y--; direction = ne; { x--; y--; break; case so: //calculer de la même façon x,y et direction case se: //calculer de la même façon x,y et direction 9