Semaine 3
Structures, pointeurs,
passage par référence
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
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
systèmes 32-bit
28 bytes sur les
systèmes 64-bit
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