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 cerr << "operateur+=(const Tableau &)" << '\n'; 70 if (sz != t.sz) { 71 cerr << "Ne peut pas ajouter deux Tableaux de tailles differentes" << '\n'; 72 exit(1); 73 } else { 74 for (size_t i=0; i < sz; i++) { 75 A[i] += t[i]; 76 }; 77 }; 78 return *this; 79 }; 80 81 // Le parametre est un entier 82 Tableau & Tableau::operator+=(float x) { 83 cerr << "operateur+=(float)" << '\n'; 84 for (size_t i=0; i < sz; i++) { 85 A[i] += x; 86 }; 87 return *this; 88 }; 89 90 // copie l'entier src dans la zone memoire pointee par dest 91 void Tableau::__copie (float src, float dest[], size_t s) 92 { 93 for ( size_t i=0; i<s; i++) { 94 dest[i] = src; 95 } 96 } 97 void Tableau::__copie (float src[], float dest[], size_t s) { 98 for (size_t i=0; i<s; i++) { 99 dest[i] = src[i]; 100 }; 101 } 102 103 // Deux autres manières d'écrire le même code: difficilement lisible, mais on voit ça souvent 104 /* 105 void Tableau::copie (float src, float *dest, size_t s) { 106 for (size_t i=0; i<s; i++) { 107 *(dest++) = src; 108 }; 109 }; 110 void Tableau::copie (float *src, float *dest, size_t s) { 111 for (size_t i=0; i<s; i++) { 112 *(dest++) = *(src++); 113 }; 114 } 115 */ 116 117 // Tableau operator+(Tableau t1, Tableau t2) { 118 Tableau operator+(const Tableau& t1, const Tableau& t2) { 119 cerr << "operateur+" << '\n'; 120 Tableau s(t1.size()); 121 if (t1.size() != t2.size()) { 122 cerr << "Ne peut pas ajouter deux Tableaux de tailles differentes" << '\n'; 123 exit(1); 124 } else { 125 s = t1; 126 s += t2; 127 }; 128 return s; 129 }; 130 131 ostream & operator<<(ostream& os, const Tableau& t) { 132 if (t.size() == 0 ) { 133 os << "{}"; 134 return os; 135 } 136 137 size_t i_dernier = t.size() - 1; 138 os << '{'; 139 for (int i=0; i<i_dernier; ++i) { 140 os << t[i] << ','; 141 } 142 os << t[i_dernier] << '}'; 143 return os; 144 } 145 146