From 63d80bac503043c8b30f1cca7428d0ba76a9e196 Mon Sep 17 00:00:00 2001 From: Orestis <orestis.malaspinas@pm.me> Date: Thu, 27 Feb 2025 15:10:20 +0100 Subject: [PATCH] updated 2025 --- slides/opaque.md | 153 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 slides/opaque.md diff --git a/slides/opaque.md b/slides/opaque.md new file mode 100644 index 0000000..b15a4da --- /dev/null +++ b/slides/opaque.md @@ -0,0 +1,153 @@ +--- +title: "Types opaques" +date: "2025-02-28" +--- + +# Types composés + +* Jusqu'ici les `struct` sont dans les `.h` et sont *transparents* + +```C +// table.h +typedef struct _table { + int *data; + int length; +} table; +// main.c +table tab; // membres de tab accessibles directement +tab.length = 10; +tab.data = malloc(tab.length * sizeof(int)); +tab.data[9] = 10; +``` + +# Types opaques + +* Afin de cacher les détails de l'implémentation. +* Afin d'éviter les modifications directs des données. +* Afin de protéger le monde de la dévastation! +* Définition de types **opaques**: + * Variables dans les structures ne sont pas accessibles. + * Variables dans les structures ne sont pas modifiables. + * Les variables ne sont même pas connues. +* Nécessité de passer par des fonctions pour initialiser/modifier les instances + de types opaques. +* Très souvent utilisés pour les structures de données abstraites (table de + hachage, pile, file, ...). + +# Utilisation d'un type opaque: problème? + +* Dans `opaque.h` + + ```C + struct table; + ``` +* Dans `opaque.c` + + ```C + struct table { + int a; + } + ``` +* Dans `main.c` + + ```C + int main() { + struct table t; + } + // error: storage size of ‘t’ isn’t known + ``` +* La taille de `table` n'est pas connue à la compilation! +* Comment faire? + +# Utilisation d'un type opaque: pointeur! + +\footnotesize + +* Dans `opaque.h` + + ```C + struct table; + struct table *create(); + void init(struct table **t); + ``` +* Dans `opaque.c` + + ```C + struct table { + int a; + } + struct table *create() { + struct table *t = malloc(sizeof(*t)); + return t; + } + void init(struct table **t) { + *t = malloc(sizeof(**t)); + } + ``` +* Dans `main.c` + + ```C + int main() { + struct table *t = create(); + init(&t); + t->a = 2; // Interdit, set(2) + printf("%d\n", t->a); // Interdit, get() + } + ``` + +# Un peu plus joli: typedef! (1/2) + +* Dans `opaque.h` + + ```C + struct _table; + typedef struct _table * table; + void init(table *t); + void set_a(table t, int a); + int get_a(table t); + ``` +* Dans `opaque.c` + + ```C + struct _table { + int a; + } + void init(table *t) { + *t = malloc(sizeof(**t)); + (*t)->a = 0; + } + void set_a(table t, int a) { + t->a = a; + } + int get_a(table t) { + return t->a; + } + ``` + +# Un peu plus joli: typedef! (2/2) + +* Dans `main.c` + + ```C + int main() { + table t; + init(&t); + set_a(t, 10); + printf("%d\n", get_a(t)); + } + ``` + +* On a fait les fonctions `get_a()` et `set_a()` comme exemples, mais... + +. . . + +* c'est pas forcément nécessaire d'implémenter (`get/set`). + +. . . + +* Par exemple, pour la hashmap on `get/set` les variables des structs! + +## Yaka + +* Utiliser les types opaques pour la hashmap! + -- GitLab