Jak za pomocą preprocesora zamienić pętle for na while?
Preprocesor - zamiana for na while
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Space: the final frontier
- Postów: 26433
Przeczytać dokumentację na temat #define? Podpowiedź:
#define while for
spowoduje zamianę słowa while na słowo for.
- Rejestracja: dni
- Ostatnio: dni
Nie słów for na while, tylko całej pętli for na całą pętle while.
Wiem, że jest wzór na zamianę tych pętli, taki, że:
for(A;B;C)
{
D
}
jest równoważne z:
A;
while (B)
(D
C;
}
Tylko jak to pre procesorem zrobić?
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Space: the final frontier
- Postów: 26433
Specjalistą od #define nie jestem ale mam wątpliwości czy w ogóle można to zrobić. Najbliższe które udało mi się napisać to:
#define for(a,b,c) a; while(b) c
co potrafi takie coś:
#define for(a,b,c) a; while(b) c
int main(){
int i,j;
for(i=0,i<10,i++);
return 0;
}
Przerobić na:
int main(){
int i,j;
i=0; while(i<10) i++;
return 0;
}
- Rejestracja: dni
- Ostatnio: dni
Chciałbym, aby to tak działało, też tak próbowałem, ale niestety nie działa.
- Rejestracja: dni
- Ostatnio: dni
#define for(a,b,c) {a; while(b) {c;}}
- Rejestracja: dni
- Ostatnio: dni
Ale żeby jeszcze ciało pętli jakoś działało... to chyba nie bardzo się da. A w ogóle to po co Ci coś takiego?
- Rejestracja: dni
- Ostatnio: dni
Potrzebuje by kod był optymalizowany na poziomie kompilacji i do tego potrzebna zamiana for na while.
to co podaliście nie działa niestety. Sama linijka się kompiluje, ale potem w pętli błędy wychodzą.
- Rejestracja: dni
- Ostatnio: dni
Kod działa identycznie, ale while szybciej się wykonuje. Jedno obliczanie pętli mniej.
- Rejestracja: dni
- Ostatnio: dni
Yyyyy... NIE! Wszystko zależy jak warunki ustawisz.
- Rejestracja: dni
- Ostatnio: dni
Hm, przykładowy kod:
int main() {
int a;
#ifdef USE_FOR
for (int i = 0; i < 10; ++i) {
a += 5 + i;
}
#else
{
int i = 0;
while (i < 10) {
a += 5 + i;
++i;
}
}
#endif
return 0;
}
Używając g++ 4.6.0:
$ g++ -S -o while.s cpp_main.cpp && g++ -S -DUSE_FOR -o for.s cpp_main.cpp && diff for.s while.s
0 ;) azrael@/e/Projekty/CPP
$ g++ -o a.exe cpp_main.cpp && g++ -o b.exe -DUSE_FOR cpp_main.cpp && cmp a.exe b.exe
0 ;) azrael@/e/Projekty/CPP
$ _
Czyli akurat w tej sytuacji nie ma żadnej różnicy, czy użyjesz for czy while. Dosłownie, wygenerowany kod asm jest identyczny, a więc i binarki są takie same. Podejrzewam (pewności nie mam), że for/while zawsze wyglądają w wygenerowanym asm tak samo.
edit: hm, chyba mi się przywidziało jednak coś, -O3 daje w tym przypadku takie same binarki - przez moment wydawało mi się, że ten sam asm dawał przy -O3 inne pliki .exe.
- Rejestracja: dni
- Ostatnio: dni
Kolejne mistrzostwo optymalizacji...
Kompilator potrafi robić znacznie bardziej skomplikowane rzeczy niż zamiana pętli for na wh... Wróć, nie robi żadnej zamiany bo dla kodu maszynowego nie ma czegoś takiego jak "pętla" są tylko skoki warunkowe.