Aller au contenu principal

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 :

cc
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.

cc
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 :

cc
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é.