Как работает диапазон на основе для простых массивов?
Это должно читаться как " Скажите, что делает ранжированный (с массивами)? "
Я отвечу, предполагая, что - возьмите следующий пример с использованием вложенных массивов:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (auto &pl : ia)
Текстовая версия:
ia
представляет собой массив массивов («вложенный массив»), содержащий [3]
массивы, каждый из которых содержит [4]
значения. В приведенном выше примере ia
выполняется цикл с помощью его основного 'range' ( [3]
), и, следовательно, [3]
время цикла . Каждый контур производит один из ia
«S [3]
первичных значений , начиная с первой и заканчивая последней - массив , содержащий [4]
значения.
- Первый цикл:
pl
равно {1,2,3,4}
- массив
- Второй цикл:
pl
равно {5,6,7,8}
- массив
- Третий цикл:
pl
равно {9,10,11,12}
- массив
Прежде чем мы объясним процесс, вот несколько простых напоминаний о массивах:
- Массивы интерпретируются как указатели на их первое значение - использование массива без какой-либо итерации возвращает адрес первого значения.
pl
должен быть ссылкой, потому что мы не можем копировать массивы
- С массивами, когда вы добавляете число к самому объекту массива, он продвигается вперед столько раз и `` указывает '' на эквивалентную запись - если
n
это число, о котором идет речь, то ia[n]
это то же самое, что и *(ia+n)
(Мы разыменуем адрес, который n
записи вперед) и ia+n
совпадает с &ia[n]
(Мы получаем адрес этой записи в массиве).
Вот что происходит:
- На каждом цикле,
pl
устанавливается в качестве ссылки на ia[n]
, с n
сравнявшись текущее значение счетчика цикла , начиная с 0. Итак, pl
находится ia[0]
на первом раунде, на втором онia[1]
, и так далее. Он получает значение через итерацию.
- Цикл продолжается до тех пор,
ia+n
пока меньше end(ia)
.
... И это все.
На самом деле это просто упрощенный способ написать это :
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int n = 0; n != 3; ++n)
auto &pl = ia[n];
Если ваш массив не вложен, этот процесс становится немного проще, поскольку ссылка не требуется, потому что повторяемое значение не является массивом, а скорее `` нормальным '' значением:
int ib[3] = {1,2,3};
for (auto pl : ib)
cout << pl;
for (int n = 0; n != 3; ++n)
cout << ib[n];
Дополнительная информация
Что, если бы мы не хотели использовать auto
ключевое слово при создании pl
? Как бы это выглядело?
В следующем примере pl
относится к array of four integers
. Каждому циклу pl
присваивается значение ia[n]
:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int (&pl)[4] : ia)
И ... Вот как это работает, с дополнительной информацией, чтобы избавиться от путаницы. Это просто «сокращенный» for
цикл, который автоматически засчитывается для вас, но не имеет возможности получить текущий цикл без выполнения этого вручную.
for
. Но в тот момент, когда этот массив распадается на указатель, информация о размере теряется.