programmez-en-d/litteraux.whata

278 lines
16 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[set
title = "Littéraux"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
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 [c "Prix total :"] ci-dessous ne sont pas calculées~ :
[code=d <<<
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.
[ = Littéraux entiers
Les littéraux 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 [c _] n'importe où parmi les caractères des littéraux entiers. Par exemple, pour séparer les nombres à intervalles de trois chiffres comme dans [c 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 [c 12]. Dans ce système, le premier chiffre ne peut pas être [c 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 [c 0], afin d'éviter des bogues causés par cette différence subtile. Ceci ne s'applique par à [c 0] lui-même~ : [c 0] est zéro.
- Dans le système hexadécimal~ : les littéraux commencent par [c 0x] ou [c 0X] et incluent les chiffres du système hexadécimal~ : «~ 0123456789abcdef~ » et «~ ABCDEF~ » comme dans [c 0x12ab00fe].
- Dans le système octal~ : les littéraux sont indiqués par le modèle [c octal] du module [std.conv] et inclue les chiffres du système octal~ : «~ 01234567~ », comme dans [c octal!576].
- Dans le système binaire~ : les littéraux commencent par [c 0b] ou [c 0B] et incluent les chiffres du système binaire~ : 0 et 1, comme dans [c 0b01100011].
]
[ = 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 [c int], [c 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 important, 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 [c int]. Quand la valeur est trop large pour être représenté par un [c 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 [c int] et qu'il est spécifié dans le système décimal alors son type est [c long].
- Si la valeur du littéral ne rentre pas dans [c int] et qu'il est spécifié dans n'importe quel autre système alors le compilateur essaie [c uint], [c long] et [c ulong], dans cet ordre, selon quel type pourra contenir la valeur.
Pour voir ce procédé en action, essayons le programme suivant qui se sert de de [c typeof] et [c stringof] :
[code=d <<<
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 :
[output <<<
--- 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
>>>]
[ = Le suffixe L
Indépendamment de la grandeur de la valeur, si elle finit par un L comme dans [c 10L], le type est [c long].
]
[ = Le suffixe U
Indépendamment de la grandeur de la valeur, si elle finit par un U comme dans [c 10U], le type est [c 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, [c 7UL] et [c 8LU] sont toutes les deux [c ulong].
]
]
[ = Les littéraux flottants
Les littéraux flottants peuvent être spécifiés soit dans le système décimal (exemple~ : [c 1.1234]), soit dans le système hexadécimal ([c 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 [c e] ou [c E], signifiant «~ fois 10 puissance~ ». Par exemple, [c 3.4e5] signifie «~ 3,4 fois 10 puissance 5~ ». Un caractère [c +] peut aussi être indiqué avant la valeur de l'exposant, mais cela n'a aucun effet. Par exemple, [c 5.6e2] et [c 5.6e+2] sont la même chose.
Le caractère [c -] tapé avant la valeur de l'exposant change son sens, qui devient "divisé par 10 puissance". Par exemple, [c 7.8e-3] signifie «~ 7.8 divisé par 10 puissance 3~ ».
Dans le système hexadécimal~ : la valeur commence par [c 0x] ou [c 0X] et les chiffres de part et d'autre du point sont ceux du système hexadécimal. Comme dans ce système, [c e] et [c E] sont des chiffres valides, l'exposant est indiqué avec [c p] ou [c P].
Une autre différence est que l'exposant ne veut pas dire «~ 10 puissance~ » mais «~ 2 puissance~ ». Par exemple, la partie [c P4] dans [c 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, [c 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, [c .25] est un littéral qui a la valeur d'un quart.
Les tirets du bas optionnels ([c _]) peuvent aussi être utilisés avec les littéraux flottant~ : [c 1_000.5].
[ = Les types des littéraux flottant
Sauf si explicitement indiqué, le type d'un littéral flottant est [c double]. Les indicateurs [c f] et [c F] signifient [c float], et l'indicateur [c L] signifie [c real]. Par exemple, [c 1.2] est [c double], [c 3.4f] est [c float] et [c 5.6L] est [c real].
]
]
[ = Les littéraux de caractères
Les littéraux de caractères sont indiqués avec des apostrophes (guillemets anglais simples) comme dans [c 'a'], [c '\n'], [c '\x21'], etc.
Il y a différentes manières d'écrire un littéral de caractère.
[p Directement. | Le caractère peut être écrit directement avec le clavier ou copié depuis un texte~ : «~ a~ », «~ ş~ », etc.]
[p 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~ : [c '\\']. Voici la liste des lettres spéciales~ :]
|=Syntaxe |= Définition
|[c \'] | guillemet simple
|[c \"] | guillemet double
|[c \?] | point d'interrogation
|[c \\] | antislash
|[c \a] | alerte (son de cloche dans certains terminaux)
|[c \b] | caractère de suppression
|[c \f] | nouvelle page
|[c \n] | nouvelle ligne
|[c \r] | retour chariot
|[c \t] | tabulation
|[c \v] | tabulation verticale
[p 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 [c \x] et doit utiliser deux chiffres pour le code~ ; quand le système octal est utilisé, le littéral doit commencer par [c \] et comporter de un à trois chiffres. Par exemple, les littéraux [c 'x21'] et [c '\41'] désignent tous les deux le point d'exclamation.]
[p Par son code Unicode. | Quand le littéral est indiqué avec un [c u] suivi par 4 chiffres hexadécimaux, son type est [c wchar]. Quand il est indiqué avec [c U] suivi de 8 chiffres hexadécimaux, son type est [c dchar]. Par exemple, [c '\u011e'] et [c '\U0000011e'] désignent tous les deux le caractère [c Ğ] et ont respectivement les types [c wchar] et [c dchar].]
[p 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 [c '\&nom;'] (voir [[http://dlang.org/entity.html | le tableau des noms de caractères]]). Par exemple, [c '\&euro;'] désigne le caractère €, '\&hearts;' le caractère ♥ et '\&copy;' le caractère ©.]
]
[ = Les littéraux de chaînes
Les littéraux de chaînes sont une combinaison de littéraux de caractères et peuvent être désignés de diverses manières.
[ = Les littéraux de chaînes 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 [c "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 [c "A4 ka\u011fıt: 3\&frac12;TL"] est le même que [c "A4 kağıt: 3½TL"].
]
[ = Les littéraux de chaîne ''Wysiwyg''
Quand les littéraux de chaînes sont écrits dans des guillemets obliques (accents graves, apostrophes inversées, ''backticks'', ''backquotes''), les caractères de la chaîne n'obéissent par aux règles spéciales de la syntaxe d'un littéral de caractère. Par exemple, le littéral [c `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 '[c \n]' désignerait le caractère de nouvelle ligne~ :
[code=d <<<
writeln(`c:\nurten`);
writeln("c:\nurten");
>>>]
[output <<<
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 [c r]~ : [c r"c:\nurten"] est aussi un littéral de chaîne wysiwyg.
]
[ = Littéraux de chaînes hexadécimaux
Dans des situations où tous les caractères d'une chaînes doivent être indiqués dans le système hexadécimal, au lieu d'entrer [c \x] avant chacun d'eux, un caractère [c 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, [c "\x44\x64\x69\x6c\x69"] et [c x"44 64 69 6c 69"] désignent la même chaîne.
]
[ = 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 [c q] avant le guillemet double ouvrant. Par exemple, la valeur de [c q".hello."] est [c "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~ :
[code=d <<<
writeln(q"MON_DELIMITEUR
première ligne
seconde ligne
MON_DELIMITEUR");
>>>]
[c MON_DELIMITEUR] ne fait pas partie de la valeur~ :
[code=d <<<
première ligne
seconde ligne
>>>]
]
[ = Littéraux de chaîne «~ jetons~ »
Les littéraux de chaînes qui commencent par q et qui utilisent [c {] et [c }] comme délimiteurs peuvent contenir du code D correct~ :
[code=d <<<
auto str = q{int nombre = 42; ++nombre;};
writeln(str);
>>>]
La sortie~ :
[output <<<
int nombre = 42; ++nombre;
>>>]
]
Cette fonctionalité est particulièrement utile pour aider les éditeurs de textes à colorer le code D dans les chaînes de caractères.
[ = Type des littéraux de chaînes
Par défaut, le type d'un littéral de chaîne est [c immutable(char)~[~]]. On peut ajouter un caractère [c c], [c w] ou [c d] pour spécifier explicitement le type de la chaîne comme étant [c immutable(char)~[~]], [c immutable(wchar)~[~]] ou [c immutable(dchar)~[~]] respectivement. Par exemple, les caractères de la chaîne [c "hello"d] sont de type [c immutable(dchar)].
Nous avons vu dans le [[part:chaines | chapitre sur les chaînes] que ces trois types de chaînes ont respectivement pour alias [c string], [c wstring] et [c dstring].
]
]
[ = 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 [c 2678400] ou [c 2_678_400], il est possible de l'écrire par un calcul plus explicite comme [c 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 [c 2678400] avait été écrit à la place de l'opération.
La même chose s'applique aux littéraux de chaînes. Par exemple, l'opération de concaténation dans [c "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 [c "bonjour le monde"].
]
[ = Exercices
# La ligne suivante donne une erreur de compilation~ :
[code=d <<<
int quantite = 10_000_000_000; // ← ERREUR de compilation
>>>]
Modifiez le programme de sorte que la ligne puisse être compilée et que [c 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~ :
[output <<<
Nombre : 25774 ← toujours sur la même ligne
>>>]
Un caractère spécial autre que [c '\n'] peut être utilisé ici.
[[part:corrections/litteraux | … Les solutions]]
]