diff --git a/lessons/contenu_cours_5.md b/lessons/contenu_cours_5.md
new file mode 100644
index 0000000000000000000000000000000000000000..5affcce9f309fca459ba11a908acdd532c937a76
--- /dev/null
+++ b/lessons/contenu_cours_5.md
@@ -0,0 +1,192 @@
+# Algorithmique et structures de données 2019-20
+
+Contenu du cours 5 du 16.10.2019
+
+******
+
+##  Type composé : `struct`
+
+- **Exemple des fractions**
+    - On considère une structure pour stocker des fractions :
+```C
+        struct _fraction {
+            int num;
+            int den;
+        } fraction;
+```
+    - On aimerait aussi définir les opérations arithmétiques associées ou utilitaires :
+```C
+        void print(fraction frac);
+        int pgcd(int n,int m);
+        void reduire(fraction* frac);
+        fraction fraction_build(int num,int den);
+        fraction add(fraction frac1,fraction frac2);
+        fraction add1(int n,fraction frac);
+        fraction add2(fraction frac,int n);
+        void add_inplace(fraction* frac1,fraction frac2);
+        fraction sub(fraction frac1,fraction frac2);
+        fraction sub1(int n,fraction frac);
+        fraction sub2(fraction frac,int n);
+        void sub_inplace(fraction* frac1,fraction frac2);
+        fraction mult(fraction frac1,fraction frac2);
+        fraction mult1(int n,fraction frac);
+        fraction mult2(fraction frac,int n);
+        void mult_inplace(fraction* frac1,fraction frac2);
+        fraction divise(fraction frac1,fraction frac2);
+        fraction divise1(int n,fraction frac);
+        fraction divise2(fraction frac,int n);
+        void divise_inplace(fraction* frac1,fraction frac2);
+        fraction puiss(fraction frac,int n);
+        float reel(fraction frac);
+```
+    -   Quelques implémentations de fonctions 
+```C
+        void reduire(fraction* frac) {
+            if (0 == frac­>num) {
+                frac­>den = 1;
+            } else {
+                int gcd = pgcd(abs(frac­>num),frac­>den);
+                frac­>num /= gcd;
+                frac­>den /= gcd;
+            }
+        }
+        
+        fraction fraction_build(int num,int den) {
+            assert(den != 0);
+            int sign = den/abs(den);
+            fraction res = {sign*num,sign*den};
+            reduire(&res);
+            return res;
+        }
+    
+        fraction add(fraction frac1,fraction frac2) {
+            return fraction_build(
+                frac1.num*frac2.den+frac1.den*frac2.num,
+                frac1.den*frac2.den
+            );
+        }
+    
+        fraction add1(int n,fraction frac) {
+            return add(fraction_build(n,1),frac);
+        }
+    
+        fraction add2(fraction frac,int n,) {
+            return add1(n,frac);
+        }
+    
+        void add_inplace(fraction* frac1,fraction frac2) {
+            *frac1 = add(*frac1,frac2);
+        }
+    
+        fraction puiss(fraction frac,int n) {
+            fraction prod = fraction_build(1,1);
+            for (int i=1;i<=abs(n);i++) {
+                prod = mult(prod,frac);
+            }
+            if (n < 0) {
+                prod = divise1(1,prod);
+            }
+            return prod;
+        }
+```
+
+- **Exemple des chaînes de caractères**
+
+    -   On peut définir un type pour les chaînes de caractères en stockant la longueur effective de la chaîne, c'est-à-dire la première occurrence du caractère `\0`
+```C
+        struct _chaine {
+            char* str;
+            int len;
+        } chaine;
+```
+    -   Quelques implémentations de fonctions
+```C
+        chaine chaine_build(char* phrase) {
+            chaine ch;
+            ch.len = length(phrase);
+            ch.str = malloc((ch.len+1)*sizeof(char));
+            for (int i=0;i<ch.len;i++) {
+                ch.str[i] = phrase[i];
+            }
+            return ch;
+        }
+    
+        chaine deep_copy(chaine ch) {
+            return chaine_build(ch.str);
+        }
+    
+        // Dangereux, car plusieurs pointeurs
+        // sur le même tableau de caractères !!!
+        chaine shallow_copy(chaine ch) {
+            chaine cpy;
+            cpy.len = ch.len;
+            cpy.str = ch.str;
+            return cpy;
+        }
+    
+        // Si plusieurs pointeurs sur même tableau de caractères,
+        // alors autres pointeurs dessus ne seront pas mis à NULL
+        void chaine_free(chaine* ch) {
+            if (NULL != ch­>str)
+                free(ch­>str);
+                ch­>str = NULL;
+            }
+            ch­>len = -­1;
+        }
+```
+    - Illustration
+
+
+##  Récursivité
+
+-   Exemple de la factorielle : n ! = n·(n-1)·(n-2)·... ·3·2·1 = n·(n-1) !   
+    Donc fact(n) = n·fact(n-1) (récursivité)  
+    et fact(1) = 1 (condition d'arrêt)
+```C
+        int fact(int n) {
+            if (n > 1) {
+                return n*fact(n­1);
+            } else {
+                return 1;
+            }
+        }
+        void main() {
+            int f = fact(4);
+        }
+```
+-   Exemple du PGCD   
+    Algorithme d'Euclide pour le PGCD de 42 et 27  
+
+>       42 = 27·1 + 15  
+>       27 = 15·1 + 12  
+>       15 = 12·1 +  3  
+>       12 =  3·4 +  0  
+    PGCD(42,27)=PGCD(27,15)=PGCD(15,12)=PGCD(12,3)=3
+```C
+        int pgcd(int n,int m) {
+            if (n%m > 0) {
+                return pgcd(m,n%m);
+            } else {
+                return m;
+            }
+        }
+```
+-   Exemple de l'écriture binaire
+```C
+        void binaire(int n) {
+            printf("%d",n%2);
+            if (n/2 != 0) {
+                binaire(n/2);
+            } else {
+                printf("\n");
+            }
+            // printf("%d",n%2);
+        }
+
+        Binaire(13); // affiche 1 0 1 1 puis un retour à la ligne`
+```
+> > > $\hspace*{36mm} 2^0 2^1 2^2 2^3$  
+
+-   Que se passe-t-il si on décommente le deuxième `printf` ?
+
+