odrobine poprawie cepe
mianowicie nie jest "od tylu" dlatego ze uzywasz strumieni, tylko dlatego ze.. to jest normalne
wezmy przykladowy program
#include<stdio.h>
int
main( void )
{
int i = 1;
printf( "%i %i %i %i\\n", i++, i++, i++, i++ );
return 0;
}
co to pokaze?
powinno 1 2 3 4.. a pokazuje
20:39:39 LiTeStEp >gcc asdf.c
20:39:45 LiTeStEp >a
4 3 2 1
20:39:45 LiTeStEp >
dlaczego tak sie dzieje? z paru przyczyn parametry sa analizowane, tj wyliczane/wstawiane na stos od tylu...
tj powyzszy kod bedzie przetlumaczony na pseudoasmowy kod tak:
mov i, 1
push i // i == 1, 4rty parametr
inc i // i == 1+1
push i // i == 2, 3ci parametr
inc i // i == 2+1
push i // i == 3, 2gi parametr
inc i // i == 3+1
push i // i == 4, 1szy parametr
inc i // i == 4+1
call printf
ret
a jako ze parametry byly wrzucane od tylu, to rzeczywiscie
"%i %i %i %i" zamieni sie na "4 3 2 1"
dlaczego takie udziwnienie?
a zeby funkcje( cos, ... ) dzialaly dobrze... tam sie w sumie zadna magia nie dzieje, np
void func( int ile, ... )
{
int *p = (&ile) + 1;
while( ile-- ) printf( "%i ", *p++ );
}
func( 4, 1, 2, 3, 4 );
czyli po prostu w pamieci argumenty sa po sobie
a dlaczego wiec sa wrzucane na stos od tylu ?
bo stos "rosnie" w strone zera, tj kazde wrzucenie powoduje ze adres nastepnego elementu bedzie MNIEJSZY... wiec musza byc od tylu wrzucane ;p
w przypadku << i >> jest podobnie, ale na innej zasadzie, wkoncu
a << b
oznacza a przesuniente o b (niewazne ze przeciazone w cout jest), a wyrazenie
a << b << c << d
kompilator zrozumie jako a przesuniente o b << c << d, czyli
a << ( b << c << d ), idac dalej a << ( b << ( c << ( d ) ) )
i liczone najpierw bedzie c << d (ktore z tej dwojki najpierw? nie wiem ;p),
potem b a potem a...
czyli nasze "na wspak" ;>
mam nadzieje ze mnie nie wylogowalo, ze za duzo nie naklamalem i ze za duzo nie pokrecilem i ze cos mozna z tego zrozumiec
</cpp>