diff --git a/slides/variables_fonctions.md b/slides/variables_fonctions.md new file mode 100644 index 0000000000000000000000000000000000000000..de50724b00f1eac70d26af75905065715e49aa1f --- /dev/null +++ b/slides/variables_fonctions.md @@ -0,0 +1,237 @@ +--- +title: "Variables et fonctions" +date: "2022-10-04" +patat: + wrap: true + margins: + left: 10 + right: 10 +--- + +# Les variables + +## Qu'est-ce qu'une variable? + +. . . + +* Un **identifiant** + +. . . + +* pour un **espace de stockage** + +. . . + +* contenant un **valeur**. + +## En général, une variable possède: + +* Un **type** (`int`, `double`, ...); +* une **adresse mémoire** (voir ci-après). + +# Représentation des variables en mémoire (1/3) + +## La mémoire est : + +- ... un ensemble de bits, +- ... accessible via des adresses, + + +------+----------+----------+------+----------+------+------+ + | bits | 00110101 | 10010000 | .... | 00110011 | .... | .... | + +======+==========+==========+======+==========+======+======+ + | addr | 2000 | 2001 | .... | 4000 | .... | .... | + +------+----------+----------+------+----------+------+------+ +- ... gérée par le système d'exploitation. +- ... séparée en deux parties: **la pile** et **le tas**. + +## Pile vs tas + ++----------------------------------+------------------------------+ +| Pile | Tas | ++==================================+==============================+ +| Ordonnée | Amas informe | ++----------------------------------+------------------------------+ +| Taille connue (à la compilation) | Taille dynamique (exécution) | ++----------------------------------+------------------------------+ + +# Représentation des variables en mémoire (2/3) + +## Une variable, `type a = valeur`{.C}, possède: + +- un type (`char`{.C}, `int`{.C}, ...), +- un contenu (une séquence de bits qui encode `valeur`{.C}), +- une adresse mémoire (accessible via `&a`{.C}), +- une portée. + +## En fonction du **type** les bits ne représentent pas la même chose! + +# Représentation des variables en mémoire (3/3) + +{width=100%} + +# Les fonctions (1/7) + +- Les parties indépendantes d'un programme. +- Permettent de modulariser et compartimenter le code. +- Syntaxe: + + ```C + type identificateur(paramètres) { + // variables optionnelles + instructions; + // type expression == type + return expression; + } + ``` + +# Les fonctions (2/7) + +## Exemple + +```C +int max(int a, int b) { + if (a > b) { + return a; + } else { + return b; + } +} +int main() { + int c = max(4, 5); +} +``` + +# Les fonctions (3/7) + +- Il existe un type `void`{.C}, "sans type", en C. +- Il peut être utilisé pour signifier qu'une fonction ne retourne rien, ou qu'elle n'a pas d'arguments. +- `return`{.C} utilisé pour sortir de la fonction. +- Exemple: + + ```C + void show_text(void) { // second void optionnel + printf("Aucun argument et pas de retour.\n"); + return; // optionnel + } + void show_text_again() { // c'est pareil + printf("Aucun argument et pas de retour.\n"); + } + ``` + +# Les fonctions (4/7) + +## Prototypes de fonctions + +- Le prototype donne la **signature** de la fonction, avant qu'on connaisse son implémentation. +- L'appel d'une fonction doit être fait **après** la déclaration du prototype. + + ```C + int max(int a, int b); // prototype + + int max(int a, int b) { // implémentation + if (a > b) { + return a; + } else { + return b; + } + } + ``` + +# Les fonctions (5/7) + +## Arguments de fonctions + +- Les arguments d'une fonction sont toujours passés **par copie**. +- Les arguments d'une fonction ne peuvent **jamais** être modifiés. + + ```C + void set_to_two(int a) { // a: nouvelle variable + // valeur de a est une copie de x + // lorsque la fonction est appelée, ici -1 + a = 2; // la valeur de a est fixée à 2 + } // a est détruite + int main() { + int x = -1; + set_to_two(x); // -1 est passé en argument + // x vaudra toujours -1 ici + } + ``` + +# Les fonctions (6/7) + +## Arguments de fonctions: pointeurs + +- Pour modifier un variable, il faut passer son **adresse mémoire**. +- L'adresse d'une variable, `x`{.C}, est accédé par `&x`{.C}. +- Un **pointeur** vers une variable entière a le type, `int *x`{.C}. +- La syntaxe `*x`{.C} sert à **déréférencer** le pointeur (à accéder à la mémoire pointée). + +# Les fonctions (7/7) + +## Exemple + +```C +void set_to_two(int *a) { + // a contient une copie de l'adresse de la + // variable passée en argument + + *a = 2; // on accède à la valeur pointée par a, + // et on lui assigne 2 +} // le pointeur est détruit, pas la valeur pointée +int main() { + int x = -1; + set_to_two(&x); // l'adresse de x est passée + // x vaudra 2 ici +} +``` + +# Quiz: Les fonctions + +## [Quiz: Les fonctions](https://cyberlearn.hes-so.ch/mod/evoting/view.php?id=1038560) + +<!-- TODO quiz; +```C +void set_to_two(int *a) { + a = 2; +} +int main() { + int x = -1; + set_to_two(&x); +} + + +void add_two(int *a) { + *a += 2; +} + +int main() { + int x = -1; + add_two(&x); +} + +void add_two(int a) { + a += 2; + printf("%d", a); +} +int main() { + int x = -1; + add_two(&x); +} +``` --> + +# Comment lire une signature? + +Que peut-on déduire de la signature de la fonction suivante: + +```C +int32_t bissect(double a1, double b1, double epsilon, + double *zero); +``` + +. . . + +Une fonction prenant trois `double` en argument, et un pointeur de +`double` (il est donc modifiable) et retournant un entier. + +Un site permettant de faire ce genre de traductions: +<https://cdecl.org/>