1 #include <cstdlib> 2 #include "tableau.hpp" 3 4 // Le constructeur principal - on passe la dimension du tableau en parametre 5 Tableau::Tableau(size_t n): sz(n) { 6 cerr << "constructeur sz = " << n << '\n'; 7 A = (float *) malloc(sz*sizeof(float)); 8 __copie(0.0,A,sz); 9 }; 10 11 // Le constructeur de copie - on fait l'alloc de memoire puis on copie 12 Tableau::Tableau (const Tableau & t): sz(t.sz) { 13 cerr << "constructeur de copie" << '\n'; 14 A = (float *) malloc(sz*sizeof(float)); 15 __copie(t.A,A,sz); 16 }; 17 18 // L'operateur = PAS D'ALLOCATION DE MEMOIRE, c'est deja fait !!! 19 Tableau & Tableau::operator=(const Tableau &t) { 20 cerr << "operateur =" << '\n'; 21 if (this==&t) // Pour gerer les cas A=A 22 return *this; 23 24 if (sz != t.sz) { 25 cerr << "Ne peut pas egaliser deux tableaux de tailles differentes" << '\n'; 26 exit(1); 27 }; 28 __copie(t.A,A,sz); 29 return *this; 30 }; 31 32 // Le destructeur: rendre la memoire au systeme 33 Tableau::~Tableau() { 34 cerr << "destructeur (sz = " << sz << ")\n"; 35 free(A); 36 }; 37 38 // renvoie un element du tableau sans deborder 39 // pas la peine de tester i < 0, size_t est un type unsigned 40 // (decommentez ce qui suit vous verrez si cela compile) 41 float & Tableau::operator[](size_t i) { 42 //if (i<0) { 43 // cerr << "ATTENTION Debordement de tableau - je renvoie tableau[0]\n"; 44 // return *A; 45 //} else 46 if (i>=sz) { 47 cerr << "ATTENTION Debordement de Tableau - je renvoie Tableau[sz-1]\n"; 48 return A[sz-1]; 49 // return *(A+sz-1); // Une autre manière d'écrire la même chose 50 } else { 51 return A[i]; 52 //return *(A+i); 53 }; 54 }; 55 56 // meme chose - version const 57 float Tableau::operator[](size_t i) const { 58 if (i>=sz) { 59 cerr << "ATTENTION Debordement de Tableau - je renvoie Tableau[sz-1]\n"; 60 return A[sz-1]; 61 } else { 62 return A[i]; 63 }; 64 }; 65 66 // operateurs += 67 // Le parametre est un autre Tableau 68 Tableau & Tableau::operator+=(const Tableau & t) { 69 if (sz != t.sz) { 70 cerr << "Ne peut pas ajouter deux Tableaux de tailles differentes" << '\n'; 71 exit(1); 72 } else { 73 for (size_t i=0; i < sz; i++) { 74 A[i] += t[i]; 75 }; 76 }; 77 return *this; 78 }; 79 80 // Le parametre est un entier 81 Tableau & Tableau::operator+=(float x) { 82 for (size_t i=0; i < sz; i++) { 83 A[i] += x; 84 }; 85 return *this; 86 }; 87 88 // imprime le Tableau sur la sortie standard 89 void Tableau::print () const { 90 for (size_t i=0; i < sz; i++) { 91 cout << A[i] << " "; 92 }; 93 cout << '\n'; 94 } 95 96 // copie l'entier src dans la zone memoire pointee par dest 97 void Tableau::__copie (float src, float dest[], size_t s) 98 { 99 for ( size_t i=0; i<s; i++) { 100 dest[i] = src; 101 } 102 } 103 void Tableau::__copie (float src[], float dest[], size_t s) { 104 for (size_t i=0; i<s; i++) { 105 dest[i] = src[i]; 106 }; 107 } 108 109 // Deux autres manières d'écrire le même code: difficilement lisible, mais on voit ça souvent 110 /* 111 void Tableau::copie (float src, float *dest, size_t s) { 112 for (size_t i=0; i<s; i++) { 113 *(dest++) = src; 114 }; 115 }; 116 void Tableau::copie (float *src, float *dest, size_t s) { 117 for (size_t i=0; i<s; i++) { 118 *(dest++) = *(src++); 119 }; 120 } 121 */ 122 123 // La famille de fonctions transform: on leur passe un objet-fonction 124 // On est obligé de définir autant de fonctions transform qu'il y a de transformations (d'objets-fonctions) définies 125 void Tableau::transform(const homo& f ) { 126 for (int i=0; i< sz; i++) 127 A[i]=f(A[i]); 128 }; 129 void Tableau::transform(const ecret& f ) { 130 for (int i=0; i< sz; i++) 131 A[i]=f(A[i]); 132 }; 133 134 Tableau operator+(const Tableau& t1, const Tableau& t2) { 135 Tableau s(t1.size()); 136 if (t1.size() != t2.size()) { 137 cerr << "Ne peut pas ajouter deux Tableaux de tailles differentes" << '\n'; 138 exit(1); 139 } else { 140 s = t1; 141 s += t2; 142 }; 143 return s; 144 }; 145