
En programmation informatique , une chaîne est traditionnellement une séquence de caractères , soit sous forme de constante littérale , soit sous forme de variable . Cette dernière peut permettre à ses éléments d'être mutés et à la longueur de changer, ou elle peut être fixe (après création). Une chaîne est généralement considérée comme un type de données et est souvent implémentée sous la forme d'une structure de données de tableau d' octets (ou de mots ) qui stocke une séquence d'éléments, généralement des caractères, en utilisant un codage de caractères . Une chaîne peut également désigner des tableaux plus généraux ou d'autres types et structures de données de séquence (ou de liste ).
Selon le langage de programmation et le type de données précis utilisé, une variable déclarée comme étant une chaîne peut soit provoquer l'allocation statique du stockage en mémoire pour une longueur maximale prédéterminée, soit utiliser une allocation dynamique pour lui permettre de contenir un nombre variable d'éléments.
Lorsqu'une chaîne apparaît littéralement dans le code source , elle est appelée chaîne littérale ou chaîne anonyme.
Dans les langages formels , utilisés en logique mathématique et en informatique théorique , une chaîne est une séquence finie de symboles choisis dans un ensemble appelé alphabet .
But
L'un des principaux objectifs des chaînes de caractères est de stocker du texte lisible par l'homme, comme des mots et des phrases. Les chaînes de caractères sont utilisées pour communiquer des informations d'un programme informatique à l'utilisateur du programme. Un programme peut également accepter une entrée de chaîne de caractères de la part de son utilisateur. De plus, les chaînes de caractères peuvent stocker des données exprimées sous forme de caractères mais qui ne sont pas destinées à la lecture humaine.
Exemples de chaînes et leurs objectifs :
- Un message comme «
file upload complete» est une chaîne que le logiciel affiche aux utilisateurs finaux . Dans le code source du programme , ce message apparaîtra probablement sous la forme d'une chaîne littérale . - Texte saisi par l'utilisateur, comme «
I got a new job today» comme mise à jour de statut sur un service de médias sociaux . Au lieu d'une chaîne littérale, le logiciel stockerait probablement cette chaîne dans une base de données . - Données alphabétiques, comme «
AGATGCCGT» représentant les séquences d'acide nucléique de l'ADN . - Paramètres ou paramètres informatiques, tels que «
?action=edit» comme chaîne de requête d'URL . Souvent, ils sont destinés à être quelque peu lisibles par l'homme, bien que leur objectif principal soit de communiquer avec les ordinateurs.
Le terme chaîne peut également désigner une séquence de données ou d'enregistrements informatiques autres que des caractères — comme une « chaîne de bits » — mais lorsqu'il est utilisé sans qualification, il fait référence à des chaînes de caractères.
Histoire
L'utilisation du mot « chaîne » pour désigner tout élément disposé en ligne, en série ou en succession remonte à des siècles. Dans la composition typographique du XIXe siècle, les compositeurs utilisaient le terme « chaîne » pour désigner une longueur de caractères imprimés sur du papier ; la chaîne était mesurée pour déterminer le salaire du compositeur.
L'utilisation du mot « chaîne » pour signifier « une séquence de symboles ou d'éléments linguistiques dans un ordre défini » est issue des mathématiques, de la logique symbolique et de la théorie linguistique pour parler du comportement formel des systèmes symboliques, en laissant de côté la signification des symboles.
Par exemple, le logicien CI Lewis écrivait en 1918 :
Un système mathématique est un ensemble de chaînes de signes reconnaissables dans lequel certaines chaînes sont prises initialement et le reste est dérivé de celles-ci par des opérations effectuées selon des règles indépendantes de toute signification attribuée aux signes. Le fait qu'un système soit constitué de « signes » plutôt que de sons ou d'odeurs n'a aucune importance.
Selon Jean E. Sammet , « le premier langage réaliste de gestion de chaînes et de recherche de motifs » pour les ordinateurs était COMIT dans les années 1950, suivi par le langage SNOBOL au début des années 1960.
Types de données de chaîne
Un type de données de type chaîne est un type de données basé sur l'idée d'une chaîne formelle. Les chaînes sont un type de données si important et utile qu'elles sont implémentées dans presque tous les langages de programmation . Dans certains langages, elles sont disponibles sous forme de types primitifs et dans d'autres sous forme de types composites . La syntaxe de la plupart des langages de programmation de haut niveau permet à une chaîne, généralement entre guillemets, de représenter une instance d'un type de données de type chaîne ; une telle méta-chaîne est appelée littéral ou littéral de chaîne .
Longueur de la chaîne
Bien que les chaînes formelles puissent avoir une longueur finie arbitraire, la longueur des chaînes dans les langages réels est souvent limitée à un maximum artificiel. En général, il existe deux types de types de données de chaîne : les chaînes de longueur fixe , qui ont une longueur maximale fixe à déterminer au moment de la compilation et qui utilisent la même quantité de mémoire que ce maximum soit nécessaire ou non, et les chaînes de longueur variable , dont la longueur n'est pas fixée arbitrairement et qui peuvent utiliser des quantités de mémoire variables en fonction des besoins réels au moment de l'exécution (voir Gestion de la mémoire ). La plupart des chaînes dans les langages de programmation modernes sont des chaînes de longueur variable. Bien entendu, même les chaînes de longueur variable sont limitées en longueur, par la taille de la mémoire informatique disponible . La longueur de la chaîne peut être stockée sous la forme d'un entier séparé (ce qui peut imposer une autre limite artificielle à la longueur) ou implicitement via un caractère de terminaison, généralement une valeur de caractère avec tous les bits à zéro comme dans le langage de programmation C. Voir également « Terminé par un caractère nul » ci-dessous.
Codage des caractères
Les types de données de chaîne ont historiquement alloué un octet par caractère et, bien que le jeu de caractères exact varie selon les régions, les codages de caractères étaient suffisamment similaires pour que les programmeurs puissent souvent s'en sortir en ignorant cela, car les caractères qu'un programme traitait spécialement (comme le point, l'espace et la virgule) étaient au même endroit dans tous les codages qu'un programme rencontrerait. Ces jeux de caractères étaient généralement basés sur ASCII ou EBCDIC . Si du texte dans un codage était affiché sur un système utilisant un codage différent, le texte était souvent déformé , bien que souvent quelque peu lisible et certains utilisateurs d'ordinateurs ont appris à lire le texte déformé.
Les langages logographiques tels que le chinois , le japonais et le coréen (collectivement appelés CJK ) nécessitent bien plus que 256 caractères (la limite d'un codage d'un octet par caractère sur 8 bits) pour une représentation raisonnable. Les solutions normales consistaient à conserver les représentations sur un seul octet pour l'ASCII et à utiliser des représentations sur deux octets pour les idéogrammes CJK . L'utilisation de ces représentations avec le code existant entraînait des problèmes de correspondance et de découpage des chaînes, dont la gravité dépendait de la manière dont le codage des caractères était conçu. Certains codages tels que la famille EUC garantissent qu'une valeur d'octet dans la plage ASCII ne représentera que ce caractère ASCII, ce qui rend le codage sûr pour les systèmes qui utilisent ces caractères comme séparateurs de champs. D'autres codages tels que ISO-2022 et Shift-JIS n'offrent pas de telles garanties, ce qui rend la correspondance sur les codes d'octets dangereuse. Ces codages n'étaient pas non plus « auto-synchronisés », de sorte que la localisation des limites des caractères nécessitait de revenir au début d'une chaîne, et le collage de deux chaînes ensemble pouvait entraîner la corruption de la deuxième chaîne.
Unicode a quelque peu simplifié la situation. La plupart des langages de programmation disposent désormais d'un type de données pour les chaînes Unicode. Le format de flux d'octets préféré d'Unicode, UTF-8, est conçu pour ne pas présenter les problèmes décrits ci-dessus pour les anciens codages multi-octets. UTF-8, UTF-16 et UTF-32 nécessitent que le programmeur sache que les unités de code de taille fixe sont différentes des « caractères », la principale difficulté actuellement réside dans les API mal conçues qui tentent de masquer cette différence (UTF-32 rend les points de code de taille fixe, mais ce ne sont pas des « caractères » en raison de la composition des codes).
Implémentations
Certains langages, comme C++ , Perl et Ruby , permettent normalement de modifier le contenu d'une chaîne après sa création ; on les appelle chaînes mutables . Dans d'autres langages, comme Java , JavaScript , Lua , Python et Go , la valeur est fixe et une nouvelle chaîne doit être créée si une modification doit être apportée ; on les appelle chaînes immuables . Certains de ces langages avec des chaînes immuables fournissent également un autre type qui est mutable, comme Java et .NET , le StringBuilderJava thread-safe StringBufferet le Cocoa
NSMutableString . L'immuabilité présente à la fois des avantages et des inconvénients : bien que les chaînes immuables puissent nécessiter la création inefficace de nombreuses copies, elles sont plus simples et complètement thread-safe .
Les chaînes sont généralement implémentées sous forme de tableaux d'octets, de caractères ou d'unités de code, afin de permettre un accès rapide aux unités individuelles ou aux sous-chaînes, y compris les caractères lorsqu'ils ont une longueur fixe. Quelques langages tels que Haskell les implémentent plutôt sous forme de listes chaînées .
Certains langages, tels que Prolog et Erlang , évitent d'implémenter un type de données de chaîne dédié, adoptant à la place la convention de représentation des chaînes sous forme de listes de codes de caractères.
Représentations
Les représentations de chaînes dépendent fortement du choix du répertoire de caractères et de la méthode de codage des caractères. Les implémentations de chaînes plus anciennes ont été conçues pour fonctionner avec le répertoire et le codage définis par ASCII ou des extensions plus récentes comme la série ISO 8859. Les implémentations modernes utilisent souvent le vaste répertoire défini par Unicode ainsi qu'une variété de codages complexes tels que UTF-8 et UTF-16.
Le terme chaîne d'octets désigne généralement une chaîne d'octets à usage général, plutôt que des chaînes de caractères uniquement (lisibles), des chaînes de bits ou autre. Les chaînes d'octets impliquent souvent que les octets peuvent prendre n'importe quelle valeur et que toutes les données peuvent être stockées telles quelles, ce qui signifie qu'aucune valeur ne doit être interprétée comme une valeur de terminaison.
La plupart des implémentations de chaînes sont très similaires aux tableaux de longueur variable , les entrées stockant les codes de caractères des caractères correspondants. La principale différence est que, avec certains codages, un seul caractère logique peut occuper plusieurs entrées dans le tableau. Cela se produit par exemple avec UTF-8, où les codes simples ( points de code UCS ) peuvent occuper entre un et quatre octets, et les caractères simples peuvent occuper un nombre arbitraire de codes. Dans ces cas, la longueur logique de la chaîne (nombre de caractères) diffère de la longueur physique du tableau (nombre d'octets utilisés). UTF-32 évite la première partie du problème.
Terminé par zéro
La longueur d'une chaîne peut être stockée implicitement en utilisant un caractère de terminaison spécial ; il s'agit souvent du caractère nul (NUL), dont tous les bits sont à zéro, une convention utilisée et perpétuée par le langage de programmation populaire C. [ Par conséquent, cette représentation est communément appelée chaîne C. Cette représentation d'une chaîne de n caractères prend n + 1 espace (1 pour le terminateur) et est donc une structure de données implicite .
Dans les chaînes terminées, le code de fin n'est pas un caractère autorisé dans aucune chaîne. Les chaînes avec un champ de longueur n'ont pas cette limitation et peuvent également stocker des données binaires arbitraires .
Un exemple d'une chaîne terminée par un caractère nul stockée dans un tampon de 10 octets , avec sa représentation ASCII (ou UTF-8 plus moderne) sous forme de nombres hexadécimaux de 8 bits est :
F |
R |
A |
N |
K
|
NUL | k
|
e
|
f
|
w
| ||||||||||||||||||||
| 46 16 | 52 16 | 41 16 | 4E 16 | 4B 16 | 00 16 | 6B 16 | 65 16 | 66 16 | 77 16
La longueur de la chaîne dans l'exemple ci-dessus, " Terminé par octet et par bitL'utilisation d'un octet spécial autre que null pour terminer les chaînes est historiquement apparue à la fois dans le matériel et dans les logiciels, bien que parfois avec une valeur qui était également un caractère d'impression. De manière assez similaire, les machines de « traitement de données » comme l' IBM 1401 utilisaient un bit de marque de mot spécial pour délimiter les chaînes à gauche, là où l'opération commencerait à droite. Ce bit devait être clair dans toutes les autres parties de la chaîne. Cela signifiait que, bien que l'IBM 1401 ait un mot de sept bits, presque personne n'a jamais pensé à l'utiliser comme une fonction et à remplacer l'affectation du septième bit pour (par exemple) gérer les codes ASCII. Les premiers logiciels de micro-ordinateurs s'appuyaient sur le fait que les codes ASCII n'utilisaient pas le bit de poids fort et le définissaient pour indiquer la fin d'une chaîne. Il devait être réinitialisé à 0 avant la sortie. Préfixe de longueurLa longueur d'une chaîne peut également être stockée explicitement, par exemple en préfixant la chaîne avec la longueur sous forme de valeur d'octet. Cette convention est utilisée dans de nombreux dialectes Pascal ; par conséquent, certaines personnes appellent une telle chaîne une chaîne Pascal ou P-string . Le stockage de la longueur de la chaîne sous forme d'octets limite la longueur maximale de la chaîne à 255. Pour éviter de telles limitations, les implémentations améliorées des P-strings utilisent des mots de 16, 32 ou 64 bits pour stocker la longueur de la chaîne. Lorsque le champ de longueur couvre l' espace d'adressage , les chaînes ne sont limitées que par la mémoire disponible . Si la longueur est limitée, elle peut être codée dans un espace constant, généralement un mot machine, ce qui conduit à une structure de données implicite , prenant un espace n + k , où k est le nombre de caractères dans un mot (8 pour l'ASCII 8 bits sur une machine 64 bits, 1 pour l'UTF-32/UCS-4 32 bits sur une machine 32 bits, etc.). Si la longueur n'est pas limitée, le codage d'une longueur n prend un espace log( n ) (voir code de longueur fixe ), donc les chaînes préfixées par une longueur sont une structure de données succincte , codant une chaîne de longueur n dans un espace log( n ) + n . Dans ce dernier cas, le champ de préfixe de longueur lui-même n'a pas de longueur fixe, par conséquent les données de chaîne réelles doivent être déplacées lorsque la chaîne augmente de telle sorte que le champ de longueur doit être augmenté. Voici une chaîne Pascal stockée dans un tampon de 10 octets, avec sa représentation ASCII / UTF-8 :
|
