Diskuze: "Range-based for" smyčka

C++ C a C++ "Range-based for" smyčka

Avatar
pangas
Člen
Avatar
pangas:

Ahoj, mám dotaz ohledně zápisu takové smyčky:

int my_array[] = {1, 2, 3, 4, 5};
for(int& x : my_array)
{
  cout<<x<<endl;
}

Vykládám si to tak, že se do nové proměnné x uloží adresa pole my_array a poté se hodnota x zvětšuje o jedno, než nabude hodnoty stejné jako je adresa posledního prvku pole.
Je to opravdu takhle jednoduché?

 
Odpovědět 5. listopadu 22:16
Avatar
pangas
Člen
Avatar
pangas:

Respektive, že se do x uloží hodnota uložená na adrese pole my_array a poté se adresa x zvětšuje o 1.

 
Nahoru Odpovědět 5. listopadu 22:21
Avatar
pangas
Člen
Avatar
pangas:

Další situace, které nerozumím je to, že výše zmíněný kus kódu, mi ve funkci main funguje tak, jak má. Pokud ale stejný kód použiji v metodě třídy, dostávám error "begin and end was not declared in this scope".

void List::removeAll(int d[]){
    for(int& i : d)
        removeAll(i);

Pozn: Metoda removeAll je přetížená, takže removeAll(i) je v pořádku.
Budu vděčný za odezvu.

Editováno 5. listopadu 23:09
 
Nahoru Odpovědět 5. listopadu 23:08
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na pangas
Martin Dráb:

Respektive, že se do x uloží hodnota uložená na adrese pole my_array a poté se adresa x zvětšuje o 1.

Já tomu rozumím tak, že se v každé iteraci vzniká proměnná i, což je reference na int a postupně se směruje na jednotlivé položky zadaného pole (v jedné iteraci na jednu položku). To je samozřejmě pohled bez optimalizací. Optimalizovaný kód bude vypadat trochu jinak.

error "begin and end was not declared in this scope"

Protože ta funkce neví, jak velké pole jsi ji předal. V C/C++ je pole v zásadě jen ukazatel na jeho první prvek a následující výrazy jsou ekvivalentní:

a[i]
*(a + i)

A jelikož není známá velikost toho pole, for smyčka neví, kdy má skončit.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět 5. listopadu 23:21
2 + 2 = 5 for extremely large values of 2
Avatar
pangas
Člen
Avatar
Odpovídá na Martin Dráb
pangas:

Aha, ale jak tedy obejít to, že předem nevím, jak velké pole bude vstupovat do funkce jako parametr?

 
Nahoru Odpovědět 6. listopadu 13:17
Avatar
HONZ4
Člen
Avatar
Odpovídá na pangas
HONZ4:

místo pole použít třeba vector

 
Nahoru Odpovědět  +1 6. listopadu 13:23
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na pangas
Martin Dráb:

Nebo si velikost pole předávat také jako parametr funkce, pokud se ti nelíbí režie zavedená použitím kontejneru (např ten std::vector<T>). Pak ale samozřejmě nepůjde použít tento fajnový konstrukt for cyklu.

Nahoru Odpovědět 6. listopadu 13:50
2 + 2 = 5 for extremely large values of 2
Avatar
pangas
Člen
Avatar
pangas:

Díky oběma, už to funguje, jak má. Snad jsem pochopil i ten range-based cyklus.

 
Nahoru Odpovědět 6. listopadu 13:56
Avatar
pangas
Člen
Avatar
Odpovídá na Martin Dráb
pangas:

To byla nouzová situace, ale mě se nelíbilo předávat délku pole jako parametr. Vektor mi asi vyhovuje více pro tento účel.

 
Nahoru Odpovědět 6. listopadu 13:58
Avatar
ostrozan
Redaktor
Avatar
ostrozan:

Hmm to vidím poprvé :

int my_array[] = {1, 2, 3, 4, 5};
for(int& x : my_array)
{
  cout<<x<<endl;
}

není to jen jednodušší varianta foreach ?

int my_array[] = {1, 2, 3, 4, 5};
for each(int x in my_array)
{
  cout<<x<<endl;
}

kde je úplně jedno jak je pole dlouhé

 
Nahoru Odpovědět 6. listopadu 14:15
Avatar
Drahomír Hanák
Tým ITnetwork
Avatar
Odpovídá na ostrozan
Drahomír Hanák:

for each není ve standardu klasického C++ (https://msdn.microsoft.com/…s177202.aspx), ale s range-based for jde dělat to samé. Bude to fungovat i pro vlastní typy, pokud pro ně definuješ metody begin a end, které vrátí iterátor.

 
Nahoru Odpovědět  +3 6. listopadu 15:31
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 11 zpráv z 11.