diff --git a/TP1/CPP/Makefile b/TP1/CPP/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8d18471febbaa741a65975278594e89e7c1175db
--- /dev/null
+++ b/TP1/CPP/Makefile
@@ -0,0 +1,12 @@
+CC= g++ 
+CXXFLAGS= -Wall -ansi --pedantic -g
+
+CPP_O_FILE = arraylist.o main.o
+
+all: $(CPP_O_FILE)
+	$(CC) $(CXXFLAGS) -o arraylist_analysis $(CPP_O_FILE)
+
+clean:
+	rm -rf *.o
+	rm -rf *~
+	rm -rf arraylist_analysis
diff --git a/TP1/CPP/analyzer.hpp b/TP1/CPP/analyzer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..34546d877b7ab77d9f5eb1d556685dc1ded0c38d
--- /dev/null
+++ b/TP1/CPP/analyzer.hpp
@@ -0,0 +1,120 @@
+#ifndef __ANALYZER_HPP__
+#define __ANALYZER_HPP__
+
+#include<cmath>
+#include <vector>
+#include <iostream>
+#include <fstream>
+
+/**
+   Classe utilisée pour faire des statistiques élémentaires
+   sur une séquence d'opérations.
+*/
+class Analyzer{
+public:
+  /**
+   Constructeur de la classe analyse
+   Complexité en temps/espace, pire et meilleur cas : O(1)  
+ */
+  Analyzer():cumulative_square(0){}
+  
+  /**
+     Ajoute un coût, une valeur à l'analyse.
+     Complexité en temps/espace, pire cas : O(size)
+     Complexité en temps/espace, meilleur cas : O(1)
+     Complexité amortie : O(1)
+     @param x est la valeur que l'on souhaite ajouter à l'analyse.
+  */
+  void append(const double & x){
+    cost.push_back(x);    
+    cumulative_cost.push_back( (cumulative_cost.size()) ? cumulative_cost.back()+x : x);
+    cumulative_square += x*x;
+  }
+
+  /**
+     Renvoie la somme des coûts enregistrés dans cette analyse.
+     Complexité en temps/espace, meilleur cas : O(1)
+     @returns la somme des coûts enregistrés dans cette analyse.
+  */
+  double get_total_cost(){
+    return cumulative_cost.back();
+  }
+
+  /**
+     Renvoie le coût amorti d'une opération.
+     Complexité en temps/espace, meilleur cas : O(1)
+     @param pos est l'indice de l'opération pour laquelle on veut connaître le coût amorti.
+     @returns le coût amorti d'une opération.
+  */
+  double get_amortized_cost(size_t pos){
+    return (pos)? cumulative_cost.at(pos)/pos : cumulative_cost.at(pos); 
+  }
+
+  /**
+     Renvoie la moyenne des coûts de toutes les opérations enregistrées dans l'analyse.
+     Complexité en temps/espace, meilleur cas : O(1)
+     @returns la moyenne des coûts de toutes les opérations enregistrées dans l'analyse.
+  */
+  double get_average_cost(){
+    if(cumulative_cost.empty())
+      throw std::runtime_error("List is empty");
+    return cumulative_cost.back()/cumulative_cost.size();
+  }
+
+  /**
+     Renvoie la variance des coûts de toutes les opérations enregistrées dans l'analyse.
+     Complexité en temps/espace, meilleur cas : O(1)
+     @returns la variance des coûts de toutes les opérations enregistrées dans l'analyse.
+  */
+  double get_variance(){
+    double mean, mean_square;
+    mean = get_average_cost();
+    mean_square = mean * mean;
+    return cumulative_square - mean_square;
+  }
+
+  /**
+     Renvoie l'écart-type des coûts de toutes les opérations enregistrées dans l'analyse.
+     Complexité en temps/espace, meilleur cas : O(1)
+     @returns l'écart-type des coûts de toutes les opérations enregistrées dans l'analyse.
+  */
+  double get_standard_deviation(){
+    return std::sqrt(get_variance());
+  }
+
+  /**
+     Sauvegarde la liste des coûts et des coûts amortis dans un fichier.
+     Complexité en temps, meilleur/pire cas : O(size)
+     @param path est le chemin du fichier dans lequel la sauvegarde est faite.
+  */
+  void save_values(const std::string & path){
+    std::ofstream f;
+    size_t i;
+    f.open(path.c_str());
+    for (i = 0; i < cost.size(); ++i)
+      f<<i<<" "<<cost.at(i)<<" "<<get_amortized_cost(i)<<std::endl;
+    f.close();
+  }
+  
+  /**
+     Affiche la liste des coûts et des coûts amortis sur la sortie standard.
+     Complexité en temps, meilleur/pire cas : O(size)
+  */
+  void plot_values(){
+    size_t i;
+    for (i = 0; i < cost.size(); ++i)
+      std::cout<<i<<" "<<cost.at(i)<<" "<<get_amortized_cost(i)<<std::endl;
+  }
+
+private:
+  // Coût de chaque opération. Peut représenter du temps ou une autre mesure.
+  std::vector<double> cost;
+  // Coût cumulatif. La case i contient la somme des coûts des i premières opérations.
+  // Permet de calculer le coût amorti d'une opération.
+  std::vector<double> cumulative_cost;
+  // Carré du coût cumulatif. Sert à calculer la variance. On ne garde que la dernière valeur.
+  double cumulative_square;
+};
+
+
+#endif
diff --git a/TP1/CPP/arraylist.cpp b/TP1/CPP/arraylist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..67a6a394026fdc1118b9e97ae14442a19355c0f1
--- /dev/null
+++ b/TP1/CPP/arraylist.cpp
@@ -0,0 +1,9 @@
+#include "arraylist.hpp"
+
+
+template <typename P>
+P ArrayList<P>::get(const int & pos){
+  return data[pos];
+}
+
+
diff --git a/TP1/CPP/arraylist.hpp b/TP1/CPP/arraylist.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1ee96aa19b8b7ad19dec12fe281dcb4b44e808c4
--- /dev/null
+++ b/TP1/CPP/arraylist.hpp
@@ -0,0 +1,97 @@
+#ifndef __ARRAYLIST_HPP
+#define __ARRAYLIST_HPP
+
+#include<iostream>
+#include<vector>
+
+/**
+   Cette classe est un proxy pour les vecteurs, c'est à dire les tableaux dynamiques en C++.
+   On utilise cette classe afin d'avoir le contrôle sur la gestion de la mémoire.
+*/
+template <typename P>
+class ArrayList{
+public:
+  /**
+     Constructeur de la classe des tableaux dynamiques.
+     Complexité en temps/espace, pire et meilleur cas : O(1)  
+  */
+  ArrayList(){
+    data.reserve(4);
+  }
+
+  /**
+     Ajoute une valeur dans le tableau.
+     Complexité en temps/espace, pire cas : O(size)
+     Complexité en temps/espace, meilleur cas : O(1)
+     Complexité amortie : O(1)
+     @param x est la valeur que l'on souhaite ajouter.
+     @returns true si le tableau a été agrandit, false sinon
+  */
+  bool append(P x){
+    bool memory_allocation = false;
+    if( enlarging_capacity() ){
+      memory_allocation = true;
+      data.reserve( data.capacity() *2 );
+    }
+    data.push_back(x);
+    return memory_allocation;
+  }
+
+  /**
+     Supprime la dernière valeur du tableau.
+     Complexité en temps, pire cas : O(size)
+     Complexité en temps, meilleur cas : O(1)
+     Complexité amortie : O(1)
+     @returns true si le tableau a été réduit, false sinon
+  */
+  bool pop_back(){
+    bool memory_reduction = false;
+    if(!data.empty()){
+      if( reducing_capacity() ){
+	memory_reduction = true;
+	data.reserve( data.capacity() /2 );
+      }
+      data.pop_back();
+    }
+    return memory_reduction;
+  }
+  
+  /**
+     Renvoie la valeur située à la position donnée par l'utilisateur.
+     Complexité en temps/espace, pire cas : O(1)
+     @param pos est la l'indice de la case on l'utilisateur veut connaître la valeur.
+     @returns la valeur située à la position donnée par l'utilisateur.
+  */
+  P get(const int & pos);
+
+  /**
+     Renvoie le nombre d'éléments stockés dans le tableau.
+     Complexité en temps/espace, pire cas : O(1)
+     @returns le nombre d'éléments stockés dans le tableau.
+  */
+  const size_t get_size(){ return data.size(); }
+
+private:
+  // Vecteur contenant les données.
+  std::vector<P> data;
+
+  /**
+     Cette fonction détermine la règle selon laquelle un espace mémoire plus grand sera alloué ou non.
+     @returns true si le tableau doit être agrandi, false sinon.
+  */
+  bool enlarging_capacity(){
+    return data.size() >= (data.capacity() * 3)/4;
+  }
+
+  /**
+     Cette fonction détermine la règle selon laquelle un espace mémoire plus petit sera alloué ou non.
+     @returns true si le tableau doit être réduit, false sinon.
+  */
+  bool reducing_capacity(){
+    return data.size() <= data.capacity()/4 && data.size() >4;
+  }
+  
+};
+
+
+#endif
diff --git a/TP1/CPP/main.cpp b/TP1/CPP/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..490771380eec2d1c31e9d1920136667b3e24d5bf
--- /dev/null
+++ b/TP1/CPP/main.cpp
@@ -0,0 +1,44 @@
+#include<iostream>
+#include<time.h>
+#include<cstdlib>	
+#include "arraylist.hpp"
+#include "analyzer.hpp"
+
+
+int main(int argc, char ** argv){
+  int i;
+  // Tableau dynamique.
+  ArrayList<int> a;
+  // Analyse du temps pris par les opérations.
+  Analyzer time_analysis;
+  // Analyse du nombre de copies faites par les opérations.
+  Analyzer copy_analysis;
+  struct timespec before, after;
+  // Booléen permettant de savoir si une allocation a été effectuée.
+  bool memory_allocation;
+
+  for(i = 0; i < 1000000 ; i++){
+    // Ajout d'un élément et mesure du temps pris par l'opération.
+    timespec_get(&before, TIME_UTC);
+    memory_allocation = a.append(i);
+    timespec_get(&after, TIME_UTC);
+
+    // Enregistrement du temps pris par l'opération
+    time_analysis.append(after.tv_nsec - before.tv_nsec);
+    // Enregistrement du nombre de copies efféctuées par l'opération.
+    // S'il y a eu réallocation de mémoire, il a fallu recopier tout le tableau.
+    copy_analysis.append( (memory_allocation)? i:1 );
+  }
+
+  // Affichage de quelques statistiques sur l'expérience.
+  std::cerr<<"Total cost :"<<time_analysis.get_total_cost()<<std::endl;
+  std::cerr<<"Average cost :"<<time_analysis.get_average_cost()<<std::endl;
+  std::cerr<<"Variance :"<<time_analysis.get_variance()<<std::endl;
+  std::cerr<<"Standard deviation :"<<time_analysis.get_standard_deviation()<<std::endl;    
+
+  // Sauvegarde les données de l'expérience: temps et nombre de copies effectuées par opération.
+  time_analysis.save_values("../dynamic_array_time_cpp.plot");
+  copy_analysis.save_values("../dynamic_array_copy_cpp.plot");
+  
+  return 0;
+}