il buffer e la sequenza di output di cout e printf
Domanda
So che cout e printf hanno buffer oggi, e si dice che il buffer sia un po 'come uno stack e ottenga l'output di cout e printf da destra a sinistra, quindi li distribuisca (alla console o al file) dall'alto a bottem. In questo modo,
a = 1; b = 2; c = 3;
cout<<a<<b<<c<<endl;
buffer:|3|2|1|<- (take “<-” as a poniter)
output:|3|2|<- (output 1)
|3|<- (output 2)
|<- (output 3)
Quindi scrivo un codice qui sotto,
#include <iostream>
using namespace std;
int c = 6;
int f()
{
c+=1;
return c;
}
int main()
{
int i = 0;
cout <<"i="<<i<<" i++="<<i++<<" i--="<<i--<<endl;
i = 0;
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
cout<<f()<<" "<<f()<<" "<<f()<<endl;
c = 6;
printf("%d %d %d\n" , f() , f() ,f() );
system("pause");
return 0;
}
In VS2005, l'output è
i=0 i++=-1 i--=0
i=0 i++=-1 i--=0
9 8 7
9 8 7
In g ++ ((GCC) 3.4.2 (mingw-special)), l'output è,
i=0 i++=0 i--=1
i=0 i++=-1 i--=0
9 8 7
9 8 7
Sembra che il buffer sia come uno stack. Tuttavia, ho letto C ++ Primer Plus oggi, e si dice che il cout funzioni da sinistra a destra, ogni volta restituisce un oggetto (cout), quindi & Quot; That & # 8217 ; s la funzione che ti permette di concatenare l'output usando l'inserimento " ;. Ma il modo da sinistra a destra non può spiegare cout & Lt; uscita 9 8 7 Ora sono confuso su come funziona il buffer di Cout, qualcuno può aiutarmi?
Soluzione
Questo non è un bug, né ha nulla a che fare con il buffering dell'output.
L'ordine di esecuzione delle operazioni i--
e i++
non è definito quando vengono invocati più di una volta come parametri per la stessa chiamata di funzione.
Per elaborare (e possibilmente correggere) la menzione di Iraimbilanja su " punti sequenza " ;, la cout
versione equivale a:
(((cout << a) << b) << c)
In effetti, si tratta in realtà di tre chiamate di funzioni separate, ciascuno dei cui parametri vengono valutati in ordine, anche se è scritto come una singola istruzione.
L'operatore <<
è veramente ostream& operator<<(ostream& os, int)
, quindi un altro modo di scrivere questo è:
operator<< ( operator<< ( operator<< ( cout, a ), b ), c )
Poiché per la chiamata esterna non è definito (AFAIK) l'ordine in cui vengono valutati i due parametri, è perfettamente possibile per la mano destra " c " parametro (o nel tuo caso " <=> ") che si verificano prima che il parametro di sinistra venga valutato.
Altri suggerimenti
L'output di:
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
non è specificato. Questa è una trappola comune del C ++: l'ordine di valutazione degli argomenti non è specificato.
Non è così con il caso cout: usa chiamate concatenate (punti sequenza), non argomenti per una singola funzione, quindi l'ordine di valutazione è ben definito da sinistra a destra.
Modifica: David Thornley sottolinea che il comportamento del codice sopra riportato è in effetti undefined .
se possibile, prova ad aggiornare a gcc > = 4. l'ho appena eseguito su 4.0.1 ed esegue semplicemente dandy.