Skip to content
Snippets Groups Projects
Verified Commit 707be853 authored by orestis.malaspin's avatar orestis.malaspin
Browse files
parents 734d6daf cccd3332
Branches
No related tags found
No related merge requests found
Pipeline #26371 passed
--- ---
subtitle: "Programmation séquentielle en C, 2022-2023" subtitle: "Programmation séquentielle en C, 2022-2023"
author: "Orestis Malaspinas (A401)" author: "Orestis Malaspinas (A401) et un tout petit peu Michaël El Kharroubi"
institute: "Informatique et Systèmes de Communication, HEPIA" institute: "Informatique et Systèmes de Communication, HEPIA"
lang: fr-CH lang: fr-CH
revealjs-url: /reveal.js revealjs-url: /reveal.js
......
...@@ -135,9 +135,9 @@ vec3 mul(vec3 lhs, vec3 rhs){ ...@@ -135,9 +135,9 @@ vec3 mul(vec3 lhs, vec3 rhs){
* Une fonction d'ordre supérieur est une fonction qui prend en paramètre et/ou retourne une(des) autre(s) fonction(s). * Une fonction d'ordre supérieur est une fonction qui prend en paramètre et/ou retourne une(des) autre(s) fonction(s).
* Si on essayait de définir `operator`, c'est en fait une fonction qui prend deux paramètres (un terme de gauche et un terme de droite). On s'en aperçoit clairement avec la notation préfix (polonaise). * Si on essayait de définir `operator`, c'est en fait une fonction qui prend deux paramètres (un terme de gauche et un terme de droite). On s'en aperçoit clairement avec la notation préfix (polonaise).
* `L + R` -> `+ L R` * `L + R -> + L R`
* `L - R` -> `- L R` * `L - R -> - L R`
* `L * R` -> `* L R` * `L * R -> * L R`
* Comment l'implémenter concrètement en C? * Comment l'implémenter concrètement en C?
...@@ -153,20 +153,23 @@ vec3 apply_operator(operator op, vec3 lhs, vec3 rhs); ...@@ -153,20 +153,23 @@ vec3 apply_operator(operator op, vec3 lhs, vec3 rhs);
* Pour passer une fonction en paramètre en C, nous devons la passer par référence, c'est à dire à l'aide d'un pointeur de fonction. * Pour passer une fonction en paramètre en C, nous devons la passer par référence, c'est à dire à l'aide d'un pointeur de fonction.
# Rappel pointeur de fonctions # Pointeur de fonctions
* Un pointeur de fonction se définit ainsi * Un pointeur de fonction se définit ainsi
```c ```c
typedef
<type retour> (*<nom ptr fonc>)(<type params(s)>); <type retour> (*<nom ptr fonc>)(<type params(s)>);
``` ```
* Ou encore avec un `typedef`
```c
typedef <type retour> (*<nom ptr fonc>)(<type params(s)>);
```
* Dans notre cas, nous avons donc un type de fonction nommé `operator`, qui prend en entrée deux `double`{.c} et qui retourne un `double`{.c}. Ce qui nous donne * Dans notre cas, nous avons donc un type de fonction nommé `operator`, qui prend en entrée deux `double`{.c} et qui retourne un `double`{.c}. Ce qui nous donne
```c ```c
typedef double (*operator)(double, double); typedef double (*operator)(double, double);
``` ```
# Implémentation (suite) # Implémentation (suite)
...@@ -188,7 +191,6 @@ vec3 apply_operator(operator op, vec3 lhs, vec3 rhs){ ...@@ -188,7 +191,6 @@ vec3 apply_operator(operator op, vec3 lhs, vec3 rhs){
```c ```c
typedef double (*operator)(double, double); typedef double (*operator)(double, double);
vec3 apply_operator(operator op, vec3 lhs, vec3 rhs){ vec3 apply_operator(operator op, vec3 lhs, vec3 rhs){
vec3 res; vec3 res;
res.x = op(lhs.x, rhs.x); res.x = op(lhs.x, rhs.x);
...@@ -196,9 +198,9 @@ vec3 apply_operator(operator op, vec3 lhs, vec3 rhs){ ...@@ -196,9 +198,9 @@ vec3 apply_operator(operator op, vec3 lhs, vec3 rhs){
res.z = op(lhs.z, rhs.z); res.z = op(lhs.z, rhs.z);
return res; return res;
} }
double add_dbl(double lhs, double rhs){
double add_dbl(double lhs, double rhs){return lhs + rhs;} return lhs + rhs;
}
vec3 add(vec3 lhs, vec3 rhs){ vec3 add(vec3 lhs, vec3 rhs){
return apply_operator(add_dbl, lhs, rhs); return apply_operator(add_dbl, lhs, rhs);
} }
...@@ -214,3 +216,62 @@ vec3 add(vec3 lhs, vec3 rhs){ ...@@ -214,3 +216,62 @@ vec3 add(vec3 lhs, vec3 rhs){
* Reduce (réduction d'un vecteur à un seul élément) * Reduce (réduction d'un vecteur à un seul élément)
* `sum`, `multiply` * `sum`, `multiply`
# Le map
* Exemple d'application
```c
typedef double (*operator)(double);
double *map(operator op, double *tab, size_t size) {
double *res = malloc(sizeof(*res) * size);
for (int i = 0; i < size; ++i) {
res[i] = op(tab[i]);
}
return res;
}
double add_one(double val) {
return val + 1;
}
double sqr(double val){
return val * val;
}
double tab[] = {1.0, 2.0, 3.0};
double *square = map(sqr, tab, 3);
double *and_one = map(add_one, square, 3);
```
# Le map
* Permettrait le chaînage.
```C
double *sqr_and_one = map(add_one, map(sqr, tab, 3), 3);
```
. . .
* Problème?
. . .
* Allocation dynamique... fuite mémoire.
. . .
* Solution?
. . .
```c
typedef double (*operator)(double);
double *map(operator op, double *tab, size_t size) {
double *res = malloc(sizeof(*res) * size);
for (int i = 0; i < size; ++i) {
res[i] = op(tab[i]);
}
free(tab);
return res;
}
```
* Problème potentiel?
* **Attention au double free!**
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment