diff --git a/Makefile b/Makefile index 2a369d840ae922faa3768b19d771387da4e8e6e2..85b2464b0bc2b1ebeacba57e53cb9d4c1a717f5c 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,9 @@ REVEALOPTIONS += --self-contained REVEALOPTIONS += -V revealjs-url=./reveal.js REVEALOPTIONS += -V theme=white -all: base_5.pdf base_4.pdf base_3.pdf base_2.pdf base_1.pdf intro.pdf command_line.pdf index.html +all: base_6.pdf base_5.pdf base_4.pdf base_3.pdf base_2.pdf base_1.pdf intro.pdf command_line.pdf index.html -all_html: intro.html base_1.html base_2.html base_3.html base_4.html base_5.html command_line.html +all_html: intro.html base_1.html base_2.html base_3.html base_4.html base_5.html base_6.html command_line.html intro.pdf: intro.md metadata.yaml pandoc $(PDFOPTIONS) -o $@ $^ @@ -55,6 +55,12 @@ base_5.pdf: base_5.md metadata.yaml base_5.html: base_5.md metadata.yaml pandoc $(REVEALOPTIONS) -o $@ $^ +base_6.pdf: base_6.md metadata.yaml + pandoc $(PDFOPTIONS) -o $@ $^ + +base_6.html: base_6.md metadata.yaml + pandoc $(REVEALOPTIONS) -o $@ $^ + command_line.pdf: command_line.md metadata.yaml pandoc $(PDFOPTIONS) -o $@ $^ diff --git a/base_6.md b/base_6.md new file mode 100644 index 0000000000000000000000000000000000000000..d76f394ff9dbe3246683a18839e86be588f3ae20 --- /dev/null +++ b/base_6.md @@ -0,0 +1,109 @@ +% Base VI +% Inspirés des slides de F. Glück +% 28 octobre 2020 + +# Pointeurs de pointeurs + +## Doubles pointeurs + +- Un pointeur était un type comme un autre, on peut définir un pointeur sur un pointeur: + + ```C + // pointeur sur un pointeur d'entier 32bits + int32_t **double_ptr; + ``` +- Cela peut servir à deux choses principalement + 1. Allouer un tableau de tableau. + 2. Modifier un pointeur en argument dans une fonction. +- On peut même aller plus loin et avoir ds pointeurs de pointeurs de pointeurs ... de pointeurs. + + ```C + int32_t *************************a; + ``` + +## Exemple: tableau de tableaux + +- Cas pratique + + ```C + int32_t **p = malloc(3 * sizeof(int32_t *)); + p[0] = malloc(3 * sizeof(int32_t)); + p[1] = malloc(5 * sizeof(int32_t)); + p[2] = malloc(8 * sizeof(int32_t)); + ``` +- Faites un dessin de ce qui se passe en mémoire! + +## Exemple: argument d'une fonction + +- Modification d'un pointeur en argument à une fonction + + ```C + void alloc_ptr(int32_t **p, int32_t size) { + *p = malloc(size * sizeof(int32_t)); + } + ``` +- Que se passe-t-il si on utilise pas un `int32_t **p`{.C} mais un `int32_t *p`{.C}. + +# Pointeurs avancés + +## Pointeurs de fonctions (1/3) + +- Considérons la fonction `max` retournant la valeur maximale d'un tableau + + ```C + int32_t max(int32_t *t, int32_t size) { + int32_t val_max = t[0]; + for (int32_t i = 1; i < size; ++i) { + if (t[i] > val_max) { + val_max = t[i]; + } + } + return val_max; + } + ``` +- L'appel à `max`, retourne l'adresse de la fonction en mémoire. +- On peut affecter cette valeur à un pointeur. + +## Pointeurs de fonctions (2/3) + +- Le type de la fonction `max` est + + ```C + int32_t (*pmax)(int32_t *, int32_t); + ``` +- Le type doit être déclaré avec la signature de la fonction. +- On peut alors utiliser l'un ou l'autre indifféremment + + ```C + int32_t (*pmax)(int32_t *, int32_t); + pmax = max; + int32_t tab[] = {1, 4, -2, 12}; + printf("%d", max(tab, 4)); // retourne 12 + printf("%d", pmax(tab, 4)); // retourne 12 aussi + ``` + +## Pointeurs de fonctions (3/3) + +- On peut passer des fonctions en argument à d'autres fonctions + + ```C + int32_t reduce(int32_t *tab, int32_t size, int32_t init, + int32_t (*red_fun)(int32_t, int32_t)) + { + for (int32_t i = 0; i < size; ++i) { + init = red_fun(init, tab[i]); + } + return init; + } + ``` +- Ici une fonction de *réduction* `sum()`{.C} + + ```C + int32_t sum(int32_t lhs, int32_t rhs) { + return lhs + rhs; + } + int32_t tab[] = {1, 4, -2, 12}; + int32_t red = reduce(tab, 4, 0, sum); + printf("%d", red); // affiche 15 + ``` +