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