Jak działa na podstawie zakresu dla zwykłych tablic?
Czy należy to rozumieć jako: „ Powiedz mi, co robi ranged-for (z tablicami)? ”
Odpowiem zakładając, że - weź następujący przykład z użyciem zagnieżdżonych tablic:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (auto &pl : ia)
Wersja tekstowa:
ia
jest tablicą tablic („tablica zagnieżdżona”) zawierającą [3]
tablice, z których każda zawiera [4]
wartości. Powyższy przykład przechodzi ia
przez swój podstawowy „zakres” ( [3]
), a zatem wykonuje pętlę [3]
razy. Każda pętla wytwarza jeden z ia
„S [3]
podstawowych wartości, zaczynając od pierwszej a kończąc na ostatnim - tablicę zawierającą [4]
wartości.
- Pierwsza pętla:
pl
równa się {1,2,3,4}
- tablica
- Druga pętla:
pl
równa się {5,6,7,8}
- tablica
- Trzecia pętla:
pl
równa się {9,10,11,12}
- tablica
Zanim wyjaśnimy ten proces, oto kilka przyjaznych przypomnień o tablicach:
- Tablice są interpretowane jako wskaźniki do ich pierwszej wartości - użycie tablicy bez żadnej iteracji zwraca adres pierwszej wartości
pl
musi być odniesieniem, ponieważ nie możemy kopiować tablic
- W przypadku tablic, kiedy dodajesz liczbę do samego obiektu tablicy, przesuwa się ona do przodu tyle razy i „wskazuje” na równoważny wpis - Jeśli
n
jest to liczba, to ia[n]
jest to samo co *(ia+n)
(Wyłuskujemy adres będący n
wpisami naprzód) i ia+n
jest taki sam jak &ia[n]
(Otrzymujemy adres tego wpisu w tablicy).
Oto co się dzieje:
- W każdej pętli
pl
jest ustawiana jako odniesienie do ia[n]
, z n
wyrównywaniem bieżącej liczby pętli zaczynając od 0. Tak więc pl
jest ia[0]
w pierwszej rundzie, w drugiej to ia[1]
i tak dalej. Pobiera wartość poprzez iterację.
- Pętla trwa tak długo, jak
ia+n
jest krótsza niż end(ia)
.
... I to wszystko.
To naprawdę tylko uproszczony sposób pisania tego :
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];
Jeśli twoja tablica nie jest zagnieżdżona, ten proces staje się nieco prostszy , ponieważ odwołanie nie jest potrzebne, ponieważ iterowana wartość nie jest tablicą, ale raczej „normalną” wartością:
int ib[3] = {1,2,3};
for (auto pl : ib)
cout << pl;
for (int n = 0; n != 3; ++n)
cout << ib[n];
Dodatkowe informacje
A co by było, gdybyśmy nie chcieli używać auto
słowa kluczowego podczas tworzenia pl
? Jakby to wyglądało?
W poniższym przykładzie pl
odwołuje się do pliku array of four integers
. Na każdej pętli pl
podawana jest wartość ia[n]
:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int (&pl)[4] : ia)
I ... Tak to działa, z dodatkowymi informacjami, które pozwolą uniknąć nieporozumień. To tylko „skrócona” for
pętla, która automatycznie liczy się za Ciebie, ale brakuje jej sposobu na odzyskanie bieżącej pętli bez robienia tego ręcznie.
for
. Ale w momencie, gdy tablica rozpada się na wskaźnik, informacja o rozmiarze zostaje utracona.