Глава 4 закончена
This commit is contained in:
parent
141dd624b1
commit
e57718386b
|
@ -125,6 +125,8 @@ assert(a !is null);
|
|||
|
||||
Благодаря последней строке этого кода обнаруживается нечто странное: пустой массив – это необязательно `null`.
|
||||
|
||||
[Исходный код](src/chapter-4-1/)
|
||||
|
||||
[В начало ⮍](#4-1-динамические-массивы) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.1.1. Длина
|
||||
|
@ -146,6 +148,8 @@ assert(array[$ - 1] == 42);
|
|||
|
||||
Изменение длины массива обсуждается в разделах 4.1.8–4.1.10.
|
||||
|
||||
[Исходный код](src/chapter-4-1-1/)
|
||||
|
||||
[В начало ⮍](#4-1-1-длина) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.1.2. Проверка границ
|
||||
|
@ -235,6 +239,8 @@ array = array[$ / 2 .. $];
|
|||
|
||||
Выражение `array[0 .. $]` получает срез, включающий все содержимое массива `array`. Это выражение встречается довольно часто, и тут язык помогает программистам, позволяя вместо записи `array[0 .. $]` использовать краткую форму `array[]`.
|
||||
|
||||
[Исходный код](src/chapter-4-1-3/)
|
||||
|
||||
[В начало ⮍](#4-1-3-срезы) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.1.4. Копирование
|
||||
|
@ -281,6 +287,8 @@ subarray[1] = 33;
|
|||
assert(array[2] == 33); // Изменение массива subarray отразилось на массиве array
|
||||
```
|
||||
|
||||
[Исходный код](src/chapter-4-1-4/)
|
||||
|
||||
[В начало ⮍](#4-1-4-копирование) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.1.5. Проверка на равенство
|
||||
|
@ -301,6 +309,8 @@ assert(a !is b); // Тест пройден, a и b различны, хотя
|
|||
|
||||
При поэлементном сравнении массивов просматриваются все элементы обоих массивов и соответствующие пары сравниваются по очереди с помощью оператора `==`.
|
||||
|
||||
[Исходный код](src/chapter-4-1-5/)
|
||||
|
||||
[В начало ⮍](#4-1-5-проверка-на-равенство) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.1.6. Конкатенация
|
||||
|
@ -323,6 +333,8 @@ assert(a.length == 8);
|
|||
|
||||
Под результирующий массив всегда выделяется новая область памяти.
|
||||
|
||||
[Исходный код](src/chapter-4-1-6/)
|
||||
|
||||
[В начало ⮍](#4-1-6-конкатенация) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.1.7. Поэлементные операции
|
||||
|
@ -385,6 +397,8 @@ a[] = b[]; // Скопировать все данные из b в a
|
|||
|
||||
Поэлементные операции очень мощны, а чем больше мощность, тем больше ответственность. Именно вы отвечаете за отсутствие перекрывания между l- и r-значениями каждого присваивания в поэлементной операции. Приводя высокоуровневые операции к примитивным операциям над векторами, которые может выполнять конечный процессор (на котором будет исполняться программа), компилятор вправе считать, что это именно так. Если вы намеренно используете перекрывание, то напишите циклы обработки элементов массива вручную, чтобы компилятор не смог выполнить какие-то непроверенные присваивания.
|
||||
|
||||
[Исходный код](src/chapter-4-1-7/)
|
||||
|
||||
[В начало ⮍](#4-1-7-поэлементные-операции) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.1.8. Сужение
|
||||
|
@ -436,6 +450,8 @@ palindrome 34 95 548
|
|||
|
||||
то содержимое массива `args` примет вид `["palindrome", "34", "95", "548"]`. Вот где пригодилось сужение слева `args = args[1 .. $]`: оно сокращает массив args до массива `["34", "95", "548"]`. Затем программа пошагово сравнивает элементы на концах массива. Если они не равны, то дальше можно не сравнивать: пишем `"не палиндром"` и закругляемся. А если проверка прошла успешно, то сужаем массив `args` с обоих концов. Только если все проверки возвратят `true`, а в массиве `args` останется не больше одного элемента (пустые массивы и массивы из одного элемента программа считает палиндромами), программа напечатает `"палиндром"` и завершится. Несмотря на то что программа активно манипулирует массивами, после инициализации массива `args` память не перераспределялась ни разу. Работа начинается c обращения к массиву `args` (память под который была выделена заранее), а потом он только сужается.
|
||||
|
||||
[Исходный код](src/chapter-4-1-8/)
|
||||
|
||||
[В начало ⮍](#4-1-8-сужение) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.1.9. Расширение
|
||||
|
@ -500,6 +516,8 @@ assert(b == [40, 50, 60, 70]); // Тест пройден; массив a был
|
|||
|
||||
Этот код искусно заставляет массив `a` думать, что в конце области памяти, которую он занимает, есть свободное место: первоначально массив `a` был больше по размеру, затем массив `b` занял вторую половину массива `a`, а сам массив `a` сузился до своей первой половины. Перед добавлением новых элементов в массив `a` массивы `a` и `b` занимали соседние области памяти: массив `a` находился слева от массива `b`. Однако успешное выполнение теста `assert` после добавления новых элементов в массив a подтвердило, что этот массив был перенесен в другую область памяти, а не расширился на том же месте. Оператор расширения добавляет в массив элементы без изменения адреса массива, только если уверен, что справа от расширяющегося массива нет другого массива, и при малейшем сомнении всегда готов подстраховаться, перераспределив память.
|
||||
|
||||
[Исходный код](src/chapter-4-1-9/)
|
||||
|
||||
[В начало ⮍](#4-1-9-расширение) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.1.10. Присваивание значения свойству .length
|
||||
|
@ -531,6 +549,8 @@ assert(array.length == 101);
|
|||
|
||||
Здесь нет никакой магии; все, что необходимо сделать компилятору, – это переписать выражение `array.length ‹о›= b` в несколько иной форме: `array.length = array.length ‹о› b`. И все-таки немного магии тут есть (на самом деле, всего лишь ловкость рук): в переписанном выражении массив вычисляется всего лишь раз, что очень кстати, если реально `array` – это какое-то замысловатое выражение.
|
||||
|
||||
[Исходный код](src/chapter-4-1-10/)
|
||||
|
||||
[В начало ⮍](#4-1-10-присваивание-значения-свойству-length) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
## 4.2. Массивы фиксированной длины
|
||||
|
@ -598,6 +618,7 @@ foreach (ref element; array)
|
|||
element = uniform(0.0, 1.0);
|
||||
}
|
||||
```
|
||||
[Исходный код](src/chapter-4-2/)
|
||||
|
||||
[В начало ⮍](#4-2-массивы-фиксированной-длины) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
|
@ -649,6 +670,7 @@ int[] b = a[1 .. 7]; // Все в порядке
|
|||
auto c = a[1 .. 7]; // Все в порядке, c также имеет тип int[]
|
||||
int[6] d = a[1 .. 7]; // Все в порядке, срез a[1 .. 7] скопирован в d
|
||||
```
|
||||
[Исходный код](src/chapter-4-2-3/)
|
||||
|
||||
[В начало ⮍](#4-2-3-получение-срезов) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
|
@ -690,6 +712,8 @@ auto r = fun(point); // Все в порядке, теперь r имеет
|
|||
|
||||
Свойство `.dup` позволяет получить дубликат массива фиксированной длины (см. раздел 4.1), но вы получите не объект типа `T[n]`, а динамически выделенный массив типа `T[]`, содержащий копию массива фиксированной длины. Такое поведение оправданно, ведь чтобы получить копию статического массива `а` того же типа, не нужно прибегать ни к каким дополнительным ухищрениям – просто напишите `auto copy = a`.
|
||||
|
||||
[Исходный код](src/chapter-4-2-4/)
|
||||
|
||||
[В начало ⮍](#4-2-4-копирование-и-неявные-преобразования) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.2.5. Проверка на равенство
|
||||
|
@ -709,6 +733,8 @@ assert(dynamic !is fixed);
|
|||
assert(dynamic == fixed);
|
||||
```
|
||||
|
||||
[Исходный код](src/chapter-4-2-5/)
|
||||
|
||||
[В начало ⮍](#4-2-5-проверка-на-равенство) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.2.6. Конкатенация
|
||||
|
@ -726,6 +752,8 @@ double[5] e = a ~ d; // Все в порядке, явный запрос ма
|
|||
|
||||
Если в качестве результата конкатенации `~` явно указан массив фиксированной длины, никогда не происходит динамического выделения памяти: статически выделяется блок памяти, и результат конкатенации копируется в него.
|
||||
|
||||
[Исходный код](src/chapter-4-2-6/)
|
||||
|
||||
[В начало ⮍](#4-2-6-конкатенация) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.2.7. Поэлементные операции
|
||||
|
@ -811,6 +839,8 @@ int[string] aa = [ "здравствуй":42, "мир":75 ];
|
|||
auto aa = [ "здравствуй":42, "мир":75 ];
|
||||
```
|
||||
|
||||
[Исходный код](src/chapter-4-4/)
|
||||
|
||||
[В начало ⮍](#4-4-ассоциативные-массивы) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.4.1. Длина
|
||||
|
@ -829,6 +859,8 @@ assert(aa.length == 2);
|
|||
|
||||
В отличие от одноименного свойства массивов, свойство `.length` ассоциативных массивов предназначено только для чтения. Тем не менее можно очистить ассоциативный массив, присвоив его переменной значение `null`.
|
||||
|
||||
[Исходный код](src/chapter-4-4-1/)
|
||||
|
||||
[В начало ⮍](#4-4-1-длина) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.4.2. Чтение и запись ячеек
|
||||
|
@ -852,7 +884,7 @@ aa["моцарелла"] = "mozzarella";
|
|||
assert(aa["здравствуй"] == "ciao");
|
||||
```
|
||||
|
||||
Если вы попытаетесь прочитать значение по ключу, которого нет в ассоциативном массиве, возникнет исключительная ситуация. Но обычно генерация исключения в случае, когда ключ не обнаружен, – слишком строгая мера, чтобы быть полезной, поэтому для чтения ассоциативных массивов предоставляется альтернативная функция, возвращающая значение по умолчанию, если ключ не найден в массиве. Она реализована в виде метода `get`, принимающего два аргумента. Если при вызове `aa.get(ключ, значeние_по_умолчанию)` в массиве найден `ключ`, то функция возвращает соответствующее ему значение, а выражение `значение_по__умолчанию` не вычисляется; иначе `значение_по__умолчанию` вычисляется и метод возвращает результат этого вычисления.
|
||||
Если вы попытаетесь прочитать значение по ключу, которого нет в ассоциативном массиве, возникнет исключительная ситуация. Но обычно генерация исключения в случае, когда ключ не обнаружен, – слишком строгая мера, чтобы быть полезной, поэтому для чтения ассоциативных массивов предоставляется альтернативная функция, возвращающая значение по умолчанию, если ключ не найден в массиве. Она реализована в виде метода `get`, принимающего два аргумента. Если при вызове `aa.get(ключ, значeние_по_умолчанию)` в массиве найден `ключ`, то функция возвращает соответствующее ему значение, а выражение `значение_по_умолчанию` не вычисляется; иначе `значение_по_умолчанию` вычисляется и метод возвращает результат этого вычисления.
|
||||
|
||||
```d
|
||||
assert(aa["здравствуй"] == "ciao");
|
||||
|
@ -870,6 +902,8 @@ assert("эй" !in aa);
|
|||
// Попытка прочесть aa["эй"] вызвала бы исключение
|
||||
```
|
||||
|
||||
[Исходный код](src/chapter-4-4-2/)
|
||||
|
||||
[В начало ⮍](#4-4-2-чтение-и-запись-ячеек) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.4.3. Копирование
|
||||
|
@ -887,6 +921,8 @@ assert(a1["Sam"] == 3.5); // наоборот
|
|||
|
||||
При этом у ассоциативных массивов, как и у обычных, есть свойство `.dup`, создающее поэлементную копию массива.
|
||||
|
||||
[Исходный код](src/chapter-4-4-3/)
|
||||
|
||||
[В начало ⮍](#4-4-3-копирование) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.4.4. Проверка на равенство
|
||||
|
@ -902,6 +938,8 @@ a2["Bob"] = 18;
|
|||
assert(a1 != a2);
|
||||
```
|
||||
|
||||
[Исходный код](src/chapter-4-4-4/)
|
||||
|
||||
[В начало ⮍](#4-4-4-проверка-на-равенство) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.4.5. Удаление элементов
|
||||
|
@ -969,6 +1007,8 @@ foreach (k; gammaFunc.byKey())
|
|||
}
|
||||
```
|
||||
|
||||
[Исходный код](src/chapter-4-4-6/)
|
||||
|
||||
[В начало ⮍](#4-4-6-перебор-элементов) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
### 4.4.7. Пользовательские типы
|
||||
|
@ -1113,6 +1153,8 @@ void main()
|
|||
|
||||
Кодировка литерала определяется контекстом, в котором этот литерал используется. В предыдущем примере компилятор преобразует строковый литерал, без какой-либо обработки во время исполнения программы, из кодировки UTF-8 в кодировку UTF-16, а потом в кодировку UTF-32 (соответствующие типам `string`, `wstring` и `dstring`), хотя написание литералов во всех трех случаях одинаково. Если требуемая кодировка литерала не может быть однозначно определена, добавьте к нему суффикс `c`, `w` или `d` (например, `"как_здесь"d`): строка будет преобразована в кодировку UTF-8, UTF-16 или UTF-32 соответственно (см. раздел 2.2.5.2).
|
||||
|
||||
[Исходный код](src/chapter-4-5-4/)
|
||||
|
||||
[В начало ⮍](#4-5-4-массивы-знаков-бонусы-строки) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
#### 4.5.4.1. Цикл foreach применительно к строкам
|
||||
|
@ -1168,6 +1210,8 @@ foreach (dchar c; str)
|
|||
|
||||
В рассмотренном примере в инструкции `foreach` выполнялось перекодирование в направлении от «узкого» к более «широкому» представлению, но обратное преобразование также возможно. Например, можно начать со значения типа `dstring`, а затем просмотреть его по одному (закодированному) знаку типа `char`.
|
||||
|
||||
[Исходный код](src/chapter-4-5-4-1/)
|
||||
|
||||
[В начало ⮍](#4-5-4-1-цикл-foreach-применительно-к-строкам) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
## 4.6. Опасный собрат массива – указатель
|
||||
|
@ -1230,6 +1274,8 @@ y += 100; // Хм...
|
|||
|
||||
Существует «урезанная» безопасная версия D, известная как SafeD (см. главу 11), также есть флаг компилятора, установка которого включает проверку принадлежности используемых в программе инструкций и типов данных этому безопасному подмножеству средств языка. Естественно, в безопасном D (SafeD) запрещено большинство операций с указателями. Встроенные массивы – это важное средство, позволяющее создавать мощные, выразительные программы на SafeD.
|
||||
|
||||
[Исходный код](src/chapter-4-6/)
|
||||
|
||||
[В начало ⮍](#4-6-опасный-собрат-массива-указатель) [Наверх ⮍](#4-массивы-ассоциативные-массивы-и-строки)
|
||||
|
||||
## 4.7. Итоги и справочник
|
||||
|
@ -1267,7 +1313,7 @@ y += 100; // Хм...
|
|||
|`[t1, ..., tk]`|`T[k]`|Литерал массива, но только если тип `T[k]` запрошен явно; `T` определяется по типу `t1` (см. разделы [2.2.6](../02-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5-%D1%82%D0%B8%D0%BF%D1%8B-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85-%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F#2-2-6-литералы-массивов-и-ассоциативных-массивов) и [4.1](#4-1-динамические-массивы))|
|
||||
|`a = b`|`ref T[n]`|Копирует содержимое одного массива в другой (см. раздел [4.2.4](#4-2-4-копирование-и-неявные-преобразования))|
|
||||
|`a[‹в›]`|`ref T`|Предоставляет доступ к элементу по индексу (символ `$` в `‹в›` заменяется на `a.length`, `‹в›` должно быть приводимым к типу `размер_t`; кроме того, должно соблюдаться условие `‹в› < a.length`) (см. раздел [4.1](#4-1-динамические-массивы))|
|
||||
|`a[‹в1› .. ‹в2›]`|`T[]/T[k]`|Получает срез массива `a` (символ `$` в `‹в1›` и `‹в2›` заменяется на `a.length`, `‹в1›` и `‹в2›` должны быть приводимыми к типу `размер_t`, также должно соблюдаться условие `‹в1› <= ‹в2› && ‹в2› <= a.length`) (см. раздел [4.2.3](#4-2-3-получение-срезов)))|
|
||||
|`a[‹в1› .. ‹в2›]`|`T[]/T[k]`|Получает срез массива `a` (символ `$` в `‹в1›` и `‹в2›` заменяется на `a.length`, `‹в1›` и `‹в2›` должны быть приводимыми к типу `размер_t`, также должно соблюдаться условие `‹в1› <= ‹в2› && ‹в2› <= a.length`) (см. раздел [4.2.3](#4-2-3-получение-срезов))|
|
||||
|`a[]`|`T[]`|Поэлементная операция (см. раздел [4.1.7](#4-1-7-поэлементные-операции)) или приведение `a` (массива фиксированной длины) к типу динамического массива, то же, что и `a[0 .. $]`|
|
||||
|`a.dup`|`T[]`|Получает дубликат массива (см. раздел [4.2.4](#4-2-4-копирование-и-неявные-преобразования))|
|
||||
|`a.length`|`размер_t`|Читает длину массива (см. раздел [4.2.1](#4-2-1-длина))|
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto array1 = new short[55];
|
||||
assert(array1.length == 55);
|
||||
writeln(array1);
|
||||
|
||||
auto array2 = new int[10];
|
||||
array2[9] = 42;
|
||||
assert(array2[$ - 1] == 42);
|
||||
writeln(array2);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
void main()
|
||||
{
|
||||
auto array = new int[10];
|
||||
array.length += 1000; // Расширяется
|
||||
assert(array.length == 1010);
|
||||
array.length /= 10; // Сужается
|
||||
assert(array.length == 101);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
// Напечатать только вторую половину
|
||||
writeln(array[$ / 2 .. $]);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
void main()
|
||||
{
|
||||
int[] array = [0, 1, 2];
|
||||
int[] subarray = array[1 .. $];
|
||||
assert(subarray.length == 2);
|
||||
subarray[1] = 33;
|
||||
assert(array[2] == 33);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
void main()
|
||||
{
|
||||
auto a = ["hello", "world"];
|
||||
auto b = a;
|
||||
assert(a is b); // Тест пройден, у a и b одни те же границы
|
||||
assert(a == b); // Естественно, тест пройден
|
||||
b = a.dup;
|
||||
assert(a == b); // Тест пройден, a и b равны, хотя занимают разные области памяти
|
||||
assert(a !is b); // Тест пройден, a и b различны, хотя имеют одинаковое содержимое
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
void main()
|
||||
{
|
||||
int[] a = [0, 10, 20];
|
||||
int[] b = a ~ 42;
|
||||
assert(b == [0, 10, 20, 42]);
|
||||
a = b ~ a ~ 15;
|
||||
assert(a.length == 8);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto a = [ 0.5, -0.5, 1.5, 2 ];
|
||||
auto b = [ 3.5, 5.5, 4.5, -1 ];
|
||||
auto c = new double[4]; // Память под массив должна быть уже выделена
|
||||
c[] = (a[] + b[]) / 2; // Рассчитать среднее арифметическое a и b
|
||||
assert(c == [ 2.0, 2.5, 3.0, 0.5 ]);
|
||||
|
||||
auto d = [1.0, 2.5, 3.6];
|
||||
auto e = [4.5, 5.5, 1.4];
|
||||
auto f = new double[3];
|
||||
f[] += 4 * d[] + e[];
|
||||
|
||||
int[] g = new int[5];
|
||||
int[] h = new int[5];
|
||||
g[] = -1; // Заполнить все ячейки b значением -1
|
||||
h[] = g[]; // Скопировать все данные из b в a
|
||||
writeln(g);
|
||||
writeln(h);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto array = [0, 2, 4, 6, 8, 10];
|
||||
array = array[0 .. $ - 2];
|
||||
// Сужение справа на два элемента
|
||||
assert(array == [0, 2, 4, 6]);
|
||||
array = array[1 .. $];
|
||||
// Сужение слева на один элемент
|
||||
assert(array == [2, 4, 6]);
|
||||
array = array[1 .. $ - 1];
|
||||
// Сужение с обеих сторон
|
||||
assert(array == [4]);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import std.conv, std.stdio;
|
||||
|
||||
int main(string[] args)
|
||||
{
|
||||
// Избавиться от имени программы
|
||||
args = args[1 .. $];
|
||||
while (args.length >= 2)
|
||||
{
|
||||
if (to!int(args[0]) != to!int(args[$ - 1]))
|
||||
{
|
||||
writeln("не палиндром");
|
||||
return 1;
|
||||
}
|
||||
args = args[1 .. $ - 1];
|
||||
}
|
||||
writeln("палиндром");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
void main()
|
||||
{
|
||||
int[] a = [0, 10, 20, 30, 40, 50, 60, 70];
|
||||
auto b = a[4 .. $];
|
||||
a = a[0 .. 4];
|
||||
// Сейчас a и b примыкают друг к другу
|
||||
a ~= [0, 0, 0, 0];
|
||||
assert(b == [40, 50, 60, 70]); // Тест пройден; массив a был перенесен в новую область памяти
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import std.random;
|
||||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
// От 1 до 127 элементов
|
||||
auto array = new double[uniform(1, 128)];
|
||||
|
||||
foreach (i; 0 .. array.length)
|
||||
{
|
||||
array[i] = uniform(0.0, 1.0);
|
||||
}
|
||||
|
||||
writeln(array);
|
||||
|
||||
foreach (ref element; array)
|
||||
{
|
||||
element = uniform(0.0, 1.0);
|
||||
}
|
||||
|
||||
writeln(array);
|
||||
|
||||
auto copy = array.dup;
|
||||
assert(array !is copy);
|
||||
assert(array == copy);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[5] array = [40, 30, 20, 10, 0];
|
||||
auto slice1 = array[2 .. $]; // slice1 имеет тип int[]
|
||||
assert(slice1 == [20, 10, 0]);
|
||||
auto slice2 = array[]; // Такой же, как array[0 .. $]
|
||||
assert(slice2 == array);
|
||||
|
||||
int[10] a;
|
||||
int[] b = a[1 .. 7]; // Все в порядке
|
||||
auto c = a[1 .. 7]; // Все в порядке, c также имеет тип int[]
|
||||
int[6] d = a[1 .. 7]; // Все в порядке, срез a[1 .. 7] скопирован в d
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import std.stdio;
|
||||
|
||||
int[3] fun(int[3] x, int[3] y)
|
||||
{
|
||||
// x и y – копии переданных аргументов
|
||||
x[0] = y[0] = 100;
|
||||
return x;
|
||||
}
|
||||
|
||||
double[3] fun2(double[] x)
|
||||
{
|
||||
double[3] result;
|
||||
result[] = 2 * x[]; // Операция над массивом в целом
|
||||
return result;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int[3] a = [1, 2, 3];
|
||||
int[3] b = a;
|
||||
a[1] = 42;
|
||||
assert(b[1] == 2); // b – независимая копия a
|
||||
|
||||
auto c = fun(a, b); // c имеет тип int[3]
|
||||
|
||||
assert(c == [100, 42, 3]);
|
||||
writeln(c);
|
||||
assert(b == [1, 2, 3]); // Вызов fun никак на отразился на b
|
||||
writeln(b);
|
||||
|
||||
double[3] point = [0, 0, 0];
|
||||
double[] test = point; // Все в порядке
|
||||
auto r = fun2(point); // Все в порядке, теперь r имеет тип double[3]
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[4] fixed = [1, 2, 3, 4];
|
||||
auto anotherFixed = fixed;
|
||||
assert(anotherFixed !is fixed); // Не то же самое (копирование по значению)
|
||||
assert(anotherFixed == fixed); // Те же данные
|
||||
auto dynamic = fixed[]; // Получает границы массива fixed
|
||||
assert(dynamic is fixed);
|
||||
assert(dynamic == fixed); // Естественно
|
||||
dynamic = dynamic.dup; // Создает копию
|
||||
assert(dynamic !is fixed);
|
||||
assert(dynamic == fixed);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
double[2] a;
|
||||
double[] b = a ~ 0.5; // Присоединить к double[2] значение, получить double[]
|
||||
auto c = a ~ 0.5; // То же самое
|
||||
double[3] d = a ~ 1.5; // Все в порядке, явный запрос массива фиксированной длины
|
||||
double[5] e = a ~ d; // Все в порядке, явный запрос массива фиксированной длины
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import std.stdio, std.random;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[128] someInts;
|
||||
|
||||
int[3] a;
|
||||
assert(a == [0, 0, 0]);
|
||||
|
||||
int[3] b = [1, 2, 3];
|
||||
assert(b == [1, 2, 3]);
|
||||
|
||||
int[4] c = -1;
|
||||
assert(c == [-1, -1, -1, -1]);
|
||||
|
||||
int[1024] d = void;
|
||||
|
||||
double[10] array;
|
||||
foreach (i; 0 .. array.length)
|
||||
{
|
||||
array[i] = uniform(0.0, 1.0);
|
||||
}
|
||||
writeln(array);
|
||||
foreach (ref element; array)
|
||||
{
|
||||
element = uniform(0.0, 1.0);
|
||||
}
|
||||
writeln(array);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
string[int] aa;
|
||||
assert(aa == null);
|
||||
assert(aa.length == 0);
|
||||
aa = [0:"zero", 1:"not zero"];
|
||||
assert(aa.length == 2);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Создать ассоциативный массив с соответствием строка/строка
|
||||
auto aa = [ "здравствуй":"salve", "мир":"mundi" ];
|
||||
// Перезаписать значения
|
||||
aa["здравствуй"] = "ciao";
|
||||
aa["мир"] = "mondo";
|
||||
// Создать несколько новых пар ключ–значение
|
||||
aa["капуста"] = "cavolo";
|
||||
aa["моцарелла"] = "mozzarella";
|
||||
|
||||
writeln(aa);
|
||||
|
||||
assert(aa["здравствуй"] == "ciao");
|
||||
// Ключ "здравствуй" существует, поэтому второй аргумент игнорируется
|
||||
assert(aa.get("здравствуй", "salute") == "ciao");
|
||||
// Ключ "здорово" не существует, возвратить второй аргумент
|
||||
assert(aa.get("здорово", "buongiorno") == "buongiorno");
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto a1 = [ "Jane":10.0, "Jack":20, "Bob":15 ];
|
||||
auto a2 = a1; // a1 и a2 ссылаются на одни данные
|
||||
a1["Bob"] = 100; // Изменяя a1,...
|
||||
assert(a2["Bob"] == 100); // ...мы изменяем a2...
|
||||
a2["Sam"] = 3.5; // ...и
|
||||
assert(a1["Sam"] == 3.5); // наоборот
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto a1 = [ "Jane":10.0, "Jack":20, "Bob":15 ];
|
||||
auto a2 = [ "Jane":10.0, "Jack":20, "Bob":15 ];
|
||||
assert(a1 !is a2);
|
||||
assert(a1 == a2);
|
||||
a2["Bob"] = 18;
|
||||
assert(a1 != a2);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto coffeePrices = [
|
||||
"французская ваниль" : 262,
|
||||
"ява" : 239,
|
||||
"французская обжарка" : 224
|
||||
];
|
||||
|
||||
foreach (kind, price; coffeePrices)
|
||||
{
|
||||
writefln("%s стоит %s руб. за 100 г", kind, price);
|
||||
}
|
||||
|
||||
auto gammaFunc = [-1.5:2.363, -0.5:-3.545, 0.5:1.772];
|
||||
double[] keys = gammaFunc.keys;
|
||||
assert(keys == [ -1.5, -0.5, 0.5 ]);
|
||||
|
||||
writeln(keys);
|
||||
|
||||
foreach (k; gammaFunc.byKey())
|
||||
{
|
||||
writeln(k);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[string] aa = ["здравсвтуй":42, "мир":75];
|
||||
writeln(aa);
|
||||
auto bb = ["здравсвтуй":42, "мир":75];
|
||||
writeln(bb);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
string str = "Hall\u00E5, V\u00E4rld!";
|
||||
|
||||
foreach (c; str)
|
||||
{
|
||||
write('[', c, ']');
|
||||
}
|
||||
|
||||
writeln();
|
||||
|
||||
foreach (dchar c; str)
|
||||
{
|
||||
write('[', c, ']');
|
||||
}
|
||||
|
||||
writeln();
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import std.stdio;
|
||||
import std.utf;
|
||||
|
||||
void main()
|
||||
{
|
||||
{
|
||||
string a = "hello";
|
||||
string b = a; // Переменная b теперь тоже указывает на значение "hello"
|
||||
string c = b[0 .. 4]; // Переменная c указывает на строку "hell"
|
||||
// Если бы такое присваивание было разрешено, это изменило бы a, b, и c:
|
||||
// a[0] = 'H';
|
||||
// Конкатенация оставляет переменные b и c нетронутыми:
|
||||
a = 'H' ~ a[stride(a, 0) .. $];
|
||||
assert(a == "Hello" && b == "hello" && c == "hell");
|
||||
}
|
||||
|
||||
{
|
||||
string a = "Независимо от представления \u03bb стоит \u20AC20.";
|
||||
wstring b = "Независимо от представления \u03bb стоит \u20AC20.";
|
||||
dstring c = "Независимо от представления \u03bb стоит \u20AC20.";
|
||||
writeln(a, '\n', b, '\n', c);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto arr = [ 5, 10, 20, 30 ];
|
||||
auto p = arr.ptr;
|
||||
assert(*p == 5);
|
||||
++p;
|
||||
assert(*p == 10);
|
||||
++*p;
|
||||
assert(*p == 11);
|
||||
p += 2;
|
||||
assert(*p == 30);
|
||||
assert(p - arr.ptr == 3);
|
||||
}
|
Loading…
Reference in New Issue