2.2.4-2.2.5

This commit is contained in:
Alexander Zhirov 2023-01-22 17:09:17 +03:00
parent 871eb75c78
commit a69bc1f89c
2 changed files with 75 additions and 3 deletions

View File

@ -5,9 +5,9 @@
- [2.2. Литералы](#2-2-литералы)
- [2.2.1. Логические литералы](#2-2-1-логические-литералы)
- [2.2.2. Целые литералы](#2-2-2-целые-литералы)
- [2.2.3. Литералы с плавающей запятой]()
- [2.2.4. Знаковые литералы]()
- [2.2.5. Строковые литералы]()
- [2.2.3. Литералы с плавающей запятой](#2-2-3-литералы-с-плавающей-запятой)
- [2.2.4. Знаковые литералы](#2-2-4-знаковые-литералы)
- [2.2.5. Строковые литералы](#2-2-5-строковые-литералы)
- [2.2.5.1. Строковые литералы: WYSIWYG, с разделителями, строки токенов и импортированные]()
- [2.2.5.2. Тип строкового литерала]()
- [2.2.6. Литералы массивов и ассоциативных массивов]()
@ -190,7 +190,79 @@ auto targetSalary = 15_000_000;
[В начало ⮍](#2-2-2-целые-литералы) [Наверх ⮍](#2-основные-типы-данных-выражения)
### 2.2.3. Литералы с плавающей запятой
Литералы с плавающей запятой могут быть десятичными и шестнадцатеричными. Десятичные литералы с плавающей запятой легко определить по аналогии с только что определенными десятичными целыми числами: десятичный литерал с плавающей запятой состоит из десятичного литерала, который также может содержать точку[^5] в любой позиции, за ней могут следовать показатель степени (характеристика) и суффикс. Показатель степени[^6] это то, что обозначается как `e`, `E`, `e+`, `E+`, `e-` или `E-`, после чего следует целый десятичный литерал без знака[^7]. В качестве суффикса может выступать `f`, `F` или `L`. Разумеется, хотя бы что-то одно из `e/E` и `f/F` должно присутствовать, иначе если в числе нет точки, вместо числа с плавающей запятой получим целое. Суффикс `f/F` заставляет компилятор определить тип литерала как `float`, а суффикс `L` как `real`. Иначе литералу будет присвоен тип `double`.
Может показаться, что шестнадцатеричные константы с плавающей запятой вещь странноватая. Однако, как показывает практика, они очень удобны, если нужно записать число очень *точно*. Внутреннее представление чисел с плавающей запятой характеризуется тем, что числа хранятся в двоичном виде, поэтому запись вещественного числа в десятичном виде повлечет преобразования, невозможные без округлений, поскольку 10 не степень 2. Шестнадцатеричная форма записи, напротив, позволяет записать число с плавающей запятой точно так, как оно будет представлено. Полный курс по представлению чисел с плавающей запятой выходит за рамки этой книги; отметим лишь, что все реализации D гарантированно используют формат IEEE 754, полную информацию о котором можно найти в Сети (сделайте запрос «формат чисел с плавающей запятой IEEE 754»).
Шестнадцатеричный литерал с плавающей запятой состоит из префикса `0x` или `0X`, за которым следует строка шестнадцатеричных цифр, содержащая точку в любой позиции. Затем идет обязательный показатель степени[^8], который начинается с `p`, `P`, `p+`, `P+`, `p-` или `P-` и заканчивается десятичными (не шестнадцатеричными!) цифрами. Только так называемая мантисса дробная часть перед показателем степени выражается шестнадцатеричным числом; сам показатель степени целое десятичное число. Показатель степени шестнадцатеричной константы с плавающей запятой означает степень 2 (а не 10, как в случае с десятичным представлением). Завершается литерал необязательным суффиксом `f`, `F` или `L`[^9]. Рассмотрим несколько подходящих примеров:
```d
auto
a = 1.0, // a имеет тип double
b = .345E2f, // b = 34.5 имеет тип float
c = 10f, // c имеет тип float из-за суффикса
d = 10., // d имеет тип double
e = 0x1.fffffffffffffp1023, // наибольшее возможное значение типа double
f = 0XFp1F; // f = 30.0, тип float
```
Рисунок 2.2 без лишних слов описывает литералы с плавающей запятой языка D. Правила интерпретации автомата те же, что и для автомата, иллюстрирующего распознавание целых литералов: переход выполняется по мере чтения знаков литерала с целью прочитать как можно больше. Представление в виде автомата проясняет несколько фактов, которые было бы утомительно описывать, не используя формальный аппарат. Например, `0x.p1` и `0xp1` вполне приемлемые, хотя и странные формы записи нуля, а конструкции типа `0e1`, `.e1` и `0x0.0` запрещены.
![image-2-2](images/image-2-2.png)
***Рис. 2.2.*** *Распознавание литералов с плавающей запятой*
[В начало ⮍](#2-2-3-литералы-с-плавающей-запятой) [Наверх ⮍](#2-основные-типы-данных-выражения)
### 2.2.4. Знаковые литералы
Знаковый литерал это один знак, заключенный в одиночные кавычки, например `'a'`. Если в качестве знака выступают сами кавычки, их нужно экранировать с помощью обратной косой черты: `'\''`. На самом деле в D, как и в других языках, определены несколько разных escape-последовательностей[^10] (см. табл. 2.3). В дополнение к стандартному набору управляющих непечатаемых символов D предоставляет следующие возможности записать знаки Юникода: `'\u03C9'` (знаки `\u`, за которыми следуют ровно 4 шестнадцатеричные цифры), `'\U0000211C'` (знаки `\U`, за которыми следуют ровно 8 шестнадцатеричных цифр) и `'\©'` (имя, окруженное знаками `\&` и `;`). Первый из этих примеров знак `ω` в Юникоде, второй красивая письменная ``, а последний грозный знак `©`. Если вам нужен полный список знаков, которые можно отобразить, поищите в Интернете информацию о таблице знаков Юникода.
*Таблица 2.3. Экранирующие последовательности в D*
|Escape-последовательность|Тип|Описание|
|-|-|-|
|`\"`|`char`|Двойная кавычка (если двусмысленно)|
|`\\`|`char`|Обратная косая черта|
|`\a`|`char`|Звуковой сигнал (Bell, ASCII 7)|
|`\b`|`char`|Backspace (ASCII 8)|
|`\f`|`char`|Смена страницы (ASCII 12)|
|`\n`|`char`|Перевод строки (ASCII 10)|
|`\r`|`char`|Возврат каретки (ASCII 13)|
|`\t`|`char`|Табуляция (ASCII 9)|
|`\v`|`char`|Вертикальная табуляция (ASCII 11)|
|`\<13 восьмеричные цифры>`|`char`|Знак UTF-8 в восьмеричном представлении (не больше 377<sub>8</sub>)|
|`\x<2 шестнадцатеричные цифры>`|`char`|Знак UTF-8 в шестнадцатеричном представлении|
|`\u<4 шестнадцатеричные цифры>`|`wchar`|Знак UTF-16 в шестнадцатеричном представлении|
|`\U<8 шестнадцатеричных цифр>`|`dchar`|Знак UTF-32 в шестнадцатеричном представлении|
|`\&<имя знака>;`|`dchar`|Имя знака Юникод|
[В начало ⮍](#2-2-4-знаковые-литералы) [Наверх ⮍](#2-основные-типы-данных-выражения)
### 2.2.5. Строковые литералы
Теперь, когда мы знаем, как представляются отдельные знаки, строковые литералы для нас пустяк. D прекрасно справляется с обработкой строк отчасти благодаря своим мощным средствам представления строковых литералов. Как и другие языки, работающие со строками, D различает строки, заключенные в кавычки (внутри которых можно размещать экранированные последовательности из табл. 2.3), и WYSIWYG-строки[^11] (которые компилятор распознает «вслепую», не пытаясь обнаружить и расшифровать никакие escape-последовательности). Стиль WYSIWYG очень удобен для представления строк, где иначе пришлось бы использовать множество экранированных знаков; два выдающихся примера регулярные выражения и пути к файлам в системе Windows. Строки, заключенные в кавычки (quoted strings), это последовательности знаков в двойных кавычках, `"как в этом примере"`. В таких строках все escape-последовательности из табл. 2.3 являются значимыми. Строки всех видов, расположенные подряд, автоматически подвергаются конкатенации:
```d
auto crlf = "\r\n";
auto a = "В этой строке есть \"двойные кавычки\", а также
перевод строки, даже два" "\n";
```
Текст умышленно перенесен на новую строку после слова `также`: строковый литерал может содержать знак перевода строки (реальное начало новой строки в исходном коде, а не комбинацию `\n`), который будет сохранен именно в этом качестве.
[В начало ⮍](#2-2-5-строковые-литералы) [Наверх ⮍](#2-основные-типы-данных-выражения)
[^1]: Впрочем, использование нелатинских букв является дурным тоном. *Прим. науч. ред.*
[^2]: С99 обновленная спецификация C, в том числе добавляющая поддержку знаков Юникода. *Прим. пер.*
[^3]: Сам язык не поддерживает восьмеричные литералы, но поскольку они присутствуют в некоторых C-подобных языках, в стандартную библиотеку был добавлен соответствующий шаблон. Теперь запись `std.conv.octal!777` аналогична записи `0777` в C. *Прим. науч. ред.*
[^4]: Для тех, кто готов воспринимать теорию: автоматы на рис. 2.1 и 2.2 это детерминированные конечные автоматы (ДКА).
[^5]: В России в качестве разделителя целой и дробной части чисел с плавающей запятой принята запятая (поэтому и говорят: «числа с плавающей *запятой*»), однако в англоговорящих странах для этого служит точка, поэтому в языках программирования (обычно основанных на английском международном языке информатики) разделителем является точка. *Прим. пер.*
[^6]: Показатель степени 10 по-английски exponent, поэтому для его обозначения и используется буква `e`. *Прим. пер.*
[^7]: Запись `Ep` означает «умножить на 10 в степени `p`», то есть `p` это порядок. *Прим. пер.*
[^8]: Степень по-английски power, поэтому показатель степени 2 обозначается буквой `p`. *Прим. пер.*
[^9]: Да, синтаксис странноватый, но D скопировал его из стандарта C99, чтобы не изобретать свою нотацию с собственными выкрутасами, которых все равно не избежать.
[^10]: Escape-последовательность (от англ. escape избежать), экранирующая/управляющая последовательность специальная комбинация знаков, отменяющая стандартную обработку компилятором следующих за ней знаков (они как бы «исключаются из рассмотрения»). *Прим. пер.*
[^11]: WYSIWIG акроним «What You See Is What You Get» (что видишь, то и получишь) способ представления, при котором данные в процессе редактирования выглядят так же, как и в результате обработки каким-либо инструментом (компилятором, после отображения браузером и т. п.). *Прим. пер.*

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB