Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions cpp/cpp_chapter_0142/text.md
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ bool is_sorted(int arr[], std::size_t n, std::function<bool(int, int)> comp)
}
```

### Длина массива
### Длина массива {#block-array-length}

Давайте получим длину массива, разделив его размер на размер типа элемента:

Expand All @@ -560,7 +560,13 @@ std::println("{}", len);

Для получения размера массива `offsets` в байтах мы применили к нему оператор [sizeof](https://en.cppreference.com/w/cpp/language/sizeof.html). В предыдущей главе мы [использовали](/courses/cpp/chapters/cpp_chapter_0141/#block-sizeof) `sizeof` для того, чтобы узнать, сколько байт выделяется под тип. Но `sizeof` можно применять не только для типов, но и для переменных.

Деление размера массива на размер его элемента — это способ определения длины, который работает во всех версиях C++, но не отличается удобством. В C++17 появилась функция [std::size()](https://en.cppreference.com/w/cpp/iterator/size.html), упрощающая задачу:
Запись `sizeof(offsets) / sizeof(int)` не слишком удобна, потому что явно задействует тип элемента массива. Более каноничным считается получение длины массива делением размера массива на размер нулевого элемента. Это абсолютно безопасно, потому что сишные массивы нулевой длины запрещены.

```cpp
std::size_t len = sizeof(offsets) / sizeof(offsets[0]);
```

Оба описанных способа работают во всех версиях C++, но не отличаются удобством. В C++17 появилась функция [std::size()](https://en.cppreference.com/w/cpp/iterator/size.html), упрощающая задачу:

```cpp {.example_for_playground .example_for_playground_006}
int offsets[] = {-1, 0, -1, 2};
Expand All @@ -573,7 +579,7 @@ std::println("{}", len);
4
```

Оба способа получения длины **не работают** внутри функций, в которые массив передаётся. Виной тому низведение массива (array to pointer decay) — неявное приведение сишного массива к указателю на его первый элемент. Указатель — это переменная, которая хранит адрес другой переменной. Низведение массива происходит при передаче его в функцию: {#block-array-to-pointer-decay}
Ни один из способов получения длины **не работает** внутри функций, в которые массив передаётся. Виной тому низведение массива (array to pointer decay) — неявное приведение сишного массива к указателю на его первый элемент. Указатель — это переменная, которая хранит адрес другой переменной. Низведение массива происходит при передаче его в функцию: {#block-array-to-pointer-decay}

```cpp {.example_for_playground}
import std;
Expand Down Expand Up @@ -659,7 +665,7 @@ Accelerometer measurement #1

Кроме того, отсутствует удобный способ избежать случайного выхода за границы сишного массива. Зато в контейнере `std::array` такой способ есть. Метод `at()`, в отличие от оператора `[]`, проверяет индекс и в случае выхода за границы бросает исключение.

Сишные массивы нельзя присваивать друг другу и сравнивать через операторы `=` и `==`. Все присваивания и сравнения выполняются поэлементно, в цикле.
Сишные массивы нельзя присваивать друг другу и сравнивать через операторы `=` и `==`. Все присваивания и сравнения выполняются поэлементно, в цикле. {#block-compare}


### Советы по работе с массивами {#block-advice}
Expand Down
Loading