Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • high-order-functions
  • master
  • pk
  • yassin.elhakoun-master-patch-15592
  • yassin.elhakoun-master-patch-40090
5 results

Target

Select target project
  • programmation_sequentielle/cours
  • yassin.elhakoun/cours-de-prog
2 results
Select Git revision
  • high-order-functions
  • master
  • pk
3 results
Show changes
Commits on Source (9)
......@@ -86,6 +86,7 @@ if (x) { // si x s'évalue à `vrai`
int i = 0;
while (i < 10) {
if (i == 3) {
i += 1;
continue;
}
printf("%d\n", i);
......@@ -122,10 +123,11 @@ if (x) { // si x s'évalue à `vrai`
```C
int main() {
// ...
if (error)
if (error) {
return EXIT_FAILURE;
else
} else {
return EXIT_SUCCESS;
}
}
```
......
......@@ -3,7 +3,6 @@ subtitle: "Programmation séquentielle en C, 2023-2024"
author: "Orestis Malaspinas (A401)"
institute: "Informatique et Systèmes de Communication, HEPIA"
lang: fr-CH
revealjs-url: /reveal.js
mathjaxurl: "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"
---
---
title: "Types opaques"
date: "2024-02-27"
---
# 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!
......@@ -15,9 +15,11 @@ date: "2023-10-12"
void foo(int a) {
a = 2;
}
int x = 1;
foo(x);
// Que vaut x ici?
void main() {
int x = 1;
foo(x);
// Que vaut x ici?
}
```
# Rappel (2/3)
......@@ -28,9 +30,11 @@ date: "2023-10-12"
void foo(int a) {
a = 2;
}
int x = 1;
foo(x);
// x vaut toujours 1
void main() {
int x = 1;
foo(x);
// x vaut toujours 1
}
```
* Une nouvelle variable `int a` est créée lors de l'appel à `foo(a)`, et on lui assigne la valeur de `x`.
......@@ -48,9 +52,11 @@ date: "2023-10-12"
void foo(int *a) { // le pointeur a
*a = 2; // déréférencement du pointeur a
}
int x = 1;
foo(&x); // référence vers x
// Ici x faut 2
void main() {
int x = 1;
foo(&x); // référence vers x
// Ici x faut 2
}
```
* Une nouvelle variable `int *a` est créée lors de l'appel à `foo`, et on lui assigne la valeur de `&x`.
* `&x` n'est jamais modifiée **mais** `x` l'est.
......@@ -63,9 +69,11 @@ date: "2023-10-12"
int foo(int a) {
return a + 2;
}
int x = 1;
int y = foo(x); // x n'est pas modifiée
// et y vaut x + 2
void main() {
int x = 1;
int y = foo(x); // x n'est pas modifiée
// et y vaut x + 2
}
```
# Les tableaux statiques
......