28. Littéraux▲
Les programmes effectuent leur tâche en manipulant les valeurs de variables et d'objets. Ils produisent de nouvelles valeurs et de nouveaux objets en les utilisant avec des fonctions et des opérateurs.
Certaines valeurs n'ont pas besoin d'être produites pendant l'exécution du programme ; elles sont écrites directement dans le code source. Par exemple, la valeur flottante 0.75 et la chaîne "Prix total :" ci-dessous ne sont pas calculées :
prixSoldé =
prixDeBase *
0
.75
;
prixTotal +=
nombre *
prixSoldé;
writeln
(
"Prix total : "
, prixTotal);
De telles valeurs écrites littéralement dans le code source sont appelées littéraux. Nous avons utilisé beaucoup de littéraux dans les programmes que nous avons écrits jusqu'à maintenant. Nous allons couvrir tous les types de littéraux et leur syntaxe.
28-1. Littéraux entiers▲
Les littéraux de type entier peuvent être écrits de quatre façons différentes : le système décimal que nous utilisons dans la vie de tous les jours ; les systèmes hexadécimal et binaire, qui sont plus adaptés dans certains calculs ; et le système octal, qui peut être nécessaire dans des cas très rares.
Pour rendre le code plus lisible ou pour n'importe quelle autre raison, il est possible d'insérer des caractères _ n'importe où parmi les caractères des littéraux entiers. Par exemple, pour séparer les nombres à intervalles de trois chiffres comme dans 1_234_567. Ces caractères sont optionnels ; ils sont ignorés par le compilateur.
- Dans le système décimal : les littéraux sont indiqués par les chiffres décimaux exactement de la même manière que nous le faisons dans la vie de tous les jours, comme dans 12. Dans ce système, le premier chiffre ne peut pas être 0 parce que ce chiffre est réservé pour indiquer le système octal dans la plupart des autres langages. En D, les littéraux entiers ne peuvent pas commencer avec le chiffre 0, afin d'éviter des bogues causés par cette différence subtile. Ceci ne s'applique par à 0 lui-même : 0 est zéro.
- Dans le système hexadécimal : les littéraux commencent par 0x ou 0X et incluent les chiffres du système hexadécimal : « 0123456789abcdef » et « ABCDEF » comme dans 0x12ab00fe.
- Dans le système octal : les littéraux sont indiqués par le modèle octal du module conv et incluent les chiffres du système octal : « 01234567 », comme dans octal!576.
- Dans le système binaire : les littéraux commencent par 0b ou 0B et incluent les chiffres du système binaire : 0 et 1, comme dans 0b01100011.
28-2. Les types des littéraux entiers▲
Exactement comme n'importe quelle autre valeur, tout littéral est typé. Les types des littéraux ne sont pas indiqués explicitement comme int, double, etc. Le compilateur infère le type depuis la valeur et la syntaxe du littéral lui-même.
Même si la plupart du temps les types des littéraux ne sont pas importants, parfois les types peuvent ne pas correspondre aux expressions dans lesquelles ils sont utilisés. Dans de tels cas, le type doit être explicité.
Par défaut, les littéraux entiers sont inférés comme étant de type int. Quand la valeur est trop grande pour être représentée par un int, le compilateur utilise le procédé suivant pour décider de quel type le littéral est :
- si la valeur du littéral ne rentre pas dans int et qu'il est spécifié dans le système décimal alors son type est long ;
- si la valeur du littéral ne rentre pas dans int et qu'il est spécifié dans n'importe quel autre système alors le compilateur essaie uint, long et ulong dans cet ordre pour déterminer quel type pourra contenir la valeur.
Pour voir ce procédé en action, essayons le programme suivant qui se sert de typeof et stringof :
import
std.stdio;
void
main
(
)
{
writeln
(
"\n--- Ces nombres sont écrits en décimal ---"
);
// rentre dans int, le type est donc int
writeln
(
2_147_483_647
, "\t\t"
,
typeof
(
2_147_483_647
).stringof);
// ne rentre pas dans int et est décimal, le type est donc long
writeln
(
2_147_483_648
, "\t\t"
,
typeof
(
2_147_483_648
).stringof);
writeln
(
"\n--- Ces nombres ne sont PAS écrits en décimal ---"
);
// rentre dans int, le type est donc int
writeln
(
0x7FFF_FFFF
, "\t\t"
,
typeof
(
0x7FFF_FFFF
).stringof);
// ne rentre pas dans un int et n'est pas décimal, le type est donc uint
writeln
(
0x8000_0000
, "\t\t"
,
typeof
(
0x8000_0000
).stringof);
// ne rentre pas dans un uint et n'est pas décimal, le type est donc long
writeln
(
0x1_0000_0000
, "\t\t"
,
typeof
(
0x1_0000_0000
).stringof);
// ne rentre pas dans un long et n'est pas décimal, le type est donc ulong
writeln
(
0x8000_0000_0000_0000
, "\t\t"
,
typeof
(
0x8000_0000_0000_0000
).stringof);
}
La sortie :
--- Ces nombres sont écrits en décimal ---
2147483647
int
2147483648
long
--- Ces nombres ne sont PAS écrits en décimal ---
2147483647
int
2147483648
uint
4294967296
long
9223372036854775808
ulong
28-2-1. Le suffixe L▲
Indépendamment de la grandeur de la valeur, si elle finit par un L comme dans 10L, le type est long.
28-2-2. Le suffixe U▲
Indépendamment de la grandeur de la valeur, si elle finit par un U comme dans 10U, le type est unsigned. La minuscule 'u' peut également être utilisée.
Les indicateurs L et U peuvent être utilisés ensemble dans n'importe quel ordre. Par exemple, 7UL et 8LU sont toutes les deux ulong.
28-3. Les littéraux flottants▲
Les littéraux flottants peuvent être spécifiés soit dans le système décimal (exemple : 1.1234), soit dans le système hexadécimal (0x9a.bc). (NDT Le séparateur décimal est un point.)
Dans le système décimal : un exposant peut être ajouté après le caractère e ou E, signifiant « fois 10 puissance ». Par exemple, 3.4e5 signifie « 3,4 fois 10 puissance 5 ». Un caractère + peut aussi être indiqué avant la valeur de l'exposant, mais cela n'a aucun effet. Par exemple, 5.6e2 et 5.6e+2 sont la même chose.
Le caractère - tapé avant la valeur de l'exposant change son sens, qui devient « divisé par 10 puissance ». Par exemple, 7.8e-3 signifie « 7.8 divisé par 10 puissance 3 ».
Dans le système hexadécimal : la valeur commence par 0x ou 0X et les chiffres de part et d'autre du point sont ceux du système hexadécimal. Comme dans ce système, e et E sont des chiffres valides, l'exposant est indiqué avec p ou P.
Une autre différence est que l'exposant ne veut pas dire « 10 puissance » mais « 2 puissance ». Par exemple, la partie P4 dans 0xabc.defP4 veut dire « 2 puissance 4 ».
Les littéraux en virgule flottante ont presque toujours un point, mais il peut être omis si un exposant est indiqué. Par exemple, 2e3 est un littéral flottant dont la valeur est 2000.
La valeur avant le point peut être omise si elle est nulle. Par exemple, .25 est un littéral qui a la valeur d'un quart.
Les tirets du bas optionnels (_) peuvent aussi être utilisés avec les littéraux flottant : 1_000.5.
28-3-1. Les types des littéraux flottant▲
Sauf si explicitement indiqué, le type d'un littéral flottant est double. Les indicateurs f et F signifient float, et l'indicateur L signifie real. Par exemple, 1.2 est double, 3.4f est float et 5.6L est real.
28-4. Les littéraux de caractères▲
Les littéraux de caractères sont indiqués avec des apostrophes (guillemets anglais simples) comme dans 'a', '\n', '\x21', etc.
Il y a différentes manières d'écrire un littéral de caractère.
Directement. Le caractère peut être écrit directement avec le clavier ou copié depuis un texte : « a », « ş », etc.
Avec une lettre spéciale. Le caractère est indiqué par un antislash suivi d'une lettre spéciale ; par exemple, le caractère antislash lui-même peut être désigné de cette manière : '\\'. Voici la liste des lettres spéciales :
Syntaxe |
Définition |
---|---|
\' |
guillemet simple |
\" |
guillemet double |
\? |
point d'interrogation |
\\ |
antislash |
\a |
alerte (son de cloche dans certains terminaux) |
\b |
caractère de suppression |
\f |
nouvelle page |
\n |
nouvelle ligne |
\r |
retour chariot |
\t |
tabulation |
\v |
tabulation verticale |
Par son code ASCII étendu. Les codes peuvent être indiqués soit dans le système hexadécimal, soit dans le système octal. Quand le système hexadécimal est utilisé, le littéral doit commencer par \x et doit utiliser deux chiffres pour le code ; quand le système octal est utilisé, le littéral doit commencer par \ et comporter de un à trois chiffres. Par exemple, les littéraux 'x21' et ' \41' désignent tous les deux le point d'exclamation.
Par son code Unicode. Quand le littéral est indiqué avec un u suivi par 4 chiffres hexadécimaux, son type est wchar. Quand il est indiqué avec U suivi de 8 chiffres hexadécimaux, son type est dchar. Par exemple, '\u011e' et '\U0000011e' désignent tous les deux le caractère Ğ et ont respectivement les types wchar et dchar.
Par son nom d'entité (comme en HTML). Les caractères qui ont un nom peuvent être désignés par ce nom en utilisant la syntaxe '\&nom;' (voir le tableau des noms de caractères). Par exemple, '\€' désigne le caractère €, '\♥' le caractère ♥ et '\©' le caractère ©.
28-5. Les littéraux de chaîne▲
Les littéraux de chaîne sont une combinaison de littéraux de caractères et peuvent être désignés de diverses manières.
28-5-1. Les littéraux de chaîne entourés de guillemets anglais doubles▲
La manière la plus commune d'écrire un littéral de chaîne est d'entrer les caractères entre guillemets anglais doubles, comme dans "salut". Les caractères individuels d'un littéral de chaîne suivent les règles des littéraux de caractères. Par exemple, le littéral "A4 ka\u011fıt: 3\½TL" est le même que "A4 kağıt: 3½TL".
28-5-2. Les littéraux de chaîne Wysiwyg▲
Quand les littéraux de chaîne sont écrits dans des guillemets obliques (accents graves, apostrophes inversées, backticks, backquotes), les caractères de la chaîne n'obéissent pas aux règles spéciales de la syntaxe d'un littéral de caractère. Par exemple, le littéral `c:\nurten` peut être un nom de répertoire sur le système d'exploitation Windows. S'il était écrit avec des guillemets doubles, le '\n' désignerait le caractère de nouvelle ligne :
writeln
(
`c:\nurten`
);
writeln
(
"c:\nurten"
);
Sortie :
c:\nurten ← wysiwyg (
what you see is what you get, ce que vous voyez est ce que vous obtenez)
c: ← Le littéral caractère est pris comme une nouvelle ligne
urten
Les littéraux de chaîne Wysiwyg (NDT What You See Is What You Get : « ce que vous voyez est ce que vous obtenez ») peuvent également être écrits entre guillemets doubles en les préfixant avec le caractère r : r"c:\nurten" est aussi un littéral de chaîne wysiwyg.
28-5-3. Littéraux de chaîne hexadécimaux▲
Dans des situations où tous les caractères d'une chaîne doivent être indiqués dans le système hexadécimal, au lieu d'entrer \x avant chacun d'eux, un caractère x peut être ajouté avant le guillemet double ouvrant. Dans ce cas, chaque caractère du littéral de chaîne est pris comme étant écrit en hexadécimal. De plus, le littéral peut contenir des espaces et ceux-ci seront ignorés par le compilateur. Par exemple, "\x44\x64\x69\x6c\x69" et x"44 64 69 6c 69" désignent la même chaîne.
28-5-4. Littéraux de chaîne délimités▲
Le littéral de chaîne peut contenir des délimiteurs qui sont entrés à l'intérieur des guillemets anglais doubles. Ces délimiteurs ne sont pas considérés comme faisant partie de la valeur du littéral. Les littéraux de chaîne délimités commencent par un q avant le guillemet double ouvrant. Par exemple, la valeur de q".hello." est "hello", les points ne font pas partie de la valeur. S'il finit par une nouvelle ligne, le délimiteur peut avoir plus d'un caractère :
writeln
(
q"MON_DELIMITEUR
première ligne
seconde ligne
MON_DELIMITEUR");
MON_DELIMITEUR ne fait pas partie de la valeur :
première ligne
seconde ligne
28-5-5. Littéraux de chaîne « jetons »▲
Les littéraux de chaîne qui commencent par q et qui utilisent { et } comme délimiteurs peuvent contenir du code D correct :
auto
str =
q{
int
nombre =
42
; ++
nombre;}
;
writeln
(
str);
La sortie :
int nombre =
42; ++nombre;
Cette fonctionnalité est particulièrement utile pour aider les éditeurs de textes à colorer le code D dans les chaînes de caractères.
28-5-6. Type des littéraux de chaîne▲
Par défaut, le type d'un littéral de chaîne est immutable(char)[]. On peut ajouter un caractère c, w ou d pour spécifier explicitement le type de la chaîne comme étant immutable(char)[], immutable(wchar)[] ou immutable(dchar)[] respectivement. Par exemple, les caractères de la chaîne « hello »d sont de type immutable(dchar).
Nous avons vu dans le chapitre sur les chainesChaînes de caractères que ces trois types de chaînes ont respectivement pour alias string, wstring et dstring.
28-6. Les littéraux sont calculés lors de la compilation▲
Il est possible d'utiliser des expressions littérales. Par exemple, au lieu d'écrire le nombre total de secondes du mois de janvier comme 2678400 ou 2_678_400, il est possible de l'écrire par un calcul plus explicite comme 60 * 60 * 24 * 31. Les opérations de multiplication n'influent pas sur la vitesse d'exécution du programme, car le programme obtenu après compilation est exactement le même que si 2678400 avait été écrit à la place de l'opération.
La même chose s'applique aux littéraux de chaîne. Par exemple, l'opération de concaténation dans "bonjour" ~ " le " ~ "monde" est exécutée lors de la compilation, pas pendant l'exécution. Le programme est compilé comme si le code ne contenait que le littéral de chaîne "bonjour le monde".
28-7. Exercices▲
-
La ligne suivante donne une erreur de compilation :
Sélectionnezint
quantite=
10_000_000_000
;// ← ERREUR de compilation
-
Modifiez le programme de sorte que la ligne puisse être compilée et que quantite vaille dix milliards.
-
Écrire un programme qui augmente la valeur d'une variable et qui l'affiche dans une boucle infinie. La valeur doit toujours être affichée sur la même ligne :
SélectionnezNombre :
25774
← toujours sur la même ligne - Un caractère spécial autre que '\n' peut être utilisé ici.