Codage et mémoire
Progression
#Codage binaire et mémoire
Travailler en C impose de visualiser la mémoire. Chaque type correspond à une représentation binaire précise ; négliger ce détail est la source de bogues subtils. Ce chapitre explore l’endianness, l’alignement et la manière dont les nombres sont codés.
#1. Endianness et représentation des entiers
Les architectures little endian stockent l’octet de poids faible en premier, les big endian font l’inverse. Utilisez le bout de code suivant pour détecter l’endianness de votre machine :
1int is_little_endian(void) {2 unsigned int x = 1;3 return *((unsigned char *)&x) == 1;4}
Nous disséquons ensuite la représentation des entiers signés (complément à deux) et non signés. L’objectif est de comprendre pourquoi un dépassement (overflow
) sur un type signé déclenche un comportement indéfini tandis qu’un dépassement sur un type non signé sature modulo 2^n. Les exercices demandent de convertir manuellement quelques nombres en binaire pour ancrer ces connaissances.
#2. Alignement et disposition des structures
Les processeurs accèdent à la mémoire plus efficacement lorsque les données sont alignées. Nous analysons une structure contenant des champs de tailles différentes, puis nous utilisons sizeof
et _Alignof
pour vérifier la disposition réelle en mémoire. Modifier l’ordre des champs permet souvent de réduire le padding. Les bitfields
complètent l’arsenal lorsqu’il faut packer des drapeaux dans un entier ; nous montrons comment modéliser les bits d’un flottant IEEE‑754 avec cette technique tout en insistant sur la portabilité limitée.
1typedef struct {2 uint32_t mantissa:23;3 uint32_t exponent:8;4 uint32_t sign:1;5} float_bits;
#3. Lecture brute et sérialisation
Une bonne pratique consiste à écrire des fonctions utilitaires pour visualiser la mémoire :
1void dump_hex(const void *buffer, size_t len) {2 const unsigned char *bytes = buffer;3 for (size_t i = 0; i < len; ++i) {4 printf("%02X ", bytes[i]);5 if ((i + 1) % 16 == 0) puts("");6 }7 puts("");8}
Nous implémentons une conversion vers le binaire (char repr[33]
) et nous écrivons un sérialiseur réseau qui utilise htonl
/htons
pour garantir l’endianness. L’atelier final demande de sérialiser une structure Message
dans un tampon et de la reconstruire côté client en vérifiant que l’ordre des octets est respecté.