update metadata about proofreaders and translators

This commit is contained in:
Raphaël JAKSE 2015-04-15 17:59:56 +02:00
parent 9d8e4c1275
commit 602c9d2402
90 changed files with 517 additions and 374 deletions

View File

@ -1,6 +1,8 @@
[set
title = "Affectation et ordre d'évaluation"
partAs = chapitre
title = "Affectation et ordre d'évaluation"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Les deux premières difficultés auxquelles sont confrontés les étudiants quand ils apprennent à programmer concernent l'opération d'affectation et l'ordre d'évaluation.

View File

@ -1,9 +1,11 @@
[set
title = "Nombres entiers et opérations arithmétiques"
partAs = chapitre
title = "Nombres entiers et opérations arithmétiques"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Nous avons vu que les instructions [c if] et [c while] permettent aux programmes de prendre des décisions en utilisant le type [c bool] sous forme d'expressions logiques. Dans ce chapitre, nous allons voir les opérations arithmétiques sur les types entiers du D. Ces fonctionnalités nous permettrons d'écrire des programmes beaucoup plus utiles.
Nous avons vu que les instructions [c if] et [c while] permettent aux programmes de prendre des décisions en utilisant le type [c bool] sous forme d'expressions logiques. Dans ce chapitre, nous allons voir les opérations arithmétiques sur les types entiers du D. Ces fonctionnalités nous permettrons d'écrire des programmes beaucoup plus utiles.
Même si les opérations arithmétiques font partie de notre vie quotidienne et sont en fait simples, il y a des concepts très importants dont un programmeur doit être conscient pour produire des programmes corrects~ : taille en bits d'un type, débordements, [[wp:fr Soupassement arithmétique | soupassements]], et troncages.
@ -93,16 +95,16 @@ Je souhaiterai aussi résumer ici trois concepts importants avant de les dévelo
|7 | 128 | | | |
|_ 8 |_ 256 | byte | -128 | 127|
| ubyte | 0 | 255|
||||| ...
||||| ...
|_ 16 |_ 65 536 | short | -32768 | 32767 |
| ushort | 0 | 65535 |
||||| ...
||||| ...
|_ 32 |_ 4 294 967 296 | int | -2147483648 | 2147483647
| uint | 0 | 4294967295
||||| ...
||||| ...
|_ 64 |_ 18 446 744 073 709 551 616 | long | -9223372036854775808 | 9223372036854775807
| ulong | 0 | 18446744073709551615
||||| ...
||||| ...
J'ai sauté beaucoup de lignes dans le tableau, et indiqué les versions signées et non signées des type D qui ont le même nombre de bits sur la même ligne (par exemple [c int] et [c uint] sont tous les deux sur la ligne des 32 bits)
@ -116,7 +118,7 @@ Je souhaiterai aussi résumer ici trois concepts importants avant de les dévelo
En règle générale, tant qu'il n'y a aucune raison spécifique de ne pas le faire, vous pouvez utiliser [c int] pour les valeurs entières.
]
[ = Dépassement
Le fait que les types ne peuvent avoir qu'un nombre limité de valeurs peut causer des effets inattendus. Par exemple, même si ajouter deux [c uint] valant 3 milliards chacun devrait donner 6 milliards, comme la somme est plus grande que la valeur maximum qu'une variable [c uint] peut stocker (environ 4 milliards), cette somme déborde. Sans aucun avertissement, seule la différence entre 6 et 4 milliards est stockée (un peu plus précisément, 6 moins 4,3 milliards).
@ -129,7 +131,7 @@ Je souhaiterai aussi résumer ici trois concepts importants avant de les dévelo
Nous verrons des techniques basiques pour aider à réduire les effets de débordements, soupassements et troncages plus loin dans le chapitre.
]
[ = [c .min] et [c .max]
Nous utiliserons les propriétés [c min] et [c max] plus bas, que nous avons vues dans le [[part:types | chapitre sur les Types Fondamentaux]]. Ces propriétés donnent les valeurs minimale et maximale qu'un type entier peut avoir.
@ -197,7 +199,7 @@ Je souhaiterai aussi résumer ici trois concepts importants avant de les dévelo
De manière similaire à l'opérateur ++, si la valeur de la variable est la valeur minimum, elle devient la valeur maximum. Ce phénomène est appelé [* soupassement] (''underflow'').
]
[ = Addition : +
Cet opérateur est utilisé avec deux expressions et ajoute leurs valeurs~ :
@ -400,7 +402,7 @@ Je souhaiterai aussi résumer ici trois concepts importants avant de les dévelo
[output 64]
]
[ = Négation : [c -]
Cet opérateur change le signe de la valeur de l'expression (négatif devient positif et inversement)~ :
@ -501,7 +503,7 @@ Je souhaiterai aussi résumer ici trois concepts importants avant de les dévelo
Se comporte de la même manière que l'opérateur de post-incrémentation mais décrémente.
]
[ = Priorité opératoire
Les opérateurs que nous avons vus jusqu'alors ont toujours été utilisés tout seuls, avec seulement une ou deux expressions. Cependant, comme les expressions logiques, il est fréquent de combiner ces opérateurs pour former des expressions arithmétiques plus complexes~ :

View File

@ -1,6 +1,7 @@
[set
title = "[c assert] et [c enforce]"
partAs = chapitre
title = "[c assert] et [c enforce]"
partAs = chapitre
translator = "Raphaël Jakse"
]
Dans les deux chapitres, nous avons vu comment les exceptions et les instructions [c scope] sont utilisés pour améliorer la correction des programmes. [c assert] est aussi un outil puissant dans le même esprit pour s'assurer que certaines suppositions sur lesquelles le programme est basé sont vaildes.
@ -68,11 +69,11 @@ Quand de telles suppositions n'existent seulement dans la tête du programmeur,
}
>>>]
Ces vérifications avec [c assert] portent le sens de « On suppose que les deux âges sont supérieurs ou égaux à zéro. ». On peut aussi le voir comme « Cette fonction ne peut marcher correctement que si les deux âges sont supérieurs ou égaux à zéro ».
Ces vérifications avec [c assert] portent le sens de « On suppose que les deux âges sont supérieurs ou égaux à zéro. ». On peut aussi le voir comme « Cette fonction ne peut marcher correctement que si les deux âges sont supérieurs ou égaux à zéro ».
[c assert] vérifie ces suppositions et termine le programme avec une [c AssertError] quand elles ne sont pas valides :
[output <<<
core.exception.AssertError@deneme(3): Assertion failure
>>>]
@ -93,7 +94,7 @@ Quand de telles suppositions n'existent seulement dans la tête du programmeur,
Parfois, on pense qu'il est impossible pour un programme de rentrer dans un bloc de code donné. Dans de tels cas, il est courant d'utiliser le littéral [c false] comme expression logique pour faire échouer une assertion. Par exemple, pour indiquer qu'on ne s'attend pas à ce que la fonction [c executerCommande()] soit appelée avec autre chose que"chanter" et "danser", et pour se protéger d'une telle possibilité, [c assert(false)] peut être inséré dans la branche [* impossible] :
[code=d <<<
void executerCommande(string commande)
{
@ -119,7 +120,7 @@ Quand de telles suppositions n'existent seulement dans la tête du programmeur,
Par exemple, en supposant que le titre d'un menu sera affiché sur un périphérique de sortie qui a une largeur limitée, le [c static assert] suivant s'assure qu'il ne sera jamais plus large que cette limite :
[code=d <<<
enum dstring titreMenu = "Menu Commande";
static assert(titreMenu.length <= 16);
@ -234,7 +235,7 @@ Quand de telles suppositions n'existent seulement dans la tête du programmeur,
]
[ = Exercices
- [
Le programme suivant inclue un nombre d'assertion. Compilez et exécuter le programme pour découvrir les bogues qui sont révélés par ces assertions.
Le programme demande un moment de départ et une durée à l'utilisateur et calcule le moment de fin en ajoutant la durée au moment de départ :
@ -314,7 +315,7 @@ Quand de telles suppositions n'existent seulement dans la tête du programmeur,
[p Note : | Vous pouvez remarquer un problème avec la sortie. Ignorez ce problème, vous le découvrirez avec l'aide des assertions très bientôt.]
]
- [
Cette fois, entrez [c 06:09] et [c 15:2]. Observez que le proramme se terminez par une [c AssertError]. Allez à la ligne du programme qui est indiquée dans le message de l'assertion et voyez qu'une des assertions a échoué. Découvrir la cause de cet échec particulier peut prendre du temps.
Cette fois, entrez [c 06:09] et [c 15:2]. Observez que le proramme se terminez par une [c AssertError]. Allez à la ligne du programme qui est indiquée dans le message de l'assertion et voyez qu'une des assertions a échoué. Découvrir la cause de cet échec particulier peut prendre du temps.
]
- [
Entrez [c 06:09] et [c 20:0] et observez que la même assertion échoue encore et corrigez aussi ce bogue.

View File

@ -1,6 +1,8 @@
[set
title = "[c auto] et [c typeof]"
partAs = chapitre
title = "[c auto] et [c typeof]"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
[ = [c auto]
@ -42,9 +44,9 @@
Dans ce code, le compilateur infère le type de [c i] en [c immutable int] (nous verrons [c immutable] dans un chapitre ultérieur).
]
[ = [c typeof]
[c typeof] donne le type d'une expression (ce qui comprend les variables simples, les objets, les littéraux...).
Ce qui suit est un exemple de comment [c typeof] peut être utilisé pour spécifier un type sans l'écrire explicitement~ :
[code=d <<<
@ -54,7 +56,7 @@
typeof(100) valeur3; // signifie "type du littéral 100"
>>>]
Les deux dernières définitions sont équivalentes à ce qui suit~ :
[code=d <<<
@ -70,6 +72,6 @@
Comme nous n'avons vu précédemment, le type des littéraux tels que 100 est [c int] (et non [c short], [c long], ou n'importe quel autre type). Écrire un programme pour déterminer le type des littéraux à virgule flottante comme 1.2.
[c typeof()] et [c .stringof] sont utiles pour ce programme.
[[part:corrections/auto_et_typeof || … La solution]]
]

View File

@ -1,6 +1,8 @@
[set
title = "Caractères"
partAs = chapitre
title = "Caractères"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Les caractères sont des briques élémentaires des chaînes. Chaque symbole d'un système d'écriture est appelé caractère~ : les lettres des alphabets, les chiffres, les signes de ponctuation, l'espace, etc. Les briques élémentaires des caractères elles-mêmes sont appelées caractères également, ce qui entraîne certaines ambiguïtés.
@ -25,14 +27,14 @@ Dans la plupart des langages, les caractères sont représentés par le type [c
]
[ = Pages de codes IBM
[ = Pages de codes IBM
IBM Corporation a défini un ensemble de tables, chacune d'elle affectant les codes de 128 à 256 de la table ASCII étendue à un ou plusieurs systèmes d'écriture. Ces tables de codes ont permis de prendre en charge les lettres de beaucoup plus d'alphabets. Par exemple, les lettres spéciales de l'alphabet turc font partie de la page de codes IBM 857.
Bien qu'elles soient plus utiles qu'ASCII, les pages de codes ont des problèmes et des limitations~ : pour afficher le texte correctement, la page de codes utilisée pour l'écrire doit être connue. En effet, le même code correspond à un autre caractère dans la plupart des autres tables. Par exemple, le code qui représente 'Ğ' dans la table 857 correspond à 'ª' dans la table 437.
Un autre problème est la limitation du nombre d'alphabet qui peuvent être utilisés au sein d'un même document. De plus, les alphabets qui ont plus de 128 caractères non ASCII ne peuvent pas être pris en charges par une table IBM.
]
[ = Pages de codes ISO/IEC 8859
@ -48,7 +50,7 @@ Dans la plupart des langages, les caractères sont représentés par le type [c
[ = Codages Unicodes
Unicode associe un unique code à chaque caractère. Comme il y a plus de caractères Unicode que ce que peut contenir une valeur 8~ bits, certains caractères doivent être représentés par au moins deux valeurs 8-bits. Par exemple, le code Unicode de 'Ğ' (``286``) est plus grand que la valeur maximale d'un type 8 bits (255).
[p Note~ : | je vais utiliser 1 et 30 comme les valeurs des deux octets qui représentent Ğ de façon arbitraire. Ils ne sont valides dans aucun codage Unicode mais utiles pour introduire ces codages Unicode. Les valeurs correctes de ces valeurs sont hors de la portée de ce chapitre.]
La manière dont les caractères sont représentés électroniquement est appelé [* codage]. Nous avons vus ci-dessus comment la chaîne [c "hello"] est représentée en ASCII. Nous allons maintant voir les 3 codages Unicodes qui correspondent aux types de caractères D.
@ -69,7 +71,7 @@ Dans la plupart des langages, les caractères sont représentés par le type [c
]
- [
[** UTF-16] : Ce codage utilise 16 bits (2 octets) pour représenter la plupart des caractères unicodes. Comme 16 bits peuvent représenter environ 65 milliers de valeurs uniques, les autres 35 mille caractères Unicode doivent être représentés par des octets supplémentaires.
Par exemple, [c "aĞ"] est codé avec 4 octets en UTF-16~ : ``0``, ``97`` ; ``1``, ``30``.
Note~ : les valeurs réelles de certains de ces octets sont différentes et l'ordre réel des octets peut être différent.
@ -158,7 +160,7 @@ Dans la plupart des langages, les caractères sont représentés par le type [c
| [c \t] | tab | Déplace l'affichage à la prochaine tabulation
Par exemple, la fonction [c write], qui ne commence pas de nouvelle ligne automatiquement, le ferait pour chaque caractère [c \n]. Chaque occurence du caractère de contrôle [c \n] à l'intérieur du littéral suivant représente le début d'une nouvelle ligne~ :
[code=d write("première ligne\ndeuxième ligne\ntroisième ligne\n"); ]
[output <<<
@ -174,7 +176,7 @@ Dans la plupart des langages, les caractères sont représentés par le type [c
De manière similaire, on ne peut pas écrire ``'\'`` pour désigner le caractère antislash. Comme l'antislash a une signification spéciale, le compilateur prendrait ``\'`` comme un caractère spécial. Le compilateur chercherait ensuite un guillemet fermant et ne le trouverait pas.
Pour éviter ces confusions, le guillemet simple et l'antislash sont [* échappés] par un antislash :
|= caractère |= Syntaxe |= Nom
| ``'`` |``\'`` | guillemet simple
| ``\`` |``\\`` | antislash (contre-oblique)
@ -285,8 +287,8 @@ Dans la plupart des langages, les caractères sont représentés par le type [c
}
>>>]
Si vous essayez ce programme dans un environnement qui n'utilise pas Unicode, vous pouvez voir que même les caractères non Unicode sont lus et affichés correctement.
Si vous essayez ce programme dans un environnement qui n'utilise pas Unicode, vous pouvez voir que même les caractères non Unicode sont lus et affichés correctement.
Cependant, si vous démarrez ce programme dans un environnement Unicode, par exemple une console sous Linux, vous pouvez voir que le caractère affiché à la sortie n'est pas le même caractère que celui qui a été entré. Pour voir ceci, entrons un caractère non-ASCII dans une console qui utilise le codage UTF-8 (comme la plupart des consoles sous Linux)~ :
[output <<<
@ -326,7 +328,7 @@ Dans la plupart des langages, les caractères sont représentés par le type [c
Ces résultats sont dépendant aussi du fait que les entrées-sorties standard des programmes sont des flux de [c char].
Nous verrons plus tard dans le [[part:chaines | chapitre sur les chaînes]] qu'il est plus facile de lire des caractères commes des chaînes, plutôt que s'occuper individuellement des codes UTF-8.
]
[ = Prise en charge de l'Unicode par le langage D
@ -343,7 +345,7 @@ Dans la plupart des langages, les caractères sont représentés par le type [c
[* Point de code] (''code point'')~ : chaque lettre, chiffre, symbole, etc. qu'Unicode définit est appelé un point de code. Par exemple, les codes unicodes de 'a' est de 'ğ' sont deux points de code distincts.
Selon le codage, les points de code sont représentés par une ou plusieurs unités de stockage. Comme mentionné ci-avant, dans le codage UTF-8 'a' est représenté par une unité de stockage et 'ğ' est représenté par deux unités de stockage. En revanche, 'a' et 'ğ' sont représentés par une seule unité de stockage dans les codages UTF-16 et UTF-32.
Le type D qui prend en charge les points de code est [c dchar]. [c char] est [c wchar] ne peuvent être utilisés que pour les unités de stockage.
]
- [

View File

@ -1,6 +1,7 @@
[set
title = "Conversions de Types, [c cast]"
partAs = chapitre
title = "Conversions de Types, [c cast]"
partAs = chapitre
translator = "Raphaël Jakse"
]
Les variables doivent être compatibles avec les expression dans lesquelles apparaissent. Comme vous l'avez peut-être déjà remarqué dans les programmes que nous avons vus jusqu'à maintenant, D est un langage [* statiquement typé], ce qui veut dire que la compatibilité des types est vérifiée lors de la compilation.
@ -30,7 +31,7 @@ Même si [c somme] et [c increment] sont de types différents, le code ci-avant
[ = Conversion automatique des types
Les conversions automatiques de types sont aussi appelées [* conversions implicites de types].
Les conversions automatiques de types sont aussi appelées [* conversions implicites de types].
Même si [c double] et [c int] sont des types compatibles dans l'expression ci-avant, l'opération d'addition doit toujours être évaluée comme un type spécifique au niveau du microprocesseur. Comme nous l'avons vu dans le [[doc:virgule_flottante | chapitre sur les virgules flottantes]], le type 64-bits [c double] est [* plus large] que le type 32-bits [c int]. De plus, toute valeur qui peut être représentée dans une variable [c int] peut être représentée dans une variable [c double].
@ -290,7 +291,7 @@ Même si [c somme] et [c increment] sont de types différents, le code ci-avant
- en appelant la fonction [c std.conv.to]
- en appelant la fonction [c std.exception.assumeUnique]
- en utilisant l'opérateur [c cast]
[ = La fonction [c to] pour la plupart des conversions
La fonction [c to], que nous avons déjà utilisé surtout pour convertir des valeurs vers [c string], peut en fait être utilisée pour beaucoup d'autres types. Sa syntaxe complète est la suivante :
@ -397,7 +398,7 @@ Même si [c somme] et [c increment] sont de types différents, le code ci-avant
[c assumeUnique] retourne une nouvelle tranche qui fournit un accès immuable aux éléments existants. Elle rend aussi la tranche originale [c null] pour empêcher les éléments d'être accidentellement modifiés.
]
[ = L'opérateur [c cast]
Les fonctions [c to] et [c assumeUnique] utilisent toutes deux l'opérateur de conversion [c cast], qui est également disponible pour le programmeur.

View File

@ -1,6 +1,8 @@
[set
title = "Chaînes de caractères"
partAs = chapitre
title = "Chaînes de caractères"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Nous avons utilisé des chaînes de caractères dans beaucoup de programmes que nous avons vus jusqu'à maintenant. Les chaînes sont une combinaison de deux fonctionnalités que nous avons couvertes dans les 3 derniers chapitres~ : les caractères et les tableaux. Dans la définition la plus simple, les chaînes ne sont rien d'autre que des tableaux de caractères. Par exemple, [c <<<char[]>>>] est un type de chaîne.
@ -28,7 +30,7 @@ Cette simple définition peut être trompeuse. Comme nous l'avons vu dans le [[p
>>>]
La touche entrée sur laquelle l'utilisateur appuie après le nom ne termine pas l'entrée. [c readf()] continue à attendre plus de caractères à ajouter à la chaîne~ :
[output <<<
Quel est votre nom ? Mert
← L'entrée n'est pas terminée alors même que la touche Entrée a été enfoncée.
@ -96,7 +98,7 @@ Cette simple définition peut être trompeuse. Comme nous l'avons vu dans le [[p
>>>]
[c readln()] peut être utilisé sans paramètre. Dans ce cas, [c readln()] retourne la ligne qui vient d'être lue. Chaîner le résultat de [c readln()] et [c chomp()] permet une syntaxe plus lisible et plus courte~ :
[code=d <<<
string nom = chomp(readln());
>>>]
@ -132,7 +134,7 @@ Cette simple définition peut être trompeuse. Comme nous l'avons vu dans le [[p
# Le type des chaînes littérales comme [c "hello"] est [c string], et non [c char~[~]], elles sont donc immuables.
# Le [c char~[~]] sur le côté gauche est une tranche, qui donnerait accès, si le code était compilé, à tous les caractères du côté droit.
Comme [c char~[~]] est mutable et que [c string] ne l'est pas, il y a conflit. Le compilateur ne permet pas d'accéder aux caractères d'un tableaux immuable par une tranche «~ mutable~ ».
@ -150,7 +152,7 @@ Cette simple définition peut être trompeuse. Comme nous l'avons vu dans le [[p
>>>]
Le programme peut maintenant être compilé et afficher la chaîne modifiée~ :
[output Salut]
De façon similaire, [c char~[~]] ne peut pas être utilisé là ou une [c string] est nécessaire. Dans ce tels cas, la propriété [c .idup] peut être utilisée pour produire une variable [c string] immuable à partir d'une variable mutable [c char[]]. Par exemple, si [c s] est une variable du type [c char~[~]], la ligne suivante ne peut être compilée~ :
@ -160,7 +162,7 @@ Cette simple définition peut être trompeuse. Comme nous l'avons vu dans le [[p
>>>]
Quand le type de [c s] est [c char~[~]], le type de l'expression à droite de l'affectation ci-dessus est [c char~[~]] également. [c .idup] est utilisé pour obtenir des chaînes immuables à partir de chaînes existantes~ :
[code=d <<<
string resultat = (s ~ '.').idup; // ← maintenant, compile
>>>]
@ -169,7 +171,7 @@ Cette simple définition peut être trompeuse. Comme nous l'avons vu dans le [[p
[ = Confusion potentielle sur la taille des chaînes
Nous avons vu que certains caractères Unicode sont représentés par plus d'un octet. Par exemple, la lettre 'é' est représentée par deux octets. On remarque cela avec la propriété [c .length] des chaînes~ :
[code=d <<<
writeln("résumé".length);
>>>]
@ -214,7 +216,7 @@ Cette simple définition peut être trompeuse. Comme nous l'avons vu dans le [[p
Notez les deux différences dans le nouveau code~ :
# Le type de chaîne est [c dchar~[~]].
# Il y a un ``d`` à la fin du littéral [c "résumé"d], indiquant que c'est un tableau de [c dchar]s.
]
[ = Chaînes littérales
@ -276,7 +278,7 @@ Cette simple définition peut être trompeuse. Comme nous l'avons vu dans le [[p
[ = Comparaison de chaînes
[p Notes~ : | Unicode ne définit pas comment les caractères sont ordonnés autrement que par leurs codes Unicode. Pour cette raison, vous pouvez obtenir des résultats qui ne correspondent pas à vos attentes. Quand l'ordre alphabétique est important, vous pouvez utiliser une bibliothèque du type [[http://code.google.com/p/trileri/ | trileri]] qui prend en charge l'idée d'alphabet.]
Jusqu'à maintenant, nous n'avons utilisé les opérateurs de comparaison [c <], [c > >=], etc. qu'avec les entiers et les flottants. Les mêmes opérateurs peuvent être utilisés avec les chaînes également, mais avec une signification différente~ : les chaînes sont ordonnées de façon ''lexicographique''. Cet ordre considère le code Unicode de chaque caractère comme étant la place de ce caractère dans un alphabet fictif géant~ :
[code=d <<<

View File

@ -1,6 +1,8 @@
[set
title = "Compilateur"
partAs = chapitre
title = "Compilateur"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Nous avons vu que les deux outils les plus utilisés en programmation D sont l'éditeur de texte et le compilateur. Les programmes D sont écrits dans des éditeurs de textes.
@ -21,9 +23,9 @@ Le concept de compilation et le rôle du compilateur doivent aussi être compris
110
000
>>>]|<[pre <<<
11110
10100
10100
11110
10100
10100
00000
>>>]|[pre <<<
LOAD 11110

View File

@ -1,6 +1,7 @@
[set
title = "Immutabilité"
partAs = chapitre
title = "Immutabilité"
partAs = chapitre
translator = "Raphaël Jakse"
]
Nous avons vu que les variables représentent des idées dans les programmes. Les interactions de ces idées sont matérialisées par les expressions qui changent les valeurs de ces variables :
@ -89,7 +90,7 @@ L'[* immuabilité] en D est représenté par les mots-clés [c const] et [c immu
writeln(42);
foo(42);
>>>]
Même si ce remplacement fait sens pour des types simples comme [c int] et ne fait aucune différence dans le programme, les constantes [c enum] apportent un coût caché quand elles sont utilisées pour des tableaux ou des tableaux associatifs :
[code=d <<<
@ -97,14 +98,14 @@ L'[* immuabilité] en D est représenté par les mots-clés [c const] et [c immu
writeln(a);
foo(a);
>>>]
En remplaçant [c a] par sa valeur, le code équivalent que le compilateur compilerait est le suivant :
[code=d <<<
writeln([ 42, 100 ]); // Un tableau est créé lors de l'exécution
foo([ 42, 100 ]); // Un autre tableau est créé lors de l'exécution
>>>]
Le coût caché ici est qu'il y aurait deux tableaux créé pour les deux expressions ci-dessus. Pour cette raison, il est plus sensé de définir les tableaux et les tableaux associatifs comme des variables immuables s'ils sont utilisés plusieurs fois dans le programme.
]
@ -459,7 +460,7 @@ L'[* immuabilité] en D est représenté par les mots-clés [c const] et [c immu
- [c string] est un alias de [c immutable(char)~[~]]
- [c wstring] est un alias de [c immutable(wchar)~[~]]
- [c dstring] est un alias de [c immutable(dchar)~[~]]
De même, les littéraux de chaînes sont également immuables :
- Le type du littéral [c "hello"c] est [c string]
@ -510,7 +511,7 @@ L'[* immuabilité] en D est représenté par les mots-clés [c const] et [c immu
enum secondesParMinute = 60;
>>>]
]
- Considérez le coût de copie des tableaux (associatifs) [c enum]. Définissez-les commes des variables [c immutable] si les tableaux sont larges et qu'ils sont utilisés plus d'une fois dans le programme.
- [

View File

@ -1,6 +1,7 @@
[set
title = "Programmation par contrats"
partAs = chapitre
title = "Programmation par contrats"
partAs = chapitre
translator = "Raphaël Jakse"
]
La programmation par contrat est une approche en conception logicielle qui traîte les parties d'un logiciel comme des entités individuelles qui se rfinent mutuellement des services. Cette approche considère que le programme peut fonctionner en accord avec sa spécification tant que le fournisseur et le consommateur du service obéissent tous deux à un [* contrat].
@ -84,7 +85,7 @@ Nous verront les blocs [c invariant] et l'[*héritage par contrat] dans un chapi
{
return estAnneeBissextile(annee) ? 29 : 28;
}
>>>]
>>>]
Même si [c resultat] est un nom raisonnable pour une valeur de retour, d'autre noms parfaitement valides peuvent aussi être utilisés.
@ -98,7 +99,7 @@ Nous verront les blocs [c invariant] et l'[*héritage par contrat] dans un chapi
>>>]
De manière similaire aux blocs [c in], les blocs [c out] sont exécutés automatiquement après l'exécution du le corps de la fonction.
Une assertion qui échoue dans un bloc [c out] indique que le contrat a été violé par la fonction.
Évidemment, les blocs [c in] et [c out] sont optionnels. En incluant les blocs [c unittest], qui sont également optionnels, les fonctions D peuvent être constitués d'un nombre de blocs pouvant aller jusqu'à 4 :
@ -117,7 +118,7 @@ Nous verront les blocs [c invariant] et l'[*héritage par contrat] dans un chapi
* Distribue la somme entre deux variables.
*
* Distribue d'abord à la première variable, mais ne lui donne
* jamais plus de 7. Le reste de la somme est distribuée
* jamais plus de 7. Le reste de la somme est distribuée
* à la seconde variable.
*/
void distribuer(in int somme, out int premiere, out int seconde)
@ -327,4 +328,4 @@ Nous verront les blocs [c invariant] et l'[*héritage par contrat] dans un chapi
J'ai choisi de retourner un [c int] pour cet exercice, de cette manière, la valeur de retour peut être comparée aux valeurs 0, 1 et 2.
[[part:corrections/contrats | … La solution]]
]
]

View File

@ -1,6 +1,8 @@
[set
title = "Affectation et ordre d'évaluation"
partAs = correction
title = "Affectation et ordre d'évaluation"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# Les valeurs de ``a``, ``b`` et ``c`` sont affichées à droite de chaque opération. La valeur qui change est à chaque opération surlignée~ :

View File

@ -1,6 +1,8 @@
[set
title = "Nombres entiers et opérations arithmétiques"
partAs = correction
title = "Nombres entiers et opérations arithmétiques"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [ On peut utiliser l'opérateur [c /] pour la division et l'opérateur [c %] pour le reste~ :

View File

@ -1,6 +1,8 @@
[set
title = "[c auto] et [c typeof]"
partAs = correction
title = "[c auto] et [c typeof]"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
On peut utiliser [c typeof()] pour déterminer le type du littéral et [c .stringof] pour avoir le nom de ce type en tant que [c string]~ :

View File

@ -1,6 +1,8 @@
[set
title = "Chaînes de caractères"
partAs = correction
title = "Chaînes de caractères"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [
@ -50,4 +52,4 @@
}
}
>>>]
]
]

View File

@ -1,6 +1,7 @@
[set
title = "Programmation par contrats"
partAs = correction
title = "Programmation par contrats"
translator = "Raphaël Jakse"
partAs = correction
]
Le bloc [c unittest] peut être implémenté simplement en copiant les vérifications qui ont déjà été écrites dans la fonction [c main]. Le seul ajout ci-dessous est le test pour le cas dans lequel la seconde équipe gagne :

View File

@ -1,6 +1,8 @@
[set
title = "La boucle do-while"
partAs = correction
title = "La boucle do-while"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Ce programme n'est pas directement lié à la boucle [c do-while] puisque tout problème qui peut être résolu avec une boucle [c do-while] peut également être résolu par les autres types de boucle.

View File

@ -1,6 +1,8 @@
[set
title = "Lire depuis l'entrée"
partAs = correction
title = "Lire depuis l'entrée"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Quand les caractères ne peuvent pas être convertis au type voulu, [c stdin] devient inutilisable. Par exemple, en entrant "abc" quand un entier est attendu rendrait [c stdin] inutilisable.
Quand les caractères ne peuvent pas être convertis au type voulu, [c stdin] devient inutilisable. Par exemple, en entrant "abc" quand un entier est attendu rendrait [c stdin] inutilisable.

View File

@ -1,6 +1,8 @@
[set
title = "Entrée formatée"
partAs = correction
title = "Entrée formatée"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Il suffit d'utiliser une chaîne de formatage où les parties de dates sont remplacées par [c %s]~ :

View File

@ -1,6 +1,7 @@
[set
title = "Les énumérations ([c enum])"
partAs = correction
title = "Les énumérations ([c enum])"
translator = "Raphaël Jakse"
partAs = correction
]
[code=d <<<
@ -87,4 +88,4 @@
writeln(" resultat: ", resultat);
}
}
>>>]
>>>]

View File

@ -1,6 +1,8 @@
[set
title = "Entrée standard et flux de sortie"
partAs = correction
title = "Entrée standard et flux de sortie"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
[code=d <<<

View File

@ -1,14 +1,16 @@
[set
title = "Expressions logiques"
partAs = correction
title = "Expressions logiques"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# Parce que le compilateur reconnaît [c 10 < valeur] comme une expression, il s'attend à avoir une virgule après elle pour l'accepter comme un argument valable de [c writeln]. Ajouter des parenthèses autour de l'expression ne marche pas non plus parce que, cette fois, une parenthèse fermante serait attendue après la même expression.
# Grouper l'expression de cette manière : [c (10 < value)] < 20 supprime l'erreur de compilation, parce que dans ce cas, [c 10 < value] est évaluée et son résultat est utilisé avec [c < 20].
Nous savons que la valeur d'une expression logique comme [c 10 < value] est soit fausse, soit vraie. Dans des expressions entières, [c false] et [c true] sont convertis en 0 et 1 respectivement (nous verrons les conversions de types automatiques dans un chapitre suivant). De ce fait, l'expression complète est l'équivalent de [c 0 < 20] ou [c 1 < 20], qui sont vraies toutes les deux.
# L'expression «~ plus grand que la valeur basse et plus petit que la valeur haute~ » peut être écrite de cette façon~ :
[code=d <<<

View File

@ -1,6 +1,8 @@
[set
title = "Fichiers"
partAs = correction
title = "Fichiers"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
[code=d <<<
@ -26,4 +28,4 @@
writeln(nomFichierSortie, " a été créé.");
}
>>>]
>>>]

View File

@ -1,6 +1,7 @@
[set
title = "Nombre variable de paramètres"
partAs = correction
title = "Nombre variable de paramètres"
partAs = correction
translator = "Olivier Pisano"
]
Pour que la fonction ``calculer`` puisse accepter un nombre variable de paramètres, elle doit inclure une tranche de ``Calcul`` suivie de ``...``~ :

View File

@ -1,6 +1,7 @@
[set
title = "Les fonctions"
partAs = correction
title = "Les fonctions"
partAs = correction
translator = "Raphaël Jakse"
]
# [code=d <<<

View File

@ -1,6 +1,8 @@
[set
title = "La boucle [c for"
partAs = correction
title = "La boucle [c for"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [

View File

@ -1,6 +1,7 @@
[set
title = "La boucle [c foreach]"
partAs = correction
title = "La boucle [c foreach]"
partAs = correction
translator = "Raphaël Jakse"
]
Pour obtenir un tableau associatif qui marche dans le sens opposé de [c noms], les types des clés et des valeurs doivent être échangés. Le nouveau tableau associatif doit être de type [c int~[string~]].

View File

@ -1,6 +1,8 @@
[set
title = "Le programme [i Hello world]"
partAs = correction
title = "Le programme [i Hello world]"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [

View File

@ -1,6 +1,8 @@
[set
title = "L'instruction if"
partAs = correction
title = "L'instruction if"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [ L'instruction [c=d writeln("Laver l'assiette")] est indentée comme si elle était dans le bloc [c else]. Cependant, du fait que le bloc de ce [c else] n'est pas écrit avec des accolades, seule l'instruction [c=d writeln("Manger la tarte")] est considérée comme étant dans la portée de ce [c else].

View File

@ -1,6 +1,8 @@
[set
title = "Littéraux"
partAs = correction
title = "Littéraux"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [

View File

@ -1,6 +1,7 @@
[set
title = "Environnement du Programme"
partAs = correction
title = "Environnement du Programme"
translator = "Raphaël Jakse"
partAs = correction
]
# [
@ -60,4 +61,4 @@
writeln("Valeur de retour : ", system(ligneDeCommande));
}
>>>]
]
]

View File

@ -1,6 +1,7 @@
[set
title = "Paramètre des fonctions"
partAs = correction
title = "Paramètre des fonctions"
translator = "Raphaël Jakse"
partAs = correction
]
# Parce que les paramètres de cette fonction sont du type de ceux qui sont copiés depuis les arguments, ce qui est échangé dans la fonction sont ces copies.
@ -22,4 +23,4 @@
2 1
>>>]
Même si ce n'est pas relatif au problème original, notez également que [c temp] est spécifié comme [c immutable] comme il ne devrait pas être changé dans la fonction après son initialisation.
Même si ce n'est pas relatif au problème original, notez également que [c temp] est spécifié comme [c immutable] comme il ne devrait pas être changé dans la fonction après son initialisation.

View File

@ -1,6 +1,8 @@
[set
title = "Rediriger l'entrée standard et les flux de sortie"
partAs = correction
title = "Rediriger l'entrée standard et les flux de sortie"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Rediriger l'entrée standard et la sortie des programmes est souvent utilisé, spécialement dans les consoles des systèmes de type Unix. Certains programmes sont conçus pour fonctionner correctement quand ils sont combinés avec d'autres programmes.

View File

@ -1,6 +1,8 @@
[set
title = "Sortie formatée"
partAs = correction
title = "Sortie formatée"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [ Nous avons déjà vu que c'est trivial avec les indicateurs de format~ :

View File

@ -1,6 +1,7 @@
[set
title = "Structures"
partAs = correction
title = "Structures"
partAs = correction
translator = "Raphaël Jakse"
]
# Une des conceptions les plus simples est d'utiliser deux membres [c dchar] :

View File

@ -1,6 +1,7 @@
[set
title = "Surcharge de fonctions"
partAs = correction
title = "Surcharge de fonctions"
partAs = correction
translator = "Olivier Pisano"
]
Les deux surcharges suivantes utilisent les surcharges d'``info()`` existantes :

View File

@ -1,6 +1,7 @@
[set
title = "[c switch] et [c case]"
partAs = correction
title = "[c switch] et [c case]"
partAs = correction
translator = "Raphaël Jakse"
]
# [
@ -46,7 +47,7 @@
]
# [
En utilisant les valeurs distinctes :
[code=d <<<
final switch (op) {
case "ajouter", "+":
@ -82,4 +83,4 @@
// ...
>>>]
]
]

View File

@ -1,6 +1,8 @@
[set
title = "Tableaux"
partAs = correction
title = "Tableaux"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# Code~ :

View File

@ -1,10 +1,12 @@
[set
title = "Tableaux associatifs"
partAs = correction
title = "Tableaux associatifs"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [
- La propriété [c .keys] retourne une tranche (c.-à-d. un tableau dynamique) qui inclue toutes les clés du tableau associatif. Itérer sur cette tranche et supprimer les éléments de chaque clé en appelant [c .remove] résultera en un tableau associatif vide~ :
- La propriété [c .keys] retourne une tranche (c.-à-d. un tableau dynamique) qui inclue toutes les clés du tableau associatif. Itérer sur cette tranche et supprimer les éléments de chaque clé en appelant [c .remove] résultera en un tableau associatif vide~ :
[code=d <<<
import std.stdio;

View File

@ -1,6 +1,8 @@
[set
title = "L'opérateur ternaire [c ?:]"
partAs = correction
title = "L'opérateur ternaire [c ?:]"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
[

View File

@ -1,6 +1,7 @@
[set
title = "Tests Unitaires"
partAs = correction
title = "Tests Unitaires"
partAs = correction
translator = "Raphaël Jakse"
]
La première chose à faire est de compiler et exécuter le programme pour s'assurer que les tests fonctionnent et échouent :

View File

@ -1,6 +1,8 @@
[set
title = "Tranches et autres fonctionnalités des tableaux"
partAs = correction
title = "Tranches et autres fonctionnalités des tableaux"
partAs = correction
proofreader = "Stéphane Goujet"
translator = "Raphaël Jakse"
]
Itérer sur les éléments d'une tranche depuis le début de la tranche est une idée intéressante. Cette méthode est aussi la base des intervalles de Phobos que nous verrons dans un chapitre ultérieur.

View File

@ -1,6 +1,8 @@
[set
title = "Types Fondamentaux"
partAs = correction
title = "Types Fondamentaux"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
On peut utiliser d'autre types à la place de [c int] :
@ -22,4 +24,4 @@ void main()
writeln("Valeur minimale : ", ulong.min);
writeln("Valeur maximale : ", ulong.max);
}
]
]

View File

@ -1,6 +1,8 @@
[set
title = "Variable"
partAs = correction
title = "Variable"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
[code=d <<<

View File

@ -1,6 +1,8 @@
[set
title = "Types à virgule flottante"
partAs = correction
title = "Types à virgule flottante"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [
@ -9,9 +11,9 @@
[code=d <<<
double first;
double second;
// ...
double result;
>>>]
]
@ -29,7 +31,7 @@
double valeur_3;
double valeur_4;
double valeur_5;
write("Value 1: ");
readf(" %s", &valeur_1);
write("Value 2: ");
@ -40,14 +42,14 @@
readf(" %s", &valeur_4);
write("Value 5: ");
readf(" %s", &valeur_5);
writeln("Le double des valeurs :");
writeln(valeur_1 * 2);
writeln(valeur_2 * 2);
writeln(valeur_3 * 2);
writeln(valeur_4 * 2);
writeln(valeur_5 * 2);
writeln("Le cinquième des valeurs :");
writeln(valeur_1 / 5);
writeln(valeur_2 / 5);

View File

@ -1,6 +1,8 @@
[set
title = "La boucle [c while]"
partAs = correction
title = "La boucle [c while]"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [

View File

@ -1,6 +1,8 @@
[set
title = "[c writeln] et [c write]"
partAs = correction
title = "[c writeln] et [c write]"
partAs = correction
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
# [

View File

@ -1,6 +1,8 @@
[set
title = "Boucle [c do]-[c while]"
partAs = chapitre
title = "Boucle [c do]-[c while]"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Dans le [[part:for | chapitre sur la boucle [c for]]], nous avons vu les étapes d'exécution d'une boucle [c while]~ :

View File

@ -1,6 +1,7 @@
[set
title = Durées de vie et opérations fondamentales
partAs = chapitre
title = Durées de vie et opérations fondamentales
partAs = chapitre
translator = "Raphaël Jakse"
]
Nous verrons bientôt les structures, la fonctionnalité de base qui permet au programmeur de définir des types spécifiques à une application. Les structures sont faites pour combiner des types fondamentaux et d'autres structures ensemble pour définir des types de plus haut niveau qui se comportent selon des besoins spécifiques des programmes. Après les structures, nous verrons les classes, qui sont la base de la programmation orientée objet en D.
@ -31,7 +32,7 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
} // ← 'vitesse' est indisponible après ce point.
>>>]
La vie de la variable [c vitesse] dans ce code prend fin lorsque l'on sort de la fonction [c testVitesse]. Il y a une seule variable dans le code suivant et elle prend 10 valeurs différentes, de 100 à 109.
La vie de la variable [c vitesse] dans ce code prend fin lorsque l'on sort de la fonction [c testVitesse]. Il y a une seule variable dans le code suivant et elle prend 10 valeurs différentes, de 100 à 109.
En ce qui conserne la durée de vie des variables, le code suivant est très différent comparé au précédent :
@ -123,7 +124,7 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
Tout variable doit être initialisée avant d'être utilisée. L'initialisation implique deux étapes :
- [** réserver de l'espace pour la variable] : cet espace est l'endroit dans lequel la valeur de la variable est stockée en mémoire.
- [** Construction] : fixer la première valeur de la variable dans cet espace (ou les premières valeurs des membres des structures et des classes).
Toute variable vie à un endroit en mémoire qui lui est réservé. Une partie du code que le compilateur génère sert à réserver de l'espace pour chaque variable.
considérons la variable suivante :
@ -210,7 +211,7 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
Pour les types fondamentaux, il n'y a pas d'opération finale à exécuter. Par exemple, la valeur d'une variable de type [c int] n'est pas remise à zéro. Pour de telle variable, il n'y a que la libération de la mémoire, qui pourra être utilisée pour d'autres variables plus tard.
En revanche, certains types de variable nécessitent des opérations spéciales pendant la finalisation. Par exemple, un objet [c File] aurait besoin d'écrire les caractères qui sont toujours dans son tampon de sortie sur le disque et de notifier au système de fichier qu'il n'utilise plus le fichier. Ces opérations sont la destruction d'un objet [c File].
En revanche, certains types de variable nécessitent des opérations spéciales pendant la finalisation. Par exemple, un objet [c File] aurait besoin d'écrire les caractères qui sont toujours dans son tampon de sortie sur le disque et de notifier au système de fichier qu'il n'utilise plus le fichier. Ces opérations sont la destruction d'un objet [c File].
Les opérations finales des tableaux sont d'un niveau plus haut : avant de finaliser le tableau, ses éléments doivent d'abord être détruits. Si les éléments sont d'un type fondamental simple comme [c int], il n'y a alors pas de d'opération finale spéciale à effectuer. Si les éléments sont d'un type structure ou classe qui ont besoin d'être finalisés, ces opérations sont alors exécutés pour chaque élément.

View File

@ -1,6 +1,8 @@
[set
title = "Lire depuis l'entrée standard"
partAs = chapitre
title = "Lire depuis l'entrée standard"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Toute donnée lue par le programme doit d'abord être stockée dans une variable. Par exemple, un programme lisant le nombre d'étudiants depuis l'entrée doit d'abord enregistrer cette information dans une variable. Le type de cette variable spécifique peut être [c int].

View File

@ -1,6 +1,8 @@
[set
title = "Entrée formatée"
partAs = chapitre
title = "Entrée formatée"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Il est possible d'indiquer le format des données attendues à l'entrée. Le format indique aussi bien les données à lire que les caractères qui doivent être ignorés.

View File

@ -1,6 +1,7 @@
[set
title = "Les énumérations ([c enum])"
partAs = chapitre
title = "Les énumérations ([c enum])"
partAs = chapitre
translator = "Raphaël Jakse"
]
[c enum] est la fonctionnalité qui permet de définir des valeurs de constantes nommées.
@ -25,7 +26,7 @@
>>>]
Les littéraux entiers 1, 2, 3 et 4 dans ce bout de code sont appelés constantes magiques. Il n'est pas facile de déterminer à quoi correspond chacun de ces littéraux dans le programme. Le code de chaque bloc doit être examiné pour voir que 1 désigne l'ajouterition, 2 la soustraction, etc. Cette tâche est relativement aisée dans le code ci-avant parce que chaque bloc ne contient qu'une ligne. Il serait considérablement plus difficile de déchiffrer le sens des constantes magiques dans la plupart des autres programmes.
Les constantes magiques doivent être évitées parce qu'elle limitent les deux qualités les plus importantes des programmes : lisibilité et maintenabilité.
[c enum] permet de donner des noms à de telles constantes et donc de rendre le code plus lisible et maintainable. Chaque condition est immédiatement compréhensible quand les valeurs énumérées suivantes sont utilisées :
@ -128,7 +129,7 @@
enum ConstanteNaturelle : double { pi = 3.14, e = 2.72 }
enum UnitéDeTempérature : string { C = "Celsius", F = "Fahrenheit" }
>>>]
]
[ = Les valeurs énumérées ne sont pas d'un type énuméré
@ -180,7 +181,7 @@
carreaux : 2
trèfles : 3
>>>]
Notez qu'une boucle [c foreach] sur cet intervalle ne considérerait pas la valeur [c .max] :
[code=d <<<

View File

@ -1,6 +1,8 @@
[set
title = "Flux d'entrée et de sortie standards"
partAs = chapitre
title = "Flux d'entrée et de sortie standards"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Jusqu'ici, l'affichage de nos programmes apparaissait dans la console. Bien qu'elle soit la destination dans la plupart des cas, en réalité les caractères sont envoyés dans les [* flux de sortie] des programmes.

View File

@ -1,6 +1,8 @@
[set
title = "Espace de nom (''name space'')"
partAs = chapitre
title = "Espace de nom (''name space'')"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Tout nom est accessible depuis l'endroit où il a été défini jusqu'à l'endroit où l'on quitte sa portée, de même que dans toutes les portées que la sienne inclue. De ce point de vue, toute portée définie un espace de nom.

View File

@ -1,6 +1,7 @@
[set
title = "Exceptions"
partAs = chapitre
title = "Exceptions"
partAs = chapitre
translator = "Raphaël Jakse"
]
Les situations non attendues font partie des programmes : erreurs de l'utilisateur, erreurs de programmation, changements dans l'environnement de programmation, etc. Les programmes doivent être écrits d'une manière qui évite la prodution de résultats incorrects quand on se trouve devant de telles conditions [i exceptionnelles].
@ -65,9 +66,9 @@ Le programme termine avec une exception qui est levé par [c to!int] :
[ = Les types d'exceptions [c Exception] et [c Error]
Seuls les types qui sont hérités de la classe [c Throwable] peuvent être levés. [c Throwable] n'est quasiment jamais directement utilisée dans les programmes. En pratique, les types qui sont levés sont des types qui héritent d'[c Exception] ou d'[c Error], qui sont eux-mêmes des types qui héritent de [c Throwable]. Par exemple, toutes les exceptions que Phobos lève sont héritées de [c Exception] ou [c Error].
[c Error] représente des situations irrécupérables qu'il n'est pas recommandé d'attraper. Pour cette raison, la plupart des exceptions qu'un programme lève sont d'un type hérité de [c Exception]. L'héritage est un concept relatif aux classes. Nous verrons les classes dans un chapitre ultérieur.
Les objets de type [c Exception] sont construits à partir d'une valeur [c string] qui représente un message d'erreur. Vous pouvez utiliser la fonction [c format] du module [c std.string] pour créer ce message :
[code=d <<<
@ -427,7 +428,7 @@ Le programme termine avec une exception qui est levé par [c to!int] :
Voici un récapitulatif de ce qu'il se passe lorsque le programme est démarré alors que le fichier n'existe pas :
- Comme dans le programme précédent, une exception [c std.exception.ErrnoException] est levée (par [c File()], pas par notre code),
- Cette exception est attrapée par [c catch],
- Cette exception est attrapée par [c catch],
- La valeur de [c 1] est supposée pendant l'exécution normale du bloc [c catch],
- et le programme continue normalement
@ -466,7 +467,7 @@ Le programme termine avec une exception qui est levé par [c to!int] :
◁ main, dernière ligne
>>>]
Comme nous pouvons le voir dans la sortie, le programme ne termine plus à cause de l'exception. Il rattrape la condition d'erreur et continue à s'exécuter normalement jusqu'à la fin de la fonction [c main].
Comme nous pouvons le voir dans la sortie, le programme ne termine plus à cause de l'exception. Il rattrape la condition d'erreur et continue à s'exécuter normalement jusqu'à la fin de la fonction [c main].
]
[ = Les blocs [c catch] sont parcourus séquentiellement
@ -620,7 +621,7 @@ Le programme termine avec une exception qui est levé par [c to!int] :
>>>]
Cela donne la possibilité de n'ouvrir le fichier que s'il existe. Malheureusement, il est encore possible que le fichier ne puisse pas être ouvert même si [c exists()] retourne [c true], si par exemple un autre processus du système supprime ou renomme le fichier avant que notre programme l'ouvre.
Pour cette raison, la méthode suivante peut être plus utile.
]
- [
@ -697,7 +698,7 @@ Le programme termine avec une exception qui est levé par [c to!int] :
[output <<<
core.exception.AssertError@deneme.d(3): Assertion failure
>>>]
[c assert] vérifie l'état du programme et affiche le nom du fichier et le numéro de la ligne de la vérification si elle échoue. Le message ci-avant indique que l'assertion à la ligne 3 de [c deneme.d] a échoué.
]
@ -719,10 +720,10 @@ Le programme termine avec une exception qui est levé par [c to!int] :
[comment Use $(C enforce) to validate programmers' use of your functions.]
- En cas de doute, levez une exception.
- Attrapez les exceptions si et seulement si vous pouvez faire quelque chose d'utile avec ces exceptions. Sinon, n'encapsulez pas de code avec une instruction [c try-catch]. Laissez plutôt la gestion de ces exceptions aux couches de code de plus hauts niveaux qui peuvent en faire quelque chose.
- Ordonnez les blocs [c catch] du plus spécifique au plus général.
- Placez les expressions qui doivent toujours être exécutées lors de la sortie d'une portée dans des blocs [c finally].
]
]

View File

@ -1,6 +1,8 @@
[set
title = "Expressions logiques"
partAs = chapitre
title = "Expressions logiques"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Le travail qu'un programme réalise est accompli par des expressions. Toute partie d'un programme qui produit une valeur ou un effet de bord est appelée une [* expression]. La définition d'expression est très large car même une constante comme 42 et une chaîne comme ``"bonjour"`` sont des expressions parce qu'elles produisent respectivement les valeurs constantes ``42`` et ``"bonjour"``.

View File

@ -1,6 +1,8 @@
[set
title = "Fichiers"
partAs = chapitre
title = "Fichiers"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Nous avons vu dans le chapitre précédent que les flux d'entrée et de sortie standard peuvent être redirigés vers et depuis des fichiers ou d'autres programmes avec les opérateurs [c > >], [c < ] et [c > | ] dans la console. Malgré leur puissance, ces outils ne sont pas adaptés dans toutes les situations parce que dans beaucoup de cas, les programmes ne peuvent pas effectuer leurs tâches en lisant leur entrée et en écrivant sur leur sortie.
@ -22,7 +24,7 @@ Dans ce chapitre, nous allons voir comment lire et écrire des fichiers du syst
De plus, les exemples de code ci-après n'écrivent pas de BOM au début du fichier. Ceci peut rendre vos fichiers incompatibles avec les systèmes qui nécessite une BOM (BOM veut dire ''Byte Ordrer Mark'', [[wiki:fr Byte_Order_Mark | indicateur d'ordre des octets]]).
]
[ = Droits d'accès
Les systèmes de fichiers donnent accès aux fichiers aux programmes avec certains droits. Les droits d'accès sont aussi important pour l'intégrité des données que pour les performances.
@ -40,7 +42,7 @@ Dans ce chapitre, nous allons voir comment lire et écrire des fichiers du syst
Tout fichier qui a été ouvert par un programme doit être fermé quand le programme a fini de l'utiliser. Dans la plupart des cas, les fichiers n'ont pas besoin d'être fermés explicitement, ils sont fermés automatiquement quand les objets [c File] sont détruits automatiquement~ :
[code=d <<<
if (uneCondition) {
@ -60,7 +62,7 @@ Dans ce chapitre, nous allons voir comment lire et écrire des fichiers du syst
>>>]
]
[ = Écrire et lire un fichier
Comme les fichiers sont des flux de caractères, les fonctions d'entrée et de sortie [c writeln], [c readf], etc. sont utilisées exactement de la même manière avec eux. La seule différence est que le nom de la variable [c File] suivie d'un point doivent être ajoutés~ :
@ -71,13 +73,13 @@ Dans ce chapitre, nous allons voir comment lire et écrire des fichiers du syst
>>>]
]
[ = [c eof()] pour tester la fin du fichier
La méthode [c eof()] détermine si la fin du fichier a été atteinte pendant la lecture du fichier. Quand c'est le cas, elle retourne [c true].
Par exemple, la boucle suivante sera exécutée jusqu'à la fin du fichier~ :
[code=d <<<
while (!fichier.eof()) {
/* ... */
@ -85,9 +87,9 @@ Dans ce chapitre, nous allons voir comment lire et écrire des fichiers du syst
>>>]
]
[ = Le module [c std.file]
Le [[ http://dlang.org/phobos/std_file.html | module [c std.file]]] contient des fonctions et des types qui sont utiles pour travailler avec le contenu des dossiers. Par exemple, la fonction [c exists] peut être utilisée pour savoir si un fichier ou un dossier existe sur le système de fichier :
[code=d <<<
@ -143,7 +145,7 @@ Dans ce chapitre, nous allons voir comment lire et écrire des fichiers du syst
Le programme ci-dessus crée ou remplace le contenu d'un fichier nommé [c enregistrements_etudiants] dans le dossier dans lequel il a été lancé (le [* dossier de travail] du programme).
[p Note~ : |
[p Note~ : |
Les noms de fichiers peuvent contenir n'importe quel caractère autorisé par le système de fichier. Pour être portable, je n'utiliserai que des caractères ASCII.
]
]

View File

@ -1,6 +1,8 @@
[set
title = "Nombre variable de paramètres"
partAs = chapitre
title = "Nombre variable de paramètres"
partAs = chapitre
translator = "Raphaël Jakse"
translator = "Olivier Pisano"
]
Ce chapitre évoque deux fonctionnalités de D qui apportent de la flexibilité aux paramètres lors des appels de fonctions~ :

View File

@ -1,6 +1,7 @@
[set
title = "Fonctions"
partAs = chapitre
title = "Fonctions"
partAs = chapitre
translator = "Raphaël Jakse"
]
Alors que les types fondamentaux sont les briques élémentaires des données d'un programme, les fonctions sont les briques élémentairess du comportement de ce programme.
@ -152,8 +153,8 @@ On peut noter, en observant les similarités entre les définitions de [c affich
nom_de_la_fonction(valeurs_des_parametres)
>>>]
Les valeurs réelles des paramètres qui sont passées aux fonctions sont appelées [* arguments de la fonction]. Même si les termes [* paramètre] et [* argument] sont parfois interchangés dans la littérature, ils désignent des concepts différents.
Les valeurs réelles des paramètres qui sont passées aux fonctions sont appelées [* arguments de la fonction]. Même si les termes [* paramètre] et [* argument] sont parfois interchangés dans la littérature, ils désignent des concepts différents.
Les arguments sont mis en correspondance avec les paramètres un à un dans l'ordre de définition des paramètres. Par exemple, le dernier appel à [c afficherMenu()] ci-dessus utilise les arguments [c "Revenir"] et [c 1], qui correspondent aux paramètres [c premiereEntree] et [c premierNombre], respectivement.
Le type de chaque argument doit correspondre au type du paramètre correspondant.
@ -166,12 +167,12 @@ On peut noter, en observant les similarités entre les définitions de [c affich
- [
[p Avoir des effets de bord. | Les effets de bord sont n'importe quel changement d'état du programme ou de son environnement. Seules certaines opérations ont des effets de bord. Un exemple est la modification de stdout quand [c afficherMenu()] affiche le menu. Un autre exemple d'effet de bord serait une fonction qui ajouterais un objet [c Etudiant] à un conteneur étudiant : cela entraînerait l'agrandissement du conteneur.]
En résumé, les opérations qui modifient l'état du programme ont des effets de bord.
]
- [p Produire une valeur : | Certaines opérations ne font que produire une valeur. Par exemple, une fonction qui ajoute des nombres produirait le résultat de cette opération. Un autre exemple serait une fonction qui créerait un objet [c Etudiant] à partir du nom et de l'adresse d'un étudiant produirait un objet [c Etudiant].]
- [p Avoir des effets de bords et produire une valeur : | Certaines opérations font les deux. Par exemple, une fonction qui lit deux valeurs depuis stdin et calcule leur somme a des effets de bords parce qu'elle modifie l'état de [c stdin] et produit également la somme des deux valeurs.]
- [p Aucune opération : |
@ -205,7 +206,7 @@ On peut noter, en observant les similarités entre les définitions de [c affich
[code=d <<<
writeln("Résultat: ", ajouter(5, diviser(100, nombreEtudiants())));
>>>]
Dans la ligne ci-avant, la valeur de retour de [c nombreEtudiants()] est passée à [c diviser()] en second argument, la valeur de retour de [c diviser()] est passée à [c ajouter()] en second argument, et finalement la valeur de retour de [c ajouter()] est passé à writeln() en second argument.
]
@ -241,7 +242,7 @@ On peut noter, en observant les similarités entre les définitions de [c affich
]
[ = Les fonctions [c void]
Le type de retour des fonctions qui ne produisent pas de valeur est conventionnellement [c void]. Nous l'avons vu de nombreuses fois avec la fonction [c main()], de même qu'avec la fonction [c afficherMenu] ci-avant. Comme elles ne retournent pas de valeur aux fonctions qui les appellent, leurs valeurs de retour a été défini comme [c void]. (Note : [c main()] peut également être définie comme retournant [c int]. Nous le verrons dans un chapitre ultérieur.)
Le type de retour des fonctions qui ne produisent pas de valeur est conventionnellement [c void]. Nous l'avons vu de nombreuses fois avec la fonction [c main()], de même qu'avec la fonction [c afficherMenu] ci-avant. Comme elles ne retournent pas de valeur aux fonctions qui les appellent, leurs valeurs de retour a été défini comme [c void]. (Note : [c main()] peut également être définie comme retournant [c int]. Nous le verrons dans un chapitre ultérieur.)
]
[ = Le nom de la fonction
@ -408,7 +409,7 @@ On peut noter, en observant les similarités entre les définitions de [c affich
write("Nombre ", i, "? ");
readf(" %s", &nombre);
>>>]
Le code serait encore mieux s'il utilisait une nouvelle fonction nommée de façon appropriée [c lire_entier()]. La nouvelle fonction peut prendre le message en paramètre, afficher ce message, lire un entier depuis l'entrée et le retourner :
[code=d <<<

View File

@ -1,6 +1,6 @@
[set
title = "Fonction membres"
partAs = chapitre
title = "Fonction membres"
partAs = chapitre
]
[fixme En attente d'écriture.]

View File

@ -1,6 +1,7 @@
[set
title = "Les paramètres ``const ref`` et les fonctions membres ``const``"
partAs = chapitre
partAs = chapitre
translator = "Olivier Pisano"
]
Ce chapitre explique comment les paramètres et les fonctions membres peuvent être marqués comme ``const`` afin d'être utilisés avec des variables ``immutable``. Comme nous avons déjà parlé des paramètres const dans les chapitres précédents, certaines informations de ce chapitre seront pour vous des révisions de fonctionnalités que vous connaissez déjà.

View File

@ -1,6 +1,8 @@
[set
title = "Boucles [c for]"
partAs = chapitre
title = "Boucles [c for]"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
La boucle [c for] a le même but que la boucle [c while]. [c for] permet d'écrire les définitions et expressions relatives à l'itération de la boucle sur la même ligne.
@ -157,15 +159,15 @@ Même si [c for] est utilisée beaucoup moins souvent que [c foreach] en pratiqu
# Afficher le tableau 9×9 suivant en utilisant deux boucles [c for], l'une à l'intérieur de l'autre~ :
[pre <<<
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8
1,0 1,1 1,2 1,3 1,4 1,5 1,6 1,7 1,8
2,0 2,1 2,2 2,3 2,4 2,5 2,6 2,7 2,8
3,0 3,1 3,2 3,3 3,4 3,5 3,6 3,7 3,8
4,0 4,1 4,2 4,3 4,4 4,5 4,6 4,7 4,8
5,0 5,1 5,2 5,3 5,4 5,5 5,6 5,7 5,8
6,0 6,1 6,2 6,3 6,4 6,5 6,6 6,7 6,8
7,0 7,1 7,2 7,3 7,4 7,5 7,6 7,7 7,8
8,0 8,1 8,2 8,3 8,4 8,5 8,6 8,7 8,8
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8
1,0 1,1 1,2 1,3 1,4 1,5 1,6 1,7 1,8
2,0 2,1 2,2 2,3 2,4 2,5 2,6 2,7 2,8
3,0 3,1 3,2 3,3 3,4 3,5 3,6 3,7 3,8
4,0 4,1 4,2 4,3 4,4 4,5 4,6 4,7 4,8
5,0 5,1 5,2 5,3 5,4 5,5 5,6 5,7 5,8
6,0 6,1 6,2 6,3 6,4 6,5 6,6 6,7 6,8
7,0 7,1 7,2 7,3 7,4 7,5 7,6 7,7 7,8
8,0 8,1 8,2 8,3 8,4 8,5 8,6 8,7 8,8
>>>]
# Utiliser une ou plusieurs boucles [c for] pour afficher le caractère [c *] de façon à produire des formes géométriques~ :
@ -194,7 +196,7 @@ Même si [c for] est utilisée beaucoup moins souvent que [c foreach] en pratiqu
********
>>>]
etc.
etc.
[[part:corrections/for | … Les solutions]]
]

View File

@ -1,6 +1,7 @@
[set
title = "Boucle [c foreach]"
partAs = chapitre
title = "Boucle [c foreach]"
partAs = chapitre
translator = "Raphaël Jakse"
]
Une des structures de contrôle les plus communes du D est la boucle [c foreach]. Elle est utilisée pour appliquer la même opération à tous les éléments d'un conteneur (ou d'un intervalle).
@ -117,7 +118,7 @@ Une partie du pouvoir de [c foreach] vient du fait qu'elle peut être utilisée
0: a
1: b
2: c
3:
3:
4: <20>
5: d
>>>]
@ -145,7 +146,7 @@ Une partie du pouvoir de [c foreach] vient du fait qu'elle peut être utilisée
>>>]
J'expliquerais ci-après pourquoi cette boucle ne pourrait pas inclure de compteur automatique.
]
[ = [c foreach] avec les tableaux associatifs
@ -273,7 +274,7 @@ Une partie du pouvoir de [c foreach] vient du fait qu'elle peut être utilisée
Avant : [1.2, 3.4, 5.6]
Après : [1.2, 3.4, 5.6]
>>>]
Ceci s'explique par le fait que [c nombre] n'est pas un élément du tableau, mais une copie d'élément. Quand on a besoin de modifier les éléments eux-même, le nom doit être défini comme une référence à l'élément par le mot-clé [c ref] :
[code=d <<<

View File

@ -1,6 +1,8 @@
[set
title = "''Hello World'' !"
partAs = chapitre
title = "''Hello World'' !"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Le premier programme montré dans la plupart des livres qui présentent un langage de programmation est le programme ''hello world''. C'est un programme très simple et très court qui affiche "hello world" et qui se termine (NdT~ : "hello world" signifie "bonjour le monde"). Ce programme est important parce qu'il présente quelques concepts essentiels de ce langage.

View File

@ -1,6 +1,8 @@
[set
title = "Instruction [c if]"
partAs = chapitre
title = "Instruction [c if]"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Nous avons appris que ce que fait le programme est effectué par les expressions. Toutes les expressions de tous les programmes que nous avons vu jusqu'à maintenant ont commencé avec la fonction [c main] et étaient exécutés jusqu'à la fin de [c main].
@ -15,7 +17,7 @@ Les instructions, d'un autre côté, sont des éléments qui affectent l'exécut
[c if] prend une expression logique entre parenthèses. Si la valeur de cette expression logique est [c true], alors il exécute les expressions qui sont dans les accolades qui suivent. À l'inverse, si l'expression logique est [c false], les expressions entre accolades ne seront pas exécutées.
L'étendue entre accolades est appelée [* bloc].
Voici la syntaxe de l'instruction [c if]~ :
@ -205,7 +207,7 @@ Les instructions, d'un autre côté, sont des éléments qui affectent l'exécut
writeln("Boire de la limonade");
writeln("Laver le verre");
} else
} else
writeln("Manger de la tarte");
writeln("Laver l'assiette");
}

View File

@ -1,6 +1,7 @@
[set
title = "Introduction"
partAs = chapitre
title = "Introduction"
partAs = chapitre
translator = "Raphaël Jakse"
]
Cet ouvrage a pour but d'enseigner le langage D aux lecteurs novices en programmation. Même si de l'expérience dans d'autres langages de programmation faciliterait les choses, ce livre commence de zéro. Si vous êtes intéressé-e par apprendre à programmer, j'espère que vous trouverez ce livre utile.

View File

@ -1,6 +1,6 @@
[set
title = "Programmer en D"
author = "Ali Çehreli, traduit par Raphaël Jakse"
author = "Ali Çehreli"
lang = "french"
showSummary = true
]

View File

@ -1,6 +1,8 @@
[set
title = "Littéraux"
partAs = chapitre
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.
@ -99,11 +101,11 @@ De telles valeurs écrites littéralement dans le code source sont appelées lit
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
[ = 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].
]
@ -112,7 +114,7 @@ De telles valeurs écrites littéralement dans le code source sont appelées lit
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.
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~ ».
@ -136,10 +138,10 @@ De telles valeurs écrites littéralement dans le code source sont appelées lit
[ = 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
@ -168,11 +170,11 @@ De telles valeurs écrites littéralement dans le code source sont appelées lit
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~ :
@ -191,13 +193,13 @@ De telles valeurs écrites littéralement dans le code source sont appelées lit
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~ :
@ -244,17 +246,17 @@ De telles valeurs écrites littéralement dans le code source sont appelées lit
]
]
[ = 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 <<<
@ -264,7 +266,7 @@ De telles valeurs écrites littéralement dans le code source sont appelées lit
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
>>>]

View File

@ -1,6 +1,7 @@
[set
title = "L'environnement du programme"
partAs = chapitre
title = "L'environnement du programme"
partAs = chapitre
translator = "Raphaël Jakse"
]
Nous avons vu que [c main] est une fonction. L'exécution du programme commence par [c main] et continue avec d'autres fonction depuis là. La définition de [c main] que nous avons utilisé jusqu'à maintenant est :
@ -27,7 +28,7 @@ Selon cette définition, [c main] ne prent pas de paramètre et ne retourne pas
De plus, même si les exemples suivant affichent des interactions dans une console Linux, elles seraient similaire mais pas exactement le même dans des consoles d'autres systèmes d'exploitation.
[code <<<
# ls un_fichier_qui_nexiste_pas
ls: impossible d'accéder à un_fichier_qui_nexiste_pas: Aucun fichier ou dossier de ce type
@ -179,8 +180,8 @@ Selon cette définition, [c main] ne prent pas de paramètre et ne retourne pas
Le premier argument est toujours le nom du programme, tel que l'utilisateur l'a écrit. Les autres arguments apparaissent dans le même ordre dans lequel ils ont été saisis.
Comment sont utilisés les arguments appartient complètement au programme. Le programme suivant affiche ses deux arguments dans l'ordre inverse :
Comment sont utilisés les arguments appartient complètement au programme. Le programme suivant affiche ses deux arguments dans l'ordre inverse :
[code=d <<<
import std.stdio;
@ -265,7 +266,7 @@ Selon cette définition, [c main] ne prent pas de paramètre et ne retourne pas
La plupart des options en lignes de commande de la plupart des programmes ont aussi des syntaxes plus courte. Par exemple, [c -c] peut avoir le même sens que [c --nombre]. Une syntaxe alternative pour chaque option peut être spécifié après un caractère [c > |]. Il peut y avoir plus d'un raccourci par option :
[code=d <<<
[code=d <<<
getopt(args,
"nombre$(HILITE |c)", &nombre,
"minimum$(HILITE |n)", &minimum,
@ -274,7 +275,7 @@ Selon cette définition, [c main] ne prent pas de paramètre et ne retourne pas
Il est commun d'utiliser un seul tiret pour la version courte et le caractère [c =] est généralement omis.
[code <<<
# ./deneme -c7 -n10 -x15
11 13 10 15 14 15 14
@ -422,6 +423,6 @@ Selon cette définition, [c main] ne prent pas de paramètre et ne retourne pas
[p Note : | Parce que le caractère [c *] a une signification spéciale sur la plupart des consoles, j'ai utilisé [c x]. Vous pouvez toujours utiliser [c *] tant qu'il est échappé : [c \*] (NdT: ou [c "*"]).]
]
# Écrivez un programme qui demande à l'utilisateur quel programme lancer, démarre ce programme et retourne sa valeur de retour.
[[part:corrections/main | … Les solutions]]
]

View File

@ -1,6 +1,8 @@
[set
title = "Quelques notes avant de lire…"
partAs = chapitre
title = "Quelques notes avant de lire…"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
[ = Remerciements de l'auteur original ([[http://acehreli.org|Ali Çehreli]])

View File

@ -1,6 +1,7 @@
[set
title = "La valeur [c null] et l'Opérateur [c is]"
partAs = chapitre
title = "La valeur [c null] et l'Opérateur [c is]"
partAs = chapitre
translator = "Raphaël Jakse"
]
Dans le chapitre précédent, nous avons vu qu'une variable d'un type référence n'a pas besoin de référencer un objet :

View File

@ -1,6 +1,7 @@
[set
title = "Opérateurs paresseux (''lazy'')"
partAs = chapitre
title = "Opérateurs paresseux (''lazy'')"
partAs = chapitre
translator = "Raphaël Jakse"
]
L'évaluation paresseuse consiste a délayer l'exécution d'expressions au moment où on a besoin du résultat de ces expressions. Les évaluations paresseuses font partie des fonctionnalités de base de certains langages de programmation.
@ -24,16 +25,16 @@ Une idée qui est similaire à l'évaluation paresseuse est le comportement de c
// ...
}
>>>]
Si le résultat de [c uneExpression()] est [c false], le résultat de l'expression [c &&] est aussi fausse et la seconde expression n'est pas évaluée.
- L'opérateur ternaire [c ?:] : Soit la première, soit la deuxième expression est évaluée selon si la condition est vraie ou fausse, respectivement.
[code=d <<<
int i = condition() ? SoitCeli() : ouCela();
>>>]
La paresse de ces opérateurs n'est pas seulement une affaire de performance. Parfois, évaluer une des expressions peut être une erreur.
Par exemple, vérifier la condition [c si la première lettre est A] ci-après serait une erreur quand la chaîne est vide :

View File

@ -1,6 +1,7 @@
[set
title = "Les paramètres de fonction"
partAs = chapitre
title = "Les paramètres de fonction"
partAs = chapitre
translator = "Raphaël Jakse"
]
Ce chapitre couvre les différentes manières de définir des paramètres de fonction.
@ -393,7 +394,7 @@ Cette fonction calcule la note moyenne en prenant 40% de la note du quiz et 60%
Error: cannot implicitly convert expression (tranche) of type
const(int)[] to int[]
>>>]
On pourrait croire que spéficier le type de retour comme [c const(int)~[~]] peut être la solution :
[code=d <<<
@ -428,7 +429,7 @@ Cette fonction calcule la note moyenne en prenant 40% de la note du quiz et 60%
return tranche;
}
>>>]
Avec ce changement, la même fonction peut maintenant être appelée avec les tranches [c mutable], [c const] et [c immutable] :
[code=d <<<
@ -655,7 +656,7 @@ Cette fonction calcule la note moyenne en prenant 40% de la note du quiz et 60%
foo(nombres); // ← ERREUR de compilation
}
>>>]
Le programme ci-avant ne peut pas être compilé parce que l'argument n'est pas partagé. Le programme peut être compilé avec les changements suivant :
[code=d <<<

View File

@ -1,6 +1,7 @@
[set
title = "L'art de la programmation"
partAs = chapitre
title = "L'art de la programmation"
partAs = chapitre
translator = "Raphaël Jakse"
]
La définition de l'art de la programmation est quelque peu discutable, mais son aspect ''conception'' est très important. Quelques idées sur la programmation :
@ -14,8 +15,8 @@ La définition de l'art de la programmation est quelque peu discutable, mais son
[ = Programmer peut être très difficile à apprendre et à enseigner.
La programmation a été enseignée depuis les années 1950. Il n'y a toujours pas de méthode efficace et fructueuse pour le faire à ce jour.
Malheureusement, apprendre à programmer peut être une tâche difficile pour une bonne moitié de tous les étudiants. Selon un [[http://www.cs.mdx.ac.uk/research/PhDArea/saeed/paper1.pdf | article de la recherche]], ceux qui peuvent apprendre à programmer facilement sont ceux qui sont capable de créer des ''modèles consistants'' pour décrire les situations inconnues qu'ils rencontrent.
Certaines difficultés en programmation viennent de la quantité de détails techniques qu'il est nécessaire d'apprendre.
]

View File

@ -1,6 +1,8 @@
[set
title = "Rediriger les flux d'entrée et de sortie standards"
partAs = chapitre
title = "Rediriger les flux d'entrée et de sortie standards"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Tous les programmes que nous avons vu jusqu'à maintenant interagissaient à travers [c stdin] et [c stdout], respectivement le flux d''entrée standard et le flux de sortie standard. Par défaut, les fonctions d'entrée et de sortie comme [c readf] et [c writeln] opèrent sur ces flux.
@ -63,7 +65,7 @@ Avant de voir comment on accède aux fichiers depuis les programmes, je voudrais
>>>]
Cette fois, le programme lira depuis [c par_deux_resultat.txt] et affichera le résultat [c 0.24] à la console.
]
[ = Rediriger les deux flux standard

View File

@ -1,9 +1,10 @@
[set
title = "Portées ([c scope])"
partAs = chapitre
title = "Portées ([c scope])"
partAs = chapitre
translator = "Raphaël Jakse"
]
Comme nous l'avons vu, les expressions qui doivent toujours être exécutées sont écrites dans le bloc [c finally], et les expressions qui doivent être exécutées quand il y a des conditions d'erreurs sont écrites dans des blocs [c catch].
Comme nous l'avons vu, les expressions qui doivent toujours être exécutées sont écrites dans le bloc [c finally], et les expressions qui doivent être exécutées quand il y a des conditions d'erreurs sont écrites dans des blocs [c catch].
On peut faire les observations suivantes sur l'utilisation de ces blocs :
- [c catch] et [c finally] ne peuvent pas être utilisés sans un bloc [c try].
@ -36,7 +37,7 @@ Les instructions [c scope] ont la même fonctionnalité que les blocs [c catch]
- [c scope(exit)] : l'expression est toujours exécutée lorsqu'on quite la portée, que ce soit normalement ou à cause d'une exception.
- [c scope(success)] : l'expression n'est exécutée que si l'on quitte la portée normalement.
- [c scope(failure)] : l'expression n'est exécutée que si l'on quitte la portée à cause d'une exception.
Même si ces instructions sont proches du mécanisme des exceptions, elles peuvent être utilisées sans bloc [c try-catch].
Comme exemple, écrivons la fonction c-avant avec une instruction [c scope(failure)] :
@ -103,4 +104,4 @@ Si une exception est levée, la sortie inclue les expressions [c scope(exit)] et
object.Exception@...: the error message
>>>]
Comme on peut le constater, les blocs des instructions [c scope] sont exécutés dans l'ordre inverse. C'est parce que du code plus bas peut dépendre de variables précédentes. Exécuter les instructions [c scope] dans l'ordre inverse permet d'annuler des effets de bords d'expressions précédentes dans un ordre consistant.
Comme on peut le constater, les blocs des instructions [c scope] sont exécutés dans l'ordre inverse. C'est parce que du code plus bas peut dépendre de variables précédentes. Exécuter les instructions [c scope] dans l'ordre inverse permet d'annuler des effets de bords d'expressions précédentes dans un ordre consistant.

View File

@ -1,6 +1,8 @@
[set
title = "Sortie formatée"
partAs = chapitre
title = "Sortie formatée"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Ce chapitre traite des fonctionnalités du module [c std.format] de Phobos, et non des fonctionnalités du langage D lui-même. Les indicateurs de formatage d'entrée et de sortie du D sont similaires à ceux du C. Avant d'aller plus loin, je voudrais résumer ici les indicateurs de format et les drapeaux~ :
@ -90,7 +92,7 @@ Du fait que [c %] a une signification spécifique dans les chaînes de formatage
[code=d <<<
int valeur = 12;
writefln("Binaire : %b", valeur);
writefln("Octal : %o", valeur);
writefln("Hexadécimal : %x", valeur);
@ -118,9 +120,9 @@ Du fait que [c %] a une signification spécifique dans les chaînes de formatage
- [c f] et [c F]~ : le paramètre flottant est affiché dans le système décimal~ ; il y a au moins un chiffre avant le point et la précision par défaut est 6.
- [c g]~ : pareil que [c f] si l'exposant est entre -5 et ''précision''~ ; sinon pareil que [c e]. ''précision'' n'indique pas le nombre de chiffres après le point, mais les chiffres significatifs de la valeur complète [comment <<< «valeur entière», c'est source de confusion. >>>]. S'il n'y a pas de chiffres significatifs après le point, le point n'est pas affiché. Les zéros les plus à droite après le point ne sont pas affichés.
- [c G]~ : pareil que pour [c g] mais avec [c E] ou [c F].
- [c a]~ : le paramètre en virgule flottante est affiché dans le format flottant hexadécimal~ :
- les caractères [c 0x]~ ;
@ -219,7 +221,7 @@ Du fait que [c %] a une signification spécifique dans les chaînes de formatage
1234.56789000
1234.568
>>>]
[code=d <<<
auto nombre = 0.123456789;
writefln("Nombre : %.*g", 4, nombre);
@ -248,13 +250,13 @@ Du fait que [c %] a une signification spécifique dans les chaînes de formatage
>>>]
- [c +]~ : si la valeur est positive, elle est préfixée par le caractère [c +]~ ; ce drapeau annule le drapeau espace.
[code=d <<<
writefln("Pas d'effet sur les valeurs négatives : %+d", -50);
writefln("Valeur positive avec le drapeau + : %+d", 50);
writefln("Valeur positive sans le drapeau + : %d", 50);
>>>]
[output <<<
Pas d'effet sur les valeurs négatives : -50
Valeur positive avec le drapeau + : +50
@ -267,7 +269,7 @@ Du fait que [c %] a une signification spécifique dans les chaînes de formatage
- [c x] et [c X]~ : si la valeur n'est pas zéro, elle est préfixée avec [c 0x] ou [c 0X]~ ;
- virgules flottantes~ : un point est affiché même s'il n'y a pas de chiffres significatifs après le point~ ;
- [c g] et [c G]~ : même les zéros non significatifs après le point sont affichés.
[code=d <<<
writefln("L'octal commence par un 0 : %#o", 1000);
writefln("L'hexadécimal commence par 0x : %#x", 1000);
@ -337,7 +339,7 @@ Du fait que [c %] a une signification spécifique dans les chaînes de formatage
>>>]
Supposons que le programme doive aussi prendre en charge le turc. La chaîne de formatage doit alors être choisie en fonction de la langue choisie. La méthode suivante utilise l'opérateur ternaire~ :
[code=d <<<
auto format = (langue == "fr"
 ? "Il y a %s étudiants dans la classe %s."
@ -375,7 +377,7 @@ Du fait que [c %] a une signification spécifique dans les chaînes de formatage
La sortie formatée est également utilisable avec la fonction [c format()] du module [c std.string]. [c format()] fonctionne de la même manière que [c writef()] mais retourne le résultat dans une chaîne au lieu de l'afficher~ :
[code=d <<<
[code=d <<<
import std.stdio;
import std.string;

View File

@ -1,6 +1,7 @@
[set
title = "Structures"
partAs = chapitre
title = "Structures"
partAs = chapitre
translator = "Raphaël Jakse"
]
Comme nous l'avons vu plusieurs fois dans les précédents chapitres de ce livre, les types fondamentaux ne sont pas suffisant pour représenter des concepts de plus haut niveau. Par exemple, même si une valeur de type [c int] est adaptée pour représenter une heure de la journée, deux variables [c int] seraient ensemble plus adaptées pour représenter un point dans le temps : une pour l'heure, une pour la minute.

View File

@ -1,6 +1,7 @@
[set
title = "Surcharge de fonctions"
partAs = "chapitre"
title = "Surcharge de fonctions"
partAs = "chapitre"
translator = "Olivier Pisano"
]
On appelle surcharger une fonction le fait de définir plusieurs fonctions ayant toutes le même nom. Pour pouvoir les différentier, leurs paramètres doivent être différents.

View File

@ -1,6 +1,7 @@
[set
title = "[c switch] et [c case]"
partAs = chapitre
title = "[c switch] et [c case]"
partAs = chapitre
translator = "Raphaël Jakse"
]
[c switch] est une structure qui permet de comparer la valeur d'une expression avec de multiples valeurs spéciales. Elle est similaire à une chaîne "if, else if, else" mais fonctionne un peu différemment. [c case] est utilisé pour spécifier les valeurs à comparer avec l'expression du [c switch]. [c case] fait partie de la structure [c switch] et n'est pas une structure en lui-même.
@ -143,7 +144,7 @@ Si une valeur [c case] correspond à la valeur de l'expression du [c switch], al
--- valeur : 20 ---
default
>>>]
]
[ = Le type de l'expression doit être entière, une chaîne ou un booléen

View File

@ -1,6 +1,8 @@
[set
title = "Tableaux"
partAs = chapitre
title = "Tableaux"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Nous avons défini 5 variables dans un des exercices du dernier chapitre et les avons utilisés dans certains calculs. Les définitions de ces variables étaient les suivantes~ :
@ -59,7 +61,7 @@ Le type des variables peut aussi être un type défini par le programmeur (nous
[ = Éléments et conteneurs
Les structures de données qui rassemblent des éléments d'un certain type sont appelés [** conteneurs]. Selon cette définition, les tableaux sont des conteneurs. Par exemple, un tableau qui stocke les températures de l'air des jours de juillet peut rassembler 31 variables [c double] et forme un conteneur d'éléments de type [c double].
Les variables d'un conteneur sont appelés éléments. Le nombre d'élements d'un tableau est appelé la longueur d'un tableau.
]
@ -220,7 +222,7 @@ Le type des variables peut aussi être un type défini par le programmeur (nous
Comme vous pouvez le voir, le tableau joursDuMois est défini et initialisé au même moment. Notez aussi que le numéro du mois, qui est entre 1 et 12, est converti en un indice valide entre 0 et 11. Toute valeur entrée en dehors de l'intervalle 1-12 entraînerait l'arrêt du programme avec une erreur.
Quand on initialise des tableaux, il est possible d'utiliser une seule valeur sur le côté droit. Dans ce cas, tous les éléments du tableau sont initialisés à cette valeur~ :
[code=d <<<
int[10] tousUn = 1; // Tous les éléments valent 1
>>>]
@ -228,7 +230,7 @@ Le type des variables peut aussi être un type défini par le programmeur (nous
]
[ = Opérations basiques sur les tableaux
Les tableaux proposent des opérations pratiques qui s'appliquent à tous leurs éléments.
Les tableaux proposent des opérations pratiques qui s'appliquent à tous leurs éléments.
- [ Copier des tableaux à taille fixe~ : l'opérateur d'affectation copie tous les éléments du tableau de droite dans le tableau de gauche~ :
[code=d <<<
@ -371,7 +373,7 @@ Le type des variables peut aussi être un type défini par le programmeur (nous
void main()
{
int[5] carres;
writeln("Veuillez entrer 5 nombres");
int i = 0;
@ -383,7 +385,7 @@ Le type des variables peut aussi être un type défini par le programmeur (nous
carres[i] = nombre * nombre;
++i;
}
writeln("=== Les carrés des nombres ===");
while (i <= carres.length)
{

View File

@ -1,6 +1,8 @@
[set
title = "Tableaux associatifs"
partAs = chapitre
title = "Tableaux associatifs"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Les tableaux associatifs sont une fonctionnalité que l'on trouve dans la plupart des langages modernes de haut niveau. Ils constituent une structure de données très rapide qui fonctionne comme une mini base de données et sont couramment utilisés dans beaucoup de programmes.
@ -163,7 +165,7 @@ La sortie~ :
[ = Exemple
Voici un programme qui affiche les noms turcs des couleurs qui sont indiqués en français~ :
Voici un programme qui affiche les noms turcs des couleurs qui sont indiqués en français~ :
[code=d <<<
import std.stdio;

View File

@ -1,6 +1,8 @@
[set
title = "L'opérateur ternaire [c ?:]"
partAs = chapitre
title = "L'opérateur ternaire [c ?:]"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
L'opérateur ternaire [c ?:] a un fonctionnement très similaire de celui de l'instruction [c if-else]~ :
@ -63,7 +65,7 @@ Les exemples suivant comparent l'opérateur [c ?:] et l'instruction [c if-else].
>>>]
]
- [
[p Affichage. |
Afficher un message différemment selon une condition~ :
]

View File

@ -1,6 +1,7 @@
[set
title = Tests unitaires
partAs = chapitre
title = Tests unitaires
partAs = chapitre
translator = "Raphaël Jakse"
]
Les gens devraient, pour la plupart, en être conscients : toute machine contenant du code d'un programme contient des bogues logiciels. Les bogues logiciels menacent les systèmes informatiques du plus simple au plus complexe. Débogguer et corriger les bugs logiciels font partie des activités quotidiennes les moins agréables d'un programmeur.
@ -23,7 +24,7 @@ Les gens devraient, pour la plupart, en être conscients : toute machine conten
[ = Découvrir les bogues
Les bogues logiciels sont découverts à différents moment dans la vie du programme avec différents types d'outils ou de personnes. Ce qui suit est une liste partielle de moments pouvant correspondre à la découverte d'un bogue, du plus tôt au plus tard :
- Lors de l'écriture du programme
- par le programmeur
- par le programmeur
- par un autre programmeur pendant une session de [* programmation en binôme]
- par le compilateur, qui va afficher des messages lors de la compilation
- par les [** tests unitaires], lors de la construction du programme
@ -50,9 +51,9 @@ Les gens devraient, pour la plupart, en être conscients : toute machine conten
Le test unitaire permet aussi la refactorisation du code (c.-à-d. l'améliorer) avec facilité et confiance. Autrement, il est courant de casser une fonctionnalité existante d'un programme lors d'un ajout de nouvelles fonctionnalités. Des bogues de ce type sont appelés [* régressions]. Sans test unitaire, les régressions ne sont des fois découvertes que lors des tests de qualité des nouvelles versions ou pire, par les utilisateurs finaux.
Le risque de régression découragent les programmeurs de refactoriser le code, ce qui les empêche parfois d'apporter la plus simple des améliorations comme corriger le nom d'une variable. Ceci entraîne le [* pourrissement du code], une situation dans laquelle le code devient de moins en moins maintenable. Par exemple, même si quelques lignes de code feraient mieux d'être bougées dans une nouvelle fonction pour être appelées depuis plusieurs endrois, la peur de créer des régressions fait que les programmeurs vont plutôt copier-coller les lignes, ce qui entraîne le problème de la [* duplication de code].
Les phrases du type « Si ce n'est pas cassé, ne le corrigez pas » viennent de la peur des régressions. Même si elles semblent transmettre la sagesse, de telles lignes de conduites entraînent, lentement mais sûrement, le pourrissement du code et celui-ci devient un bazar sans nom.
Les phrases du type « Si ce n'est pas cassé, ne le corrigez pas » viennent de la peur des régressions. Même si elles semblent transmettre la sagesse, de telles lignes de conduites entraînent, lentement mais sûrement, le pourrissement du code et celui-ci devient un bazar sans nom.
La programmation moderne rejette une telle « sagesse ». Au contraire, pour l'empêcher de devenir une source de bogues, le code est supposé être « refactorisé sans merci »? L'outil le plus important de cette approche moderne est le test unitaire.
Le test unitaire implique le test des plus petites unité de code indépendamment. Quand chaque unité de code est testé de façon indépendante, il est moins probable que des bogues apparaissent dans des codes de plus haut niveaux qui utilisent ces unités. Quand les parties fonctionnent correctement, il est plus probable que l'ensemble fonctionnera également.
@ -89,8 +90,8 @@ Les gens devraient, pour la plupart, en être conscients : toute machine conten
Même si les blocs [c unittest] peuvent apparaître n'importe où, il est pratique de les définir juste après le code qu'ils teste.
Par exemple, testons une fonction qui retourne la forme ordinale du nombre spécifié, comme dans "1er", "2nd", etc. Un bloc [c unittest] de cette fonction pourrait simplement contenir des instructions [c assert] qui comparent les valeurs de retours de la fonction aux valeurs attendues. La fonction suivante est testée avec les 3 formes de résultats de cette fonction :
Par exemple, testons une fonction qui retourne la forme ordinale du nombre spécifié, comme dans "1er", "2nd", etc. Un bloc [c unittest] de cette fonction pourrait simplement contenir des instructions [c assert] qui comparent les valeurs de retours de la fonction aux valeurs attendues. La fonction suivante est testée avec les 3 formes de résultats de cette fonction :
[code=d <<<
string ordinal(size_t nombre)
{
@ -132,7 +133,7 @@ Les gens devraient, pour la plupart, en être conscients : toute machine conten
[ = Développement piloté par les tests (''Test Driven Development (TDD)'')
Le développement piloté par les tests est une méthode de développement logiciel qui prescrit l'écriture de tests unitaires avant d'implémenter une fonctionnalité. En TDD, on se concentre sur le test unitaire. Coder est une activité secondaire qui fait passer les tests.
En accord avec le TDD, la fonction [c ordinal] ci-avant peut d'abord être implémenté incorrectement de façon intentionnelle :
[code=d <<<
@ -158,7 +159,7 @@ Les gens devraient, pour la plupart, en être conscients : toute machine conten
[code <<<
$ dmd deneme.d -w -O -unittest
$ ./deneme
$ ./deneme
core.exception.AssertError@deneme.d(10): unittest failure
>>>]
@ -318,4 +319,4 @@ Les gens devraient, pour la plupart, en être conscients : toute machine conten
{}
>>>]
[[part:corrections/tests_unitaires | … La solution]]
]
]

View File

@ -1,6 +1,8 @@
[set
title = "Tranches (''slices'') et autres fonctionnalités des tableaux"
partAs = chapitre
title = "Tranches (''slices'') et autres fonctionnalités des tableaux"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Nous avons vu dans le [[part:tableaux | chapitre sur les tableaux]] comment les éléments sont groupés comme une collection dans un tableau. Ce chapitre a été volontairement bref, laissant à ce chapitre-ci la plupart des fonctionnalités des tableaux.
@ -60,7 +62,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
Chaque tranche modifie son premier élément, et l'élément correspondant dans le tableau est affecté.
Nous avons vu plus tôt que les indices valides des tableaux vont de 0 à la taille du tableau moins un. Par exemple, les indices valides d'un tableau à trois éléments sont 0, 1 et 2. De manière similaire, l'indice de fin dans la syntaxe de la tranche est l'indice de l'élément qui est juste après le dernier élément auquel la tranche donne accès. Par exemple, une tranche de tous les élements d'un tableau à trois éléments serait [c <<<tableau[0..3]>>>].
Évidemment, l'indice de début ne peut pas être plus grand que l'indice de fin~ :
[code=d <<<
@ -129,7 +131,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
[code=d <<<
int[3] a = [ 1, 1, 1 ];
int[3] b = [ 2, 2, 2 ];
a = b; // les éléments de 'a' deviennent 2
writeln(a);
>>>]
@ -150,7 +152,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
tranche = pairs[1 .. $ - 1];
writeln(tranche);
>>>]
Ci-dessus, la tranche ne donne accès à aucun élément lors de sa définition. Ensuite, elle est utilisée pour donner accès à certains éléments de [c impairs] et ensuite à certains éléments de [c pairs]~ :
[code=d <<<
@ -162,7 +164,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
[ = Agrandir une tranche plus longue peut finir le partage
Comme la longueur d'un tableau à taille fixe ne peut pas être changée, l'idée de fin de partage ne concerne que les tranches.
Il est possible d'accéder aux mêmes éléments par plus d'une tranche. Par exemple, on accède aux deux premiers des huits éléments ci-dessous à travers trois tranches~ :
[code=d <<<
@ -181,7 +183,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
writeln(tranche);
}
>>>]
L'effet de la modification du second élément de [c quart] se remarque sur toutes les tranches~ :
[code=d <<<
@ -191,7 +193,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
>>>]
Vu sous cet angle, les tranches donnent un accès partagé aux éléments. Ce partage pose la question de ce qu'il arrive quand un nouvel élément est ajouté à une des tranches. Comme les tranches donnent accès au même élément, il pourrait ne plus y avoir de place pour ajouter des éléments à une tranche sans rentrer en conflit avec les autres.
D répond à cette question en finissant le partage s'il n'y a pas de place pour le nouvel élément~ : la tranche qui n'a pas de place pour grandir abandonne le partage. Quand cela arrive, tous les éléments existants de cette tranche sont copiés à un nouvel endroit automatiquement et la tranche commence à donner accès à ces nouveaux éléments.
Pour voir ceci en action, ajoutons un élément à [c quart] avant de modifier son second élément~ :
@ -211,7 +213,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
[1, 3, 5, 7]
[1, 3, 5, 7, 9, 11, 13, 15]
>>>]
Augmenter la taille de la tranche de façon explicite lui fait également abandonner le partage~ :
[code=d <<< ++quart.length; // Abandonne le partage >>>]
@ -243,7 +245,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
--d.length; // idem
d.length = d.length - 1; // idem
>>>]
Le partage des éléments est toujours là.
]
@ -350,7 +352,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
a[] = 42;
writeln(a);
>>>]
[output <<<[42, 42, 42]>>>]
Cette fonctionnalité nécessite une attention particulière quand elle est utilisée avec les tranches. Même s'il n'y a pas de différence apparente dans les valeurs des éléments, les deux expression suivantes ont un sens très différent :
@ -360,7 +362,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
tranche2 = tranche1; // ← tranche2 donne maintenant accès
// aux mêmes éléments que tranche1
tranche3[] = tranche1; // ← les valeurs des éléments
tranche3[] = tranche1; // ← les valeurs des éléments
// de tranche3 changent
>>>]
@ -398,7 +400,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
writeln("tranche3 après : ", tranche3);
}
>>>]
La modification depuis ``tranche2`` affecte ``tranche1`` également~ :
[output <<<
@ -416,7 +418,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
[ = Tableaux multidimensionnels
Jusqu'à maintenant nous avons utilisé les tableaux avec des types fondamentaux comme ``int`` ou ``double`` uniquement. Le type d'élément peut en fait être n'importe quel autre type, notamment d'autres tableaux. Cela permet au programmeur de définir des conteneurs complexes comme des tableaux de tableaux. Les tableaux de tableaux sont appelés tableaux multidimensionnels.
Tous les éléments de tous les tableaux que nous avons définis jusqu'à présent ont été écrits dans le code source de gauche à droite. Pour aider à comprendre l'idée de tableau bidimensionnel, définissons cette fois-ci un tableau de haut en bas~ :
[code=d <<<
@ -429,7 +431,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
>>>]
Comme vous devez vous en souvenir, la plupart des espaces dans le code source sont là pour rendre le code lisible et ne changent pas sa signification. Le tableau ci-dessus aurait pu être défini sur une seule ligne et aurait eu, le cas échéant, la même signification.
Remplaçons maintenant chaque élément de ce tableau par un autre tableau~ :
[code=d <<<
@ -476,7 +478,7 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
Par exemple, le nombre d'objets dans la première pièce du deuxième étage peut être incrémenté de cette manière :
[code=d <<<
// L'indice du deuxième étage est 1 et on accède à
// L'indice du deuxième étage est 1 et on accède à
// la première pièce de cet étage par [0][0]
++nombresObjets[1][0][0];
>>>]
@ -522,11 +524,11 @@ Quand j'écrirai ''slice'', je désignerai précisément une tranche. Quand j'é
[code=d <<<
[1, 10, 2, 15, 7, 5.5]
>>>]
Même s'il y a beaucoup de solutions à ce problème, essayez de n'utiliser que les fonctionnalités des tranches. Vous pouvez commencer avec une tranche qui donne accès à tous les éléments. Ensuite, vous pouvez réduire la tranche depuis le début et ne travailler que sur le premier élément.
L'expression suivante réduit la tranche depuis le début~ :
[code=d <<<
tranche = tranche[1 .. $];
>>>]

View File

@ -1,6 +1,8 @@
[set
title = "Types fondamentaux"
partAs = chapitre
title = "Types fondamentaux"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Nous avons vu que le cerveau d'un ordinateur est le CPU. La plupart des tâches d'un programme sont effectuées par le CPU et le reste est dispatché aux autres parties de l'ordinateur.

View File

@ -1,6 +1,7 @@
[set
title = Types valeur et types référence
partAs = chapitre
title = Types valeur et types référence
partAs = chapitre
translator = "Raphaël Jakse"
]
Ce chapitre introduit les notions de types valeur et types référence. Ces notions sont particulièrement importantes pour comprendre les différence entre les structures et les classes.
@ -51,7 +52,7 @@ Le chapitre se clôt avec un tableau qui contient les résultats des deux types
[code=d <<<
vitesse = 200;
>>>]
La valeur de l'autre variable ne change pas :
[code=d <<<
@ -220,7 +221,7 @@ Le chapitre se clôt avec un tableau qui contient les résultats des deux types
- Les variables par référence n'ont pas d'identité, elles sont de alias de variables existantes.
- Les variables de types référence ont une identité mais n'ont pas de valeur propre ; elles donnent accès a des valeurs existantes.
La manière par laquelle [c tranche] et [c tranche2] vivent en mémoire peut être illustrée comme suit :
[code <<<
@ -553,4 +554,4 @@ Le chapitre se clôt avec un tableau qui contient les résultats des deux types
- Les variables de types référence ont leurs propres adresses mais les valeurs qu'elles référencent ne leur appartiennent pas.
- Avec les types référence, l'affectation ne change pas la valeur, elle change quelle valeur est pointée.
- Les variables de types référence peuvent être nulles.
]
]

View File

@ -1,6 +1,8 @@
[set
title = "Variables"
partAs = chapitre
title = "Variables"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Les concepts concrets qui sont représentés dans un programme sont appelés [* variable]. Une valeur comme la température de l'air ou un objet plus compliqué comme un moteur de voiture peuvent être des variables d'un programme.

View File

@ -1,6 +1,8 @@
[set
title = "Types à virgule flottante"
partAs = chapitre
title = "Types à virgule flottante"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Dans le chapitre précédent, nous avons vu que malgré leur facilité d'utilisation, les opérations arithmétiques sur les entiers sont sujettes à des erreurs de programmations à cause des débordements, des soupassements et des troncages. Nous avons aussi vu que les entiers ne peuvent pas représenter des valeurs avec des parties fractionnaires comme 1,25.

View File

@ -1,6 +1,8 @@
[set
title = "Boucle [c while] (Tant que)"
partAs = chapitre
title = "Boucle [c while] (Tant que)"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
La boucle [c while] est similaire à l'instruction [c if] et fonctionne essentiellement comme une instruction [c if] répétée. Tout comme [c if], [c while] prend aussi une expression logique et évalue le bloc quand l'expression logique est vraie. La différence est que l'instruction [c while] évalue l'expression et exécute le bloc encore, tant que l'expression est vraie, pas qu'une fois. Répéter un bloc de code de cette manière est appelé «~ boucler~ ».

View File

@ -1,6 +1,8 @@
[set
title = "[c writeln] et [c write]"
partAs = chapitre
title = "[c writeln] et [c write]"
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Dans le chapitre précédent, nous avons vu que [c writeln] prend une chaîne de caractères entre parenthèses et affiche la chaîne.
@ -20,7 +22,7 @@ Note : le mot "paramètre" décrit l'information qui est passée à une fonction
}
>>>]
Parfois, toutes les informations qui doivent être affichées sur la même ligne peuvent ne pas être disponibles au même moment. Dans de tels cas, les premières parties de la ligne peuvent être affichées avec [c write] et la dernière partie de la ligne peut être affichée avec [c writeln].
Parfois, toutes les informations qui doivent être affichées sur la même ligne peuvent ne pas être disponibles au même moment. Dans de tels cas, les premières parties de la ligne peuvent être affichées avec [c write] et la dernière partie de la ligne peut être affichée avec [c writeln].
[c writeln] passe à la ligne, [c write] reste sur la même ligne :