diff --git a/exemples/alot_of_scanfs.c b/exemples/alot_of_scanfs.c deleted file mode 100644 index b07864c64f4258c7230efb4694087846a5df45c6..0000000000000000000000000000000000000000 --- a/exemples/alot_of_scanfs.c +++ /dev/null @@ -1,103 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -// Ce programme prend en argument deux -// entiers se trouvant chacun -// sur une nouvelle ligne et affiche -// la somme des deux entiers en argument -// sur une nouvelle ligne. - -// Ex: -// 12 -// 19 -// -// 31 - -void sum_two() { - int a, b; - scanf("%d %d", &a, &b); - - printf("\n%d\n", a + b); -} - -// Ce programme prend en argument 12 nombres à -// virgule flottante se trouvant chacun -// sur une nouvelle ligne. Multiplie chaque -// nombre par deux et affiche leur somme -// sur une nouvelle ligne suivi de CHF. - -// Ex: -// 12.2 -// 45.5 -// 1.5 -// 65.1 -// 89.4 -// 567.6 -// 112.8 -// 67.0 -// 35.1 -// 112.2 -// 3.3 -// 9.8 -// -// 2243.000000 CHF - -void sum_array() { - float sum = 0.0; - for (int i = 0; i < 12; ++i) { - float a = 0.0; - scanf("%f", &a); - a *= 2.0; - sum += a; - } - - printf("\n%f CHF\n", sum); -} - -// Ce programme prend en argument 2 chaînes de -// caractères sur des lignes séparées (longueur -// max de 80), les sépare au milieu et retourne -// les 4 chaînes chacune sur une nouvelle ligne -// (si la longueur N est paire on sépare en 2 -// chaînes de longueur N/2, sinon la première -// aura une longueur de N/2 et la seconde N/2+1). - -// Ex: -// abcdefgh -// asdfghjkl -// -// abcd -// efgh -// asdf -// ghjkl - -void split_mid() { - char str_one[2][41], str_two[2][41]; - for (int j = 0; j < 2; ++j) { - char str[81]; - scanf("%s", str); - int n = strlen(str); - int n1 = n / 2; - int n2 = n - n1; - for (int i = 0; i < n1; ++i) { - str_one[j][i] = str[i]; - } - str_one[j][n1] = '\0'; - for (int i = 0; i < n2; ++i) { - str_two[j][i] = str[n1 + i]; - } - str_two[j][n2] = '\0'; - } - printf("\n"); - for (int j = 0; j < 2; ++j) { - printf("%s\n", str_one[j]); - printf("%s\n", str_two[j]); - } -} - -int main() { - /* sum_two(); */ - sum_array(); - /* split_mid(); */ -} diff --git a/exemples/sum_n.c b/exemples/sum_n.c deleted file mode 100644 index 7b260a7bf6f5b816ba4343ae1c1a4c124ae0cc49..0000000000000000000000000000000000000000 --- a/exemples/sum_n.c +++ /dev/null @@ -1,22 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -int main() { - printf("Enter n: "); // affichage chaine de caractères - int n = 0; // déclaration et initialisation de n - scanf("%d", &n); // entrée au clavier - int sum = 0; // déclaration et initialisation de sum - for (int i = 0; i <= n; ++i) { // boucle for - sum += i; - } - printf("The sum of the %d first integers is: %d\n", n, sum); // affichage de n et sum - printf("The analytical formula is %d * (%d + 1) / 2 = %d.\n", n, n, n*(n+1)/2); // on peut mettre n'importe quelle expression - - if (sum != n * (n+1) / 2) { // branchement conditionnel - printf("Error: The answer we computed is wrong.\n"); - - return EXIT_FAILURE; // code d'erreur - } - - return EXIT_SUCCESS; // code de réussite -} \ No newline at end of file diff --git a/slides/les_exos_avec_le_dojo.md b/slides/les_exos_avec_le_dojo.md index 6a06a7b1f4bb5d3bd6a483ca09b7a13eab89ef94..8aadf7be18321c45a8bbb388eb62b4542ce2f052 100644 --- a/slides/les_exos_avec_le_dojo.md +++ b/slides/les_exos_avec_le_dojo.md @@ -1,6 +1,6 @@ --- title: "Dojo" -date: "2024-02-21" +date: "2025-02-21" --- # Le Dojo @@ -77,6 +77,8 @@ $ dojo auth test ... ``` * Cette commande clone également le repo de l'exercice créé dans le répertoire courant +* Laissez l'opération se terminer +* Ne quittez **JAMAIS** le repo git sur `gitedu` # Faire un exercice (2/3) diff --git a/slides/opaque.md b/slides/opaque.md new file mode 100644 index 0000000000000000000000000000000000000000..b15a4dab3695b8db484833458f5f0b179fd3ced4 --- /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! + diff --git a/slides/pointeurs_avances.md b/slides/pointeurs_avances.md new file mode 100644 index 0000000000000000000000000000000000000000..0eea725dc00afb54874ce92535c49ec096a51e61 --- /dev/null +++ b/slides/pointeurs_avances.md @@ -0,0 +1,92 @@ +--- +title: "Pointeurs avancés" +date: "2025-03-21" +--- + +# Pointeurs et `const` + +\footnotesize + +- Le mot-clé `const` permet de déclarer des valeurs **constantes** qui ne changeront plus en cours d'exécution du programme. + + ```C + const int a = 1; + a = 2; // interdit, erreur de compilation! + ``` + +## Deux niveaux de constance + +- Mais qu'est-ce que cela veut dire pour les pointeurs? +* Constance de la valeur de l'adresse? de la valeur pointée? des deux? + + ```C + int n = 12; + const int *p = &n; // la valeur *p est const, p non + int const *p = &n; // la valeur *p est const, p non + int *const p = &n; // la valeur p est const, *p non + const int *const p = &n; // la valeur p et *p sont const + ``` + +# Pointeurs et `const` + +## Exemples + +```C +int n = 12; int m = 13; +const int *p = &n; // la valeur *p est const, p non +*p = m; // erreur de compilation. +p = &m; // OK +int const *p = &n; // la valeur *p est const, p non +*p = m; // erreur de compilation. +p = &m; // OK +int *const p = &n; // la valeur p est const, *p non +*p = m; // OK +p = &m; // erreur de compilation. +const int *const p = &n; // la valeur p et *p sont const +*p = m; // erreur de compilation. +p = &m; // erreur de compilation. +``` + +# Rappel: pointeurs et fonction + +## Faites un dessin de ce qui se passe en mémoire + +```C +void foo(int *a) { + *a = 3; +} +void bar(int a) { + a = 12; +} +int main() { + int a = 1; + foo(&a); // Que vaut a? + bar(a); // Que vaut a? +} +``` + +# Pointeurs et `const` + +## Fonctions + +```C +void foo(int *a); +void foo(const int *a); // on pourra pas changer *a +void foo(int *const a); // inutile on peut pas changer a +void foo(const int *const a); // identique à ci-dessus +``` + +## Mais..... + +```C +const int a = 0; +int *b = (int *)&a; +*b = 7; +printf("a = %d\n", a); // affiche quoi? +``` + +# Utilité + +* Permet d'empêcher une mauvaise utilisation des arguments, +* Permet de documenter le code: on sait que la variable ne sera pas modifiée. +