PDA

View Full Version : [C++]Una sciocchezza sul ciclo for


swarm
18-07-2006, 13:18
Salve a tutti

mi trovo a scomodarvi per una sciocchezza, ma non trovo qualcosa che mi spieghi nel dettaglio come funziona il ciclo for e quindi lo chiedo a voi.

for(<inizializzazione>;<condizione>;<avanzamento>)

in pratica volevo sapere come fare questo; ipotizzando un ciclo for di questo tipo:

for (indice=0; indice<5 && <condizione>; indice++)
{

}

se, ad esempio, la <condizione> non vale più quando sono alla terza iterazione (indice = 3), entro nel for, la condizione non è verificata, ma indice viene comunque incrementato a 4.

come fare per lasciarlo = 3?

spero di essere stato chiaro (cosa che spesso non mi riesce :muro: )

scusate per la banalità

vi ringrazio :)

PS: in pratica vorrei evitare di dover scrivere, per quello che mi serve,

indice = indice - 1

fuori dal for :fagiano:

Black imp
18-07-2006, 13:27
nella seconda sezione del for hai la cosiddetta 'condizione di permanenza' o meglio di ingresso: nel senso che se quella condizione non è verificata il ciclo si interrompe SENZA eseguire la terza sezione , nella quale potresti anche non mettere niente tra l'altro. quindi il tuo incremento non viene eseguito se la condizione non è vera e infatti gli indici incrementati vengono poi utilizzati per capire a che punto il ciclo si è interrotto. la condizione di permanenza deve essere letta come un valore booleano per il compilatore quindi deve essere scritta tra parentesi

for (;(varbool&&(pippo==5)&&(!file.leggicarattere==eof));)
;

tanto per fare un esempio stupido :)

nota che scritto così, col ; subito dopo senza alcuna istruzione, apparentemente il ciclo non fa nulla, in realtà ad ogni iterazione in cui controlla se file.leggicarattere non ha letto un carattere nullo, lo sta di fatto eseguendo e quindi avanza nel file.

ilsensine
18-07-2006, 13:30
se, ad esempio, la <condizione> non vale più quando sono alla terza iterazione (indice = 3), entro nel for, la condizione non è verificata, ma indice viene comunque incrementato a 4.
Non è così. "indice" non viene più toccato se la condizione diventa falsa.

Prova:

for (i=0; 0; i++) { }

e vedrai che i alla fine vale 0, non 1.

il_luridone
18-07-2006, 13:37
for(<inizializzazione>;<condizione>;<avanzamento>)

il ciclo for ha questa semantica:

1. <inizializzazione>
2. se <condizione>
3. <istruzione>
4. <avanzamento>
5. goto 2

L'unico modo per non far eseguire l'avanzamento che non ti piace è togliere la condizione aggiuntiva dalla guardia e usare un break dentro al ciclo for.

for (i = 0; i < 5; i++) {
// ...
if (<condizione>)
break;
// ...
}

Non è esattamente programmazione strutturata, molti i break e i continue non li vogliono usare.

Decidi tu in base alla situazione se è meglio un index-- o un break.

andbin
18-07-2006, 13:38
deve essere letta come un valore booleano per il compilatore quindi deve essere scritta tra parentesi

for (;(varbool&&(pippo==5)&&(!file.leggicarattere==eof)); )
;E dove sta scritto?? :p

Semmai se leggicarattere è un metodo, si deve scrive allora:

for (; varbool && pippo==5 && !(file.leggicarattere()==eof); )
;

swarm
18-07-2006, 13:45
Non è così. "indice" non viene più toccato se la condizione diventa falsa.

Prova:

for (i=0; 0; i++) { }

e vedrai che i alla fine vale 0, non 1.

infatti, devo controllare meglio, non capisco perchè si incrementa...

nel mio caso, indice è un iteratore di un list<>, e quando esco dal for me lo trovo cmq avanzato.....

ecco che faccio



list<classe>:: iterator it;
bool bRet;
bRet = false;

for (it = getFile().begin(); it != getFile().end() && bRet == false; it++)
{

}



all'interno del for, ad un certo punto, io trovo l'elemento di interesse, e pongo bRet = true, quindi dovrei uscire dal for.

quando subito dopo, vado a prendermi l'elemento trovato, mi ritrovo il successivo.....

il_luridone
18-07-2006, 13:58
infatti, devo controllare meglio, non capisco perchè si incrementa...

Si incrementa perchè all'inizio bRet è falso, quindi la guardia è falsa ed entra nel corpo del ciclo.

Non è che se la variabile bRet diventa vera il for esce istantaneamente. Il corpo del for continua ad essere eseguito e con esso l'avanzamento (che viene fatto alla fine), poi alla successiva iterazione la guardia viene ricontrollata e risulta falsa: il for esce.

Again: se vuoi che schizzi fuori dal ciclo, appena bRet diventa vera mettici un break.

swarm
18-07-2006, 14:10
Si incrementa perchè all'inizio bRet è falso, quindi la guardia è falsa ed entra nel corpo del ciclo.

Non è che se la variabile bRet diventa vera il for esce istantaneamente. Il corpo del for continua ad essere eseguito e con esso l'avanzamento (che viene fatto alla fine), poi alla successiva iterazione la guardia viene ricontrollata e risulta falsa: il for esce.

Again: se vuoi che schizzi fuori dal ciclo, appena bRet diventa vera mettici un break.

infatti....

alla fine mi resta decrementare quando esco, poichè i break, se non sbaglio (poi ricontrollo) mi sono "proibiti" dalle specifiche sul codice :mc:

andbin
18-07-2006, 14:18
se non sbaglio (poi ricontrollo) mi sono "proibiti" dalle specifiche sul codice :mc:Allora puoi fare:
for (it = getFile().begin(); it != getFile().end() && bRet == false; bRet == false ? it++ : 1)

il_luridone
18-07-2006, 14:23
và che finezza ti snocciola andbin.

swarm
18-07-2006, 14:26
Allora puoi fare:
for (it = getFile().begin(); it != getFile().end() && bRet == false; bRet == false ? it++ : 1)

che tu sei un grande non c'è bisogno che te lo dica io...

ma la vuoi sapere l'ultima?

mi è impedito l'uso dell'operatore condizionale ? (perchè "poco leggibile") :mad:

e allora gli metto

it--;

alla fine del for e vaff.....

alla faccia del bello stile :D

andbin
18-07-2006, 14:40
mi è impedito l'uso dell'operatore condizionale ? (perchè "poco leggibile") :mad:Poco leggibile??? Peccato comunque. :(
In questo momento non mi viene in mente altro.

swarm
18-07-2006, 14:45
Poco leggibile??? Peccato comunque. :(
In questo momento non mi viene in mente altro.

figurati, sei stato gentilisssssssssssssssssssssssssssssssssssimo

grazie a te e agli altri

byez

Black imp
18-07-2006, 15:11
E dove sta scritto?? :p

Semmai se leggicarattere è un metodo, si deve scrive allora:

for (; varbool && pippo==5 && !(file.leggicarattere()==eof); )
;

a me diverse volte ha dato errore

andbin
18-07-2006, 15:23
a me diverse volte ha dato erroreMa proprio errore in compilazione?? O un comportamento a run-time "diverso" da quanto aspettato?? (nel secondo caso, spesso è dovuto alla questione della precedenza degli operatori).

Black imp
18-07-2006, 15:30
Ma proprio errore in compilazione?? O un comportamento a run-time "diverso" da quanto aspettato?? (nel secondo caso, spesso è dovuto alla questione della precedenza degli operatori).


no no dico in compilazione. adesso non dico proprio questo caso specifico però spesso quando bello baldanzoso tolgo le parentesi dopo gli if per es. mi cazzia subito: cioè scrivo magari if (pippo&& pluto==4) e non gli piace che il pluto==4 non sia tra parentesi - era questo che in realtà volevo dire, quando c'è una espressione di questo tipo -. forse il ciclo for non le richiede e le ho sempre messe per precauzione... proverò... :)

trallallero
18-07-2006, 15:31
mi è impedito l'uso dell'operatore condizionale ? (perchè "poco leggibile") :mad:
:eek: ???
e magari ti é permesso il goto :muro:

andbin
18-07-2006, 15:51
cioè scrivo magari if (pippo&& pluto==4) e non gli piace che il pluto==4 non sia tra parentesiStrano ... l'espressione if (pippo&& pluto==4) è corretta dal punto di vista della sintassi. Bisognerebbe poi vedere cosa sono pippo e pluto ma comunque non dovrebbe affatto dare errori in compilazione.

Black imp
18-07-2006, 16:03
Strano ... l'espressione if (pippo&& pluto==4) è corretta dal punto di vista della sintassi. Bisognerebbe poi vedere cosa sono pippo e pluto ma comunque non dovrebbe affatto dare errori in compilazione.


fa conto che pippo sia boolean e pluto un int. sotto java sono sicurissimo che mi rompeva le balle ma java l'ho eliminato dalla mia vita. sotto c e c++ anche ma non ricordo se solo col gcc o anche col visual c++... :mbe: ma onestamente anche sui libri sui quali ho studiato ho visto mettere meno parentesi di quelle che poi i compilatori mi chiedevano :mc:

Qu@ker
18-07-2006, 20:53
Ho letto in fretta e potrei non aver capito nulla, ma voglio comunque dire la mia... :D


for (it = getFile().begin();
it != getFile().end() && bRet == false;
it += (bRet == false))

Black imp
18-07-2006, 21:25
Strano ... l'espressione if (pippo&& pluto==4) è corretta dal punto di vista della sintassi. Bisognerebbe poi vedere cosa sono pippo e pluto ma comunque non dovrebbe affatto dare errori in compilazione.


ho provato una cosa simile su visual c++ e la accetta... mah :confused:

swarm
19-07-2006, 07:58
:eek: ???
e magari ti é permesso il goto :muro:

nemmeno

"vietato" l'uso :stordita:

ilsensine
19-07-2006, 17:30
it += (bRet == false)

it è un iteratore...

Qu@ker
19-07-2006, 18:37
it è un iteratore...

E quindi... ?

jcd@big:/tmp$ cat test_it.cpp
#include <iostream>
#include <vector>

typedef std::vector<int>::iterator vit;

int main(void)
{
bool b = false;
std::vector<int> v;

for (int i = 0; i < 5; ++i)
v.push_back(i);

for (vit i = v.begin(); i != v.end(); i += (b == false))
std::cout << *i << std::endl;
}
jcd@big:/tmp$ g++ test_it.cpp -o test_it -Wall
jcd@big:/tmp$ ./test_it
0
1
2
3
4
jcd@big:/tmp$

trallallero
20-07-2006, 07:13
nemmeno

"vietato" l'uso :stordita:
il "goto" te lo dovrebbe vietare il tuo stesso senso etico :D
ma il "?" ... se me lo togli smetto di programmare :sob:

ilsensine
20-07-2006, 08:34
E quindi... ?

jcd@big:/tmp$ cat test_it.cpp
#include <iostream>
#include <vector>

typedef std::vector<int>::iterator vit;

int main(void)
{
bool b = false;
std::vector<int> v;

for (int i = 0; i < 5; ++i)
v.push_back(i);

for (vit i = v.begin(); i != v.end(); i += (b == false))
std::cout << *i << std::endl;
}
jcd@big:/tmp$ g++ test_it.cpp -o test_it -Wall
jcd@big:/tmp$ ./test_it
0
1
2
3
4
jcd@big:/tmp$

Funziona su std::vector, non su std::list

#include <iostream>
#include <list>

typedef std::list<int>::iterator lit;

int main(void)
{
bool b = false;
std::list<int> l;

for (int i = 0; i < 5; ++i)
l.push_back(i);

for (lit i = l.begin(); i != l.end(); i += (b == false))
std::cout << *i << std::endl;
return 0;
}

g++ -o it it.cpp
it.cpp: In function 'int main()':
it.cpp:14: error: no match for 'operator+=' in 'i += (b == false)'

swarm
20-07-2006, 10:41
alla fine ho risolto così:



bool bTrovato = false;

it=getFile()->getLst().begin(); // inizializzazione all'inizio della lista

while (it !=getFile()->getLst.end() && bTrovato == false) {

// ricerca dell'elemento
if (<elemento trovato>) {
bTrovato = true;
}

if (bTrovato == false) {
it++;
}
}



nn sarà il massimo, ma almeno funziona :fagiano: :fagiano:

grazie a tutti!!

Qu@ker
20-07-2006, 15:48
Funziona su std::vector, non su std::list

Hai ragione, non avevo visto che si parlava di liste. :fagiano: