Skip to content
Snippets Groups Projects
Verified Commit 67f0541b authored by orestis.malaspin's avatar orestis.malaspin
Browse files

added opaque

parent b83d9da4
No related branches found
No related tags found
No related merge requests found
CC:=gcc
CFLAGS:=-Wall -Wextra -pedantic -g -fsanitize=address -fsanitize=leak -std=c2x
LDFLAGS:=-fsanitize=address -fsanitize=leak
main: opaque.o main.o
$(CC) -o $@ $^ $(LDFLAGS)
opaque.o: opaque.h
.PHONY: clean
clean:
rm -f *.o main
\ No newline at end of file
#include "opaque.h"
#include <stdio.h>
int main()
{
table t;
init(&t);
set(t, 10);
printf("%d\n", get(t));
destroy(&t);
}
\ No newline at end of file
#include "opaque.h"
#include <stdlib.h>
struct _table
{
int len;
int *data;
};
void init(table *tab)
{
*tab = malloc(sizeof(struct _table));
}
void destroy(table *tab)
{
free(*tab);
*tab = NULL;
}
int get(table tab)
{
return tab->len;
}
void set(table tab, int len)
{
tab->len = len;
}
#ifndef OPAQUE_H
#define OPAQUE_H
struct _table;
typedef struct _table *table;
void init(table *tab);
void set(table tab, int len);
int get(table tab);
void destroy(table *tab);
#endif
---
title: "Types opaques"
date: "2023-03-07"
---
# 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() {
struct table *t = create();
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 l'exemple de la hashmap on `get/set` les variables des structs!
## Yaka
* Utiliser les types opaques pour la hashmap!
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment