C++ - ha a for ciklus feltétele menet közben változik, a ciklus ezt figyelembe veszi és változtat a végrehajtások számán?
Az eset:
//myvector.size()=3
//mybool=true;
for(int i = 0; i < myvector.size(); i++)
{
if(mybool==true)
{
myvector.erase(myvector.begin()+i);
mybool=false;
}
}
Nem vagyok benne biztos, de szerintem ez attól is függ, hogy mennyire van optimalizálva a kód.
De egy dolgot biztosra tudok: programozástechnikailag nem helyes egy számlálós ciklusban menet közben a ciklusfeltételen változtatni.
A kérdés hatalmas hülyeség.
Gondold csak át.
Szerinted egy for (int i=0; i < 1; ++i) végtelen ciklust eredményez?
Másrészről igaza van #1-nek, ez teljesen hibás ciklus használat.
Nem értem egyeseket, hogy miért ugatnak. Lásd #1 és #2; Tervezés függvénye az egész. A "for" az visszavezethető "while"-ra. Szóval ugyanott tartunk.
int i = 0;
while(i < 10) { /* kód */ i++; }
Fenti megegegyezik ezzel:
for(int i = 0; i < 10; i++) { /* kód */ }
Nos akkor ha így irjuk, akkor így is jó:
int i = 0;
for(; i < 10; i++) { /* kód */ }
Igaz az i változó megmarad for után is az aktuális értékével
Mind a 3 megoldás ugyanazt eredményezi, csak az egyik átláthatóbb a másik kevésbé.
Innentől kezdve, ha feltételt módosítani akarod, tessék.
int i = 0; // az i változó megmarad while után
while(i < A.size()) { /* kód */ i++; }
Ugyanazt csinálja mint ez:
for(int i = 0; i < A.size(); i++) { /* kód */ } // az i változó nem gmarad meg a for után
Szóval: Természetesen a feltételt szükségesség és a feladat probléma megoldása miatt változtathatod. Az már más dolog, ha rosszúl tervezed meg és végtelen ciklusba esik.
Visszatérve. Ha "++i;"-t írnál, az nem befolyásol semmit. Mivel ha megnézed:
int i = 0;
while(i < 10) { /* kód */ ++i; }
Semmiben se folyásolja be a futást.
Végeredmény: #1 és #2 hülyeséget beszélt...
Senki nem mondta, hogy a for nem vezethető vissza whilera.
Azt mondtuk, hogy az itt szereplő kód orbitális baromság.
Ha se szöveget értelmezni, se programozni nem tudaz, akkor minek ugatsz bele?
Nézd már meg azt a kib#szott kódot könyórgöm...
Magyarázzam el sorról sorra?
Kódban se látok problémát, amennyiben így tervezte meg a kérdező. Mondom is mért. (Látod? Érvelek...)
//myvector.size() = 3
//mybool=false;
for(int i = 0; i < myvector.size(); i++) if(mybool==true) {
myvector.erase(myvector.begin()+i);
mybool=false;
}
Így láthatóbb.
----------------
0. Iteráció:
i=0; size=3; mybool=true
Művelet: kitöröljük a 0. indexű elemet. Így marad 2, majd false-ra állítjuk a kapcsolót. i-hez adunk 1-et.
----------------
1. Iteráció:
i=1; size=2; mybool=false
Művelet: if-be nem megy be, így i-n növelünk 1-et.
----------------
2. iteráció:
i=2; size=2, mybool=false
Művelet: Feltétel szerint (i < size) hamis, így befejezzük a ciklust.
----------------
Bár az igez, és egyet is értek avval, hogy felesleges ciklus futások történhetnek. a false-ra állítást után én egy break-et tennék bele, és probléma letudva. Ennyi erővel, persze lehet egyszerűbben is megoldani ezt.
Továbbá én nem szoktam C++ozni, így gyorban néztem egy dokumentációt, hogy a vektor hogyan működik. Remélem jól értelmeztem a fenti levezés alapján.
DE!
A kérdező nem azt kérdezte, hogy ez a kód jó-e így, hanem hogy a feltételt változtatni lehet-e. Igen. Lehet.
Szóval a fenti kód és a kérdés lényege 2 külön dolog. Így a kérdező ilyen kódot is írhatott volna:
if(int i = 0; i < var; i++) { /*kód és itt módosul a var-is*/ }
A kérdés lényege az, hogy amennyiben változtatom a ciklus feltételét (legyen az átláthatósább kedvéért var), majd azt csökkentem, az változtat-e a cikluson?
Lásd:
int var = 3;
for(int i = 0; i < var; i++){
if(i==0)var--;
}
Kivettem belőle a myboolt, hogy átláthatóbb legyen.
Az én tippem az lenne viszont, hogy a ciklus minden esetben ellenőrzi a feltétele helyességét a jelenlegi adatokkal, így ebben az esetben csak kétszer fut le a ciklus, hiába 3 a var értéke eredetileg. Helyes-e ez a következtetés?
Igen, figyelembe veszi, de a kódod nem úgy fog működni hogy azt te szeretnéd:
Ha törlöd az első elemet, a második elem lesz az első és mivel a az "i"-t is növeled, az eredeti listából a harmadik elemet fogod a következő körben vizsgálni.
Láthatod, sok bug forrása lehet ha figyelmetlenül módosítod azt a tárolót amin épp végigiterálsz, ezért rossz gyakorlatnak számít, de van amikor nem nagyon lehet megkerülni. Kicsit alakítsd át úgy, hogy csak akkor növelje az i-t, ha nem töröltél:
int i = 0;
while(i < myvector.size()) {
if(mybool) {
myvector.erase(myvector.begin()+i);
} else {
i++;
}
}
Alternatív megoldás lehet ha nem az eredeti vektorból törölsz, hanem egy új vektort építsz:
for(int i = 0; i < myvector.size(); i++) {
if(!mybool)
newvector.push_back(myvector[i]);
}
Pontosan. Erről beszéltem, mikor visszavezettem while-ra.
int var = 3;
for(int i = 0; i < var; i++){
if(i==0)var--;
}
Ez ugyan ez:
int var = 3;
while(i < var) {
if(i==0) var--;
i++
}
Mivel memóriában 1 változónak 1x foglal helyet, így azt módosítod. Azaz a változtatott értékeket hasonlítja össze. Ami 3 volt már 2 lesz.
Én úgy használtam annó, hogy egy téglalap alapú mátrixot fel kellet feltöltenem, aminek a méretét nem ismertem. (Pontosabban nem fértem hozzá.)
Mivel a négyzet is téglalat lényegében, csak egyenlőek az oldalai. Így tudtam, hogy ha úgy töltöm fel, mint egy négyzetett, akkor előbb utóbb az egész megtelik.
Nos ugyebár, ha olyan helyre akarok tenni egy elemet, ami már a mátrixon kívül van, az baj.
Erre használtam én is azt a megoldást, hogy növeltem a ciklus feltételen (nem csükkentettem, hanem növeltem), mivel ha nem a mátrixra teszem le az elemet és nem növelek az értéken, akkor annyi üres hely lesz a mátrixban, ahányat félre pakoltam.
De mondom. Tervezés függő az egész.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!