Mode
Slides
Presentation
Remote control
Send
Listen
Press F11 to switch to fullscreen.
C: Cours 4
1
Appels
2
Pile
3
Pile
4
Pile
5
Allocation
6
Allocation
7
Mémoire
8
Stack overflow
9
Tas (heap)
10
malloc
11
5 min
12
double
13
14
float
15
16
int
17
char
18
inttypes.h
19
Fixed-point
20
and, or, xor
21
bit shift
22
cast
23
Tableaux 2D
24
Examen
25
26
27
Semaine 4
Pile d'exécution, nombres,
précision, tableaux 2d
SSIE Programmation en C, Thomas Lochmatter, 2019
1

Trajectoire GPS

	int lireLigne(char * ligne, struct GpsPoint * point) {
		...
	}

	int lireFichier(char * fichier, struct GpsPoint * tableau, int longueur) {
		...
		int success = lireLigne(ligne, tableau + i);
		...
	}

	int main(int argc, char * argv[]) {
		struct GpsPoint points[1000];
		int nbPoints = lireFichier("ulagan.csv", points, 1000);
		...
		return 0;
	}
2
main temps lireFichier lireLigne calculerDistance démarrage du programme fin ... sqrt
3
main lireFichier lireLigne démarrage du programme Pile au temps T Variables de la fonction main Variables de la fonction lireFichier Variables de la fonction lireLigne Par convention, il s'agit d'une pile inverséequi commence en haut et grandit vers le bas.
4
main temps lireFichier lireLigne calculerDistance démarrage du programme fin ... sqrt points[1000]
5
main remplirSommet afficherSommet struct Sommet sommet main creerSommet afficherSommet place prévu pour la valeur de retour copie! Allocation dans main, passer un pointeur Allocation dans la fonction, et retourner une copie
6
	void rempliStructure(struct Sommet * sommet) {
		sommet->nom = ...;
		sommet->latitude = ...;
		...
	}

	int main(int argc, char * argv[]) {
		// Allouer de la mémoire
		struct Sommet sommet;

		// Passer un pointeur
		remplirSommet(&sommet);

		...

		return 0;
	}
En C, c'est la fonction qui appelle (caller) qui alloue la mémoire — et on passe des pointeurs.
7
Mémoire d'un programme lors de l'exécution Pile (stack) .text Code machine à exécuter char * text = "Hello world!\n" Constantes Variables globales initialisées Variables globales non-initialisées .rodata .data .bss double pi = 3.14159265358979; int count;
8
Stack overflow .text Code machine à exécuter char * text = "Hello world!\n" Pile (stack) Constantes Variables globales initialisées Variables globales non-initialisées .rodata .data .bss double pi = 3.14159265358979; int count;
9
Pile (stack) .text Code machine à exécuter char * text = "Hello world!\n"; Constantes Variables globales initialisées Variables globales non-initialisées .rodata .data .bss double pi = 3.14159265358979; int count; Tas (heap) pour l'allocation dynamique de mémoire malloc, free cf. semaine 7
10
	#include <stdlib.h>

	int main(int argc, char * argv[]) {
		// Allocation sur le tas (heap)
		struct Sommet * sommet = malloc(1000 * sizeof (struct Sommet));

		...

		// Libérer la mémoire
		free(sommet);
		return 0;
	}
Pour les stratégies d'allocation et libération, voir le cours 7.
11

5 min

Nombres
Qu'est-ce que vous connaissez des cours de l'année passée?
12

double

Très pratique. Haute précision.

8 bytes = 64 bits

1 bit signe
11 bit exposant
52 bit fraction

Précision: 2-53

Résolution de 5 nm sur la circonférence de la terre!

13
double x = 20 / 100;
= 0 (division de deux entiers)
double x = 20.0 / 100.0;
= 0.2 (division de deux doubles)
14

float

Etre prudent.

4 bytes = 32 bits

1 bit signe
8 bit exposant
23 bit fraction

Précision: 2-24

Résolution de 2 m sur la circonférence de la terre!

224 = 16'777'216 et la circonférence de la terre = 40'000'000 m

15

Perte de précision

		float a = 12.3;
		float b = a + 100;
		float c = b - 100;
	
  a = 12.30000019
- c = 12.30000305
-----------------
       0.00000286
	
16

int

Au minimum 2 bytes (16 bits),
souvent 4 bytes (32 bits),
dont 1 bit pour le signe.

de −231 à +231 - 1
de −2'147'483'648 à +2,147,483,647
de −2 milliards à +2 milliards
de −2 GiB à +2 GiB
pour les entiers 32 bit
17

char

Entier 8 bit (1 byte),
dont 1 bit pour le signe.

de −27 à +27 - 1
de −128 à +127
18

inttypes.h

	#include <inttypes.h>

	int8_t entier_8bits_avec_signe = 0;
	int16_t entier_16bits_avec_signe = 0;
	int32_t entier_32bits_avec_signe = 0;
	int64_t entier_64bits_avec_signe = 0;

	uint8_t entier_8bits_sans_signe = 0;
	uint16_t entier_16bits_sans_signe = 0;
	uint32_t entier_32bits_sans_signe = 0;
	uint64_t entier_64bits_sans_signe = 0;
19

Fixed-point integer

uint32_t (32 bits sans signe)

résolution de 9.33 mm sur la circonférence de la terre!

10 mm ...
0 1 2 3 4 5 6 7 8 ...
20

Operations sur le bits

a
7 6 5 4 3 2 1 0
0 0 1 1 0 1 0 1 53
b
0 1 1 0 0 1 1 0 102
a & b (a ET b)
0 0 1 0 0 1 0 0 36
a | b (a OU b)
7 6 5 4 3 2 1 0
0 1 1 1 0 1 1 1 119
a ^ b (a XOR b)
0 1 0 1 0 0 1 1 83
~a (NOT a)
1 1 0 0 1 0 1 0 202
21

Bit shift

a
7 6 5 4 3 2 1 0
0 0 1 1 0 1 0 1 53
a << 2 (2 bits vers la gauche)
1 1 0 1 0 1 0 0 212
a >> 2 (2 bits vers la droite)
0 0 0 0 1 1 0 1 13

Notation binaire

uint8_t a = 0b00110101;

Notation hexadécimale

uint8_t a = 0x35;

Notation décimale

uint8_t a = 53;

Toujours utiliser des entiers sans signe (unsigned ..., uint...).
22

Changer d'un type à l'autre

	// Implicitement (implicit cast)
	int entier = 10;
	double valeur = entier;

	// Explicitement (explicit cast)
	double valeur = 12.4;
	int entier = (int) valeur;
23

Tableaux 2D

	// Calculer l'indexe d'une case (x, y)
	int i = y * 10 + x;

	// Calculer (x, y) d'un indexe
	int x = i % 10;
	int y = i / 10;
24

Examen

  • A 13:15, pas de cours
  • En salle d'exercices
  • Sur un des PC en salle, ou sur votre propre PC
  • Accès a tout (mais pas de communication!)
  • 20 % de la note du cours entier
  • 3 à 4 exercices (du style des exercices faites)
  • Dernières questions: lundi soir à partir de 16:00 en salle d'exercices
25

Documentation

Call stack sur Wikipedia

Stack overflow sur Wikipedia

Data segment sur Wikipedia

double sur Wikipedia

float sur Wikipedia

int sur Wikipedia

inttypes.h sur Wikipedia

Bitwise operations in C sur Wikipedia

26

Inspecter un exécutable ou un processus

Afficher les sections d'un exécutable:

$$ objdump -s mon-programme

Afficher les segments de la mémoire lors de l'exécution:

$$ pmap -x PID

Afficher les processus avec leurs PID:

$$ ps ux

Afficher la PID d'un programme:

$$ pgrep mon-programme
27