Programmation/Types
Dans la plupart des langages de programmation il est possible d'attribuer arbitrairement aux variables des types pour – entre autres – déterminer la nature des données qu'elle peut contenir et la manière dont elles sont enregistrées et traitées par le système. Concrètement le type d'un élément influe sur la taille que le compilateur ou l'interpréteur lui allouera en mémoire ; et les opérations qui ne devraient pas être permises si la syntaxe du langage était respectée. Il est par exemple rare qu'un vérificateur d'erreurs ne se manifeste pas lorsqu'on tente de multiplier un « nombre » avec une « lettre ». Si à la base la « lettre » et le « nombre » sont tous deux une « succession de 0 et de 1 », en pratique ce à quoi on fait correspondre ces « successions de 0 et de 1 » rend une telle opération vide de sens.
Selon le degré d'abstraction du langage, il peut être soit indispensable de préciser le type de la variable lors de sa création, ou bien cela peut ne pas être nécessaire, le langage déterminant automatiquement le type de la variable à sa création, et le modifiant de manière dynamique lorsque la valeur contenue par la variable dépasse la quantité de mémoire correspondant au type précédent.
Types de données simples
[modifier | modifier le wikicode]Un type simple est une simple valeur dont le stockage se fait le plus souvent sur un nombre fixe d'octets. La plupart sont des valeurs numériques. Dans un langage particulier, chaque type peut avoir des variantes qui diffère par la gestion du signe (présentation), les limites autorisées (selon la taille occupé par une valeur de ce type).
Entier
[modifier | modifier le wikicode]L'entier est le type numérique le plus simple : il stocke une valeur entière. Par exemple : 1, 2, 145, 36000720.
Les bornes de valeurs acceptées par ce type dépend de la taille attribué par le langage utilisé, et par la présence d'un signe ou non.
Exemples :
- Un entier de 8 bits non signé accepte donc (soit 256) valeurs comprises entre 0 et 255 inclus,
- Un entier de 32 bits signé accepte (soit 4294967296) valeurs comprises entre -2147483648 et +2147483647 inclus.
La gestion des nombres signés nécessite de définir comment gérer les nombres négatifs. Plusieurs possibilités ont été utilisées :
Représentation « signe + magnitude »
[modifier | modifier le wikicode]Sur le nombre de bits qu'occupe le nombre entier, un bit (généralement le premier ou le dernier, selon l'implémentation) est assigné au signe. Le 0 est utilisé pour un nombre positif, le 1 pour un nombre négatif (ou vice-versa).
Exemples pour des nombres signés sur 8 bits, on peut avoir la représentation suivante :
- +5 =>
0 0000101
- -5 =>
1 0000101
Le zéro n'ayant pas de signe, son bit de signe peut valoir indifféremment 0 ou 1. Il a donc deux représentations possibles :
- 0 =>
0 0000000
- 0 =>
1 0000000
On peut noter que certains langages permettent de distinguer ces deux valeurs.
Représentation en complément à 1
[modifier | modifier le wikicode]Le bit de signe est le bit le plus significatif, et les autres bits représentent :
- la valeur absolue, si le nombre est positif,
- le complément à 1 de la valeur absolue, si le nombre est négatif (c'est à dire 0=>1 et 1=>0).
Exemples pour des nombres signés sur 8 bits :
- +5 =>
0 0000101
- -5 =>
1 1111010
Le zéro n'étant ni négatif, ni positif, il possède également deux représentations possibles :
- 0 =>
0 0000000
- 0 =>
1 1111111
Représentation en complément à 2
[modifier | modifier le wikicode]Cette représentation ressemble à la précédente.
Le bit de signe est le bit le plus significatif, et les autres bits représentent :
- la valeur absolue, si le nombre est positif,
- le complément à 2 de la valeur absolue, si le nombre est négatif. C'est à dire qu'il s'agit du complément à 1, auquel on ajoute 1.
Exemples pour des nombres signés sur 8 bits :
- +5 =>
0 0000101
- -5 =>
1 1111011
(1 1111010
+ 1)
Le zéro ne possède qu'une seule représentation :
- 0 =>
0 0000000
(soit1 1111111
+ 1, sans la retenue)
Cette représentation est la plus répandue actuellement, car elle facilite le traitement des additions et soustractions.
Exemple : -5 + 7
-5 => 1 1111011 +7 => 0 0000111 = ------------ (1)0 0000010 0 0000010 = +2
Nombre à virgule fixe
[modifier | modifier le wikicode]Nombre à virgule flottante
[modifier | modifier le wikicode]Caractère
[modifier | modifier le wikicode]Il faut ici faire la distinction entre le caractère (par exemple « a latin minuscule ») et sa représentation graphique (le « a » que vous voyez sur votre écran). Un caractère est le plus souvent représenté par une valeur numérique, où chaque valeur est associée à un caractère comme « a latin minuscule », « symbole mathématique de l'addition », « apostrophe ». La gestion des caractères en informatique a une histoire très longue. En effet, il est nécessaire de décider de la liste des caractères qui seront disponibles. Or, cette liste peut être différente suivant les pays (pensez aux langues arabes, asiatiques, au russe...) et, de fait, un grand nombre de codages de caractères ont été créés, avec chacun sa propre liste, et où un même caractère pouvait être associé à une valeur numérique différente suivant le codage (voir l'article Codage de caractères sur Wikipédia).
En pratique, l'encodage ASCII (et ses dérivés) est très courant, et tend à être remplacé très avantageusement par l'Unicode.
Exemple : En ASCII, le caractère espace est le numéro 32, en EBCDIC, il s'agit du caractère numéro 64.
Dans les langages où un caractère est effectivement représenté par un nombre, celui-ci peut être utilisé dans des calculs.
Booléen
[modifier | modifier le wikicode]Un booléen ne peut prendre que deux valeurs : vrai ou faux. Ce type est utilisé lorsqu'une expression logique est testée.
Types de données complexes
[modifier | modifier le wikicode]Les types de données complexes sont des types composés de plusieurs types plus élémentaires et qui possèdent une architecture spécifique autorisant des traitements dédiés à leur type. Ces traitement autorisés sont propres au langage et il est rare qu'un langage puisse gérer tous les types décrits ci-dessous à la fois.
Les types de données séquentielles comme les listes ou les matrices se caractérisent par leur capacité à contenir des variables rangées dans une suite de "casiers" qui peuvent être accédés par une boucle parcourant tous les indices? de la séquence.
D'autres types complexes permettent de référer à leur contenu non pas par un indice numérique, mais par une clé qui peut être de n'importe quel type. C'est le cas principalement des dictionnaires.
Enumération
[modifier | modifier le wikicode]Une énumération définit une liste de noms explicites, limitant les valeurs possibles. Par exemple : oui, non. Certains langages de programmation peuvent également associer une valeur d'un autre type à chaque nom (exemple : non = 0, oui = 1).
Chaine de caractères
[modifier | modifier le wikicode]Une chaîne de caractères est une séquence ordonnée de caractères.
Tableau
[modifier | modifier le wikicode]Un tableau contient une série d'éléments d'un certain type. Dans la plupart des langages, ce tableau est de taille fixe. Cette taille peut être déclarée en même temps que la variable (allocation statique) ou à l'allocation mémoire, si la variable est un pointeur vers un tableau (allocation dynamique).
Certains langages de programmation n'ont pas de type spécifique pour les chaînes de caractères (le langage C, par exemple) et utilise alors un tableau de caractères.
Liste
[modifier | modifier le wikicode]Une liste contient une série d'éléments d'un certain type. Le nombre d'éléments qu'elle contient est variable.
Une liste simplement chaînée est représenté par un pointeur vers une structure contenant :
- l'élément de la liste,
- un pointeur vers la structure suivante.
Ce genre de liste ne possède donc qu'un seul sens de parcours.
Une liste doublement chaînée pointe vers une structure contenant un pointeur supplémentaire vers la structure précédente. Ce genre de liste possède donc deux sens de parcours.