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

dynamic allocation

parent f11be600
No related branches found
No related tags found
No related merge requests found
......@@ -15,9 +15,9 @@ REVEALOPTIONS += --self-contained
REVEALOPTIONS += -V revealjs-url=./reveal.js
REVEALOPTIONS += -V theme=white
all: base_4.pdf base_3.pdf base_2.pdf base_1.pdf intro.pdf command_line.pdf index.html
all: base_5.pdf base_4.pdf base_3.pdf base_2.pdf base_1.pdf intro.pdf command_line.pdf index.html
all_html: intro.html base_1.html base_2.html base_3.html base_4.html command_line.html
all_html: intro.html base_1.html base_2.html base_3.html base_4.html base_5.html command_line.html
intro.pdf: intro.md metadata.yaml
pandoc $(PDFOPTIONS) -o $@ $^
......@@ -49,6 +49,12 @@ base_4.pdf: base_4.md metadata.yaml
base_4.html: base_4.md metadata.yaml
pandoc $(REVEALOPTIONS) -o $@ $^
base_5.pdf: base_5.md metadata.yaml
pandoc $(PDFOPTIONS) -o $@ $^
base_5.html: base_5.md metadata.yaml
pandoc $(REVEALOPTIONS) -o $@ $^
command_line.pdf: command_line.md metadata.yaml
pandoc $(PDFOPTIONS) -o $@ $^
......
......@@ -2,37 +2,11 @@
% Inspirés des slides de F. Glück
% 14 octobre 2020
# Représentation des variables en mémoire (1/2)
## La mémoire
* 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**.
## Une variable
* 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.
# Représentation des variables en mémoire (2/2)
# Rappel: représentation des variables en mémoire
![Les variables en mémoire.](figs/memory.svg){#fig:memory width=100%}
# Les pointeurs (1/3)
# Rappel: Les pointeurs (1/3)
- Un pointeur est une adresse mémoire.
......@@ -52,11 +26,11 @@
- `NULL`{.C} (ou `0`{.C}) est la seule adresse **toujours** invalide.
# Les pointeurs (2/3)
# Rappel: Les pointeurs (2/3)
![Les pointeurs, le déréférencement, et la mémoire.](figs/memory_deref.svg){#fig:memory width=100%}
# Les pointeurs (3/3)
# Rappel: Les pointeurs (3/3)
- Permettent d'accéder à une valeur avec une indirection.
......@@ -128,7 +102,7 @@
```
- Pour chaque `malloc()`{.C} doit correspondre exactement un `free()`{.C}.
- Si la mémoire n'est pas libérée: **fuite mémoire** (l'ordinateur plante quand il y a plus de mémoire).
- Si la mémoire est **libérée deux** fois: seg fault.
- Si la mémoire est **libérée deux** fois: *seg. fault*.
- Pour éviter les mauvaises surprises mettre `ptr`{.C} à `NULL`{.C}.
# Allocation dynamique de mémoire (4/8)
......@@ -183,7 +157,6 @@
## Pointeur de pointeur
![L'arithmétique des pointeurs.](figs/double_pointeur.svg){#fig:compilation height=100%}
# Allocation dynamique de mémoire (8/8)
......@@ -200,200 +173,6 @@
- Ceci est une matrice (un tableau de tableau).
# Prototypes de fonctions (1/N)
## Principes généraux de programmation
- Beaucoup de fonctionnalités dans un code $\Rightarrow$ Modularisation.
- Modularisation du code $\Rightarrow$ écriture de fonctions.
- Beaucoup de fonctions $\Rightarrow$ regrouper les fonctions dans des fichiers séparés.
## Mais pourquoi?
- Lisibilité.
- Raisonnement sur le code.
- Débogage.
## Exemple
- Libraire `stdio.h`: `printf()`{.C}, `scanf()`{.C}, ...
# Prototypes de fonctions (2/N)
- Prototypes de fonctions nécessaires quand:
1. Utilisation de fonctions dans des fichiers séparés.
2. Utilisation de librairies.
- Un prototype indique au compilateur la signature d'une fonction.
- On met les prototypes des fonctions **publiques** dans des fichiers *headers*, extension `.h`.
- Les *implémentations* des fonctions vont dans des fichier `.c`.
# Prototypes de fonctions (3/N)
## Fichier header
- Porte l'extension `.h`
- Contient:
- définitions des types
- prototypes de fonctions
- macros
- directives préprocesseur (cf. plus loin)
- Utilisé pour décrire **l'interface** d'une librairie ou d'un module.
- Un fichier `C` (extension `.c`) utilise un header en *l'important* avec la directive `#include`{.C}:
```C
#include <stdio.h> // libraire dans LD_LIBRARY_PATH
#include "chemin/du/prototypes.h"// chemin explicite
```
# Génération d'un exécutable (1/N)
## Un seul fichier source
![Étapes de génération.](figs/compilation.svg){#fig:compilation width=100%}
# Génération d'un exécutable (2/N)
## Un seul fichier source
```bash
gcc proc.c -o prog
```
1. **Précompilation: ** `gcc` appelle `cpp`, le préprocesseur qui effectue de la substitution de texte (`#define`, `#include`, macros, ...) et génère le code `C` à compiler, portant l'extension `.i` (`prog.i`).
2. **Compilation assembleur: ** `gcc` compile le code C en code assembleur, portant l'extension `.s` (`prog.s`).
3. **Compilation code objet: ** `gcc` appelle `as`, l'assembleur, qui compile le code assembleur en code machine (code objet) portant l'extension `.o` (`prog.o`).
4. **Édition des liens: ** `gcc` appelle `ld`, l'éditeur de liens, qui lie le code objet avec les librairies et d'autres codes objet pour produire l'exécutable final (`prog`).
Les différents codes intermédiaires sont effacés.
# Génération d'un exécutable (3/N)
## Plusieurs fichiers sources
![Étapes de génération, plusieurs fichiers.](figs/compilation_plusieurs.svg){#fig:compilation_plusieurs width=100%}
# Génération d'un exécutable (4/N)
::: Main
## `main.c`
```C
#include <stdio.h>
#include "sum.h"
int main() {
int tab[] = {1, 2, 3, 4};
printf("sum: %d\n", sum(tab, 4));
return 0;
}
```
:::
:::::::::::::: {.columns}
::: {.column width="45%"}
## `sum.h`
```C
#ifndef _SUM_H_
#define _SUM_H_
int sum(int tab[], int n);
#endif
```
:::
::: {.column width="55%"}
## `sum.c`
```C
#include "sum.h"
int sum(int tab[], int n) {
int s = 0;
for (int i = 0; i < n; i++) {
s += tab[i];
}
return s;
}
```
:::
::::::::::::::
# Génération d'un exécutable (4/N)
La compilation séparée se fait en plusieurs étapes.
## Compilation séparée
1. Générer séparément les fichiers `.o` avec l'option `-c`.
2. Éditer les liens avec l'option `-o` pour générer l'exécutable.
## Exemple
- Création des fichiers objets, `main.o` et `sum.o`
```bash
$ gcc -Wall -Wextra -std=c11 -c main.c
$ gcc -Wall -Wextra -std=c11 -c sum.c
```
- Édition des liens
```bash
$ gcc main.o sum.o -o prog
```
# Préprocesseur (1/N)
## Généralités
- Première étape de la chaîne de compilation.
- Géré automatiquement par `gcc` ou `clang`.
- Lit et interprète certaines directives:
1. Les commentaires (`//`{.C} et `/* ... */`{.C}).
2. Les commandes commençant par `#`{.C}.
- Le préprocesseur ne compile rien, mais subtitue uniquement du texte.
## La directive `define`{.C}
- Permet de définir un symbole:
```C
#define PI 3.14159
#define _SUM_H_
```
- Permet de définir une macro.
```C
#define NOM_MACRO(arg1, arg2, ...) [code]
```
# Préprocesseur (2/N)
## La directive `include`{.C}
- Permet d'inclure un fichier.
- Le contenu du fichier est ajouté à l'endroit du `#include`{.C}.
- Inclusion de fichiers "globaux" ou "locaux"
```C
#include <file.h> // LD_LIBRARY_PATH
#include "other_file.h" // local path
```
- Les inclusions multiples peuvent poser problème: définitions multiples. Les headers commencent par:
```C
#ifndef _VAR_
#define _VAR_
/*
commentaires
*/
#endif
```
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