Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Philosophie des chaînes de caractères

Comment représenter une chaîne de caractères comme “chouette” ?

Pleins représentations possibles

Pointeur vers une chaîne finissant par un caractère sentinelle

Comme vu, c’est le choix utilisé en C. C’est aussi le choix pour les chaînes bruts comme "chouette" en C++. C’est aussi le cas dans les langages Zig, Objective-C, assembleur, etc. Bien que Rust fait différemment, Rust le propose aussi pour pouvoir discuter avec les librairies C, cf. https://doc.rust-lang.org/std/ffi/struct.CStr.html.

"chouette"

chouette\0



spointer

Pointeur vers structure longueur + la chaîne à suivre

Il y a longtemps… c’était utilisé en Pascal. On mettait la longueur sur un octet puis les caractères.

8chouette



pointer

Structure contenant un pointeur vers une chaîne + la longueur

chouette



8pointer

C’est utilisé en Rust avec le type &str (référence sur str) qui est ce qu’on appelle un pointeur gras. Le pointeur est gras car il contient des informations en plus : ici le nombre d’octets. En Rust, accéder au i-ème caractère n’est pas en temps constant ! Pourquoi ? Parce que Rust gère UTF-8 et veut :

  • garantir que la chaîne soit toujours UTF8-valide
  • montrer que les fonctions couteuses ont une syntaxe horrible… donc pas de s[3] = 'a'.

ch🌿ette



7pointer

Le choix Python

Python est radical. Tout est pointeur en Python. Pointeur sur un objet compliqué… Et une chaîne de caractère est immutable, gère le UTF-8 et offre un accès direct lecture/écriture aux caractères en O(1). Chaque objet string ont des cases de la même taille, choisie en fonction du caractère qui prend le plus de place. Un emoji ? Tu paies le prix partout ! Voir https://github.com/python/cpython/blob/main/Include/cpython/unicodeobject.h.

… 3ch🌿…



pointer

Chaîne de caractères à la vecteur

En C++

En plus des char * hérité du C, on a le type string de #include <string> qui est un vecteur :

chouette\0abgaaaa



spointersize = 8capacity = 16

On peut tout faire : concaténer, modifier un caractère (mais aucune garantie que ce soit UTF-8 valide !) juste en faisant s[1] = 'b'.

En Rust

C’est similaire au C++. Mais le langage ne permet pas de modifier simplement un caractère, afin de garantir l’UTF-8-validité !

Comment est-ce fait en Scala ? Haskell ? Lisp ? Javascript ? Java ?

Discussions

Bref, Pour le bas niveau, on préfère un pointeur unique avec sentinelle :

  • Ca prend moins de mémoire. Par exemple “abc” prend 4 octets VS 3 octets + une longueur codée sur 8 octets.
  • C’était plus uniforme. Sur combien d’octets coder la longueur ?
  • Les fonctions manipulent uniquement un pointeur.

Mais il y a des problèmes de :

  • sécurité
  • d’efficacité

Aller plus loin