Как работает диапазон на основе для простых массивов?
Это должно читаться как " Скажите, что делает ранжированный (с массивами)? "
Я отвечу, предполагая, что - возьмите следующий пример с использованием вложенных массивов:
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. Но в тот момент, когда этот массив распадается на указатель, информация о размере теряется.