Mode
Slides
Presentation
Remote control
Send
Listen
Press F11 to switch to fullscreen.
C: Cours 3
1
2
Crible
3
Crible
4
Pointeur
5
Pointeur
6
NULL
7
Segfault
8
Read-only
9
Debug
10
Structures
11
Structures
12
Tableaux
13
Mémoire
14
Pointeur
15
Fonctions
16
17
Semaine 3
Structures, pointeurs,
passage par référence
SSIE Programmation en C, Thomas Lochmatter, 2019
1
	// Tableau de 5 cases x 4 bytes = 20 bytes
	int visiteurs[] = {67, 55, 33, 41, 48};

	// Chaine de caractères
	char * message = "$GPGGA,092750...";
2

Crible d'Ératosthène

pour trouver les nombres premiers
Cliquez sur la première case libre (2, 3, 5, ...) pour faire avancer l'algorithme, ou sur la case 0 pour recommencer.
3
Crible: temps d'exécution C0.070 s Python2.600 s Perl4.200 s JavaScript¹(a) 0.086 s(b) 0.310 s Pythonavec module C0.070 s 35x plus lentsur les tableauxd'entiers 1. Démarrage: 0.510 s, implémentations avec Uint8Array (a) et Array (b)
4
	// Tableau = pointeur sur la première case
	int visiteurs[] = {67, 55, 33, 41, 48};

	// Pointeur sur la case 3
	int * case3 = visiteurs + 3;

	// Accéder à la valeur de la case 3
	int valeur3 = visiteurs[3];
	int valeur3 = *(visiteurs + 3);
	int valeur3 = *case3;
	int valeur3 = case3[0];
5
	int total = 244;

	// Créer un pointeur
	int * pointeurTotal = &total;

	// Modifier la valeur
	*pointeurTotal = 250;
	pointeurTotal[0] = 250;

	// Accéder à la valeur
	printf("Valeur: %d.\n", *pointeurTotal);
Le préfix & fournit l'adresse d'une variable. Le préfix * suit un pointer pour accéder à la valeur.
6

NULL

	// Pointeur qui pointe nulle part
	int * pointeurTotal = NULL;

	// Exemple: strchr ne trouve rien
	char * message = "$GPGGA/092750...";
	char * virgule = strchr(message, ',');
	if (virgule == NULL) {
		printf("Message non conforme.");
		return 0;
	}
7

Segmentation Fault (Bus Error)

	// Accéder à une case loin en dehors d'un tableau
	int tableau[10];
	tableau[1000000] = 0;

	// Accéder à un pointeur NULL (ou proche de NULL)
	char * virgule = NULL;
	char apresVirgule = virgule[1];
Si on modifie une case pas loin des bords du tableau, le programme ne plante pas directement.
8
	// Texte (string constant) dans la zone de mémoire "rodata"
	char * texte1 = "Texte verrouille.";

	// Modification produit un segmentation fault
	texte1[0] = 't';

	// Mieux
	const char * texte1 = "Texte verrouille.";

	// Texte sur la stack
	char texte2[] = "Texte modifiable sur la stack.";
9

Debogage de Segmentation Fault

	char * virgule = ...;
	printf("Je suis à la position A.\n");
	printf("Virgule est %p.\n", virgule);

	int heure = atoi(virgule + 1);
	printf("Je suis à la position B.\n");

	*virgule = 0;
	printf("Je suis à la position C.\n");

Ne pas oublier les \n!

Sinon le texte à afficher reste dans un buffer interne.

10

Types composés, structures

	struct Sommet {
		char * nom;
		double latitude;
		double longitude;
		float altitude;
	};
nom:
latitude:
longitude:
altitude:
Il y a un ; après la définition de la structure!
11
...

int main(int argc, char * argv[]) {
	// Créer et remplir une variable
	struct Sommet cervin;
	cervin.nom = "Matterhorn";
	cervin.latitude = 45.97639
	cervin.longitude = 7.65833;;
	cervin.altitude = 4478;

	// ou créer et remplir en même temps
	struct Sommet cervin = {"Matterhorn", 45.97639, 7.65833, 4478};

	// Affiche "Matterhorn: 4478 m alt."
	printf("%s: %0.0f m alt.\n", cervin.nom, cervin.altitude);

	return 0;
}
nom: Matterhorn
latitude: 45.97639
longitude: 7.65833
altitude: 4478
12
...

int main(int argc, char * argv[]) {
	struct Sommet sommets[10];

	sommets[0].nom = "Matterhorn";
	sommets[0].latitude = 45.97639;
	sommets[0].longitude = 7.65833;
	sommets[0].altitude = 4478;

	sommets[1].nom = "Weisshorn";
	sommets[1].latitude = 46.101667;
	sommets[1].longitude = 7.716111;
	sommets[1].altitude = 4506;

	...

	return 0;
}
nom: Matterhorn
latitude: 45.97639
longitude: 7.65833
altitude: 4478
nom: Weisshorn
latitude: 46.101667
longitude: 7.716111
altitude: 4506
13

Structures en mémoire

	struct Sommet cervin;
    cervin.nom = "Matterhorn";
    cervin.latitude = 45.97639;
    cervin.longitude = 7.65833;
    cervin.altitude = 4478;

    // Taille de la structure
    int taille = sizeof (struct Sommet);
Taille
24 bytes sur les
systèmes 32-bit
28 bytes sur les
systèmes 64-bit
14
	...

    // Pointeur sur cervin
    struct Sommet * sommet = &cervin;

    // Accéder à la latitude
    sommet->latitude = 45.97639;
    sommet[0].latitude = 45.97639;
    (*sommet).latitude = 45.97639;
15

Appeler une fonction avec une structure

	...

	void afficheSommet(struct Sommet * sommet) {
		printf("Sommet %s\n", sommet->nom);
		printf("Latitude: %0.5f°\n", sommet->latitude);
		printf("Longitude: %0.5f°\n", sommet->longitude);
		printf("Altitude: %0.0f m alt.\n", sommet->altitude);
	}

	int main(int argc, char * argv[]) {
		struct Sommet cervin = {"Matterhorn", 45.97639, 7.65833, 4478};
		afficheSommet(&cervin);
		return 0;
	}
On passe la structure par référence ou par adresse! La fonction peut modifier le contenu de la structure.
16

Documentation

Pointer sur Wikipedia

Null pointer sur Wikipedia

Segmentation fault sur Wikipedia

Struct sur Wikipedia

17