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:
iajest tablicą tablic („tablica zagnieżdżona”) zawierającą [3]tablice, z których każda zawiera [4]wartości. Powyższy przykład przechodzi iaprzez 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:
plrówna się {1,2,3,4}- tablica
- Druga pętla:
plrówna się {5,6,7,8}- tablica
- Trzecia pętla:
plró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
njest to liczba, to ia[n]jest to samo co *(ia+n)(Wyłuskujemy adres będący nwpisami naprzód) i ia+njest taki sam jak &ia[n](Otrzymujemy adres tego wpisu w tablicy).
Oto co się dzieje:
- W każdej pętli
pljest ustawiana jako odniesienie do ia[n], z nwyrównywaniem bieżącej liczby pętli zaczynając od 0. Tak więc pljest 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+njest 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ć autosłowa kluczowego podczas tworzenia pl? Jakby to wyglądało?
W poniższym przykładzie plodwołuje się do pliku array of four integers. Na każdej pętli plpodawana 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” forpę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.