coutおよびprintfのバッファーおよび出力シーケンス
質問
今日、coutとprintfにバッファがあることを知っています。バッファはスタックのようなもので、coutとprintfの出力を右から左に取得し、上から(コンソールまたはファイルに)出力します。ボッテムへ。このように、
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)
次に、以下のコードを書きます
#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;
}
VS2005では、出力は
i=0 i++=-1 i--=0
i=0 i++=-1 i--=0
9 8 7
9 8 7
g ++((GCC)3.4.2(mingw-special))の下では、出力は、
i=0 i++=0 i--=1
i=0 i++=-1 i--=0
9 8 7
9 8 7
バッファはスタックのようです。ただし、今日は C ++ Primer Plus を読んでおり、coutは左から右に動作し、毎回オブジェクト(cout)を返すと言われているので、<!> quot; That <!>#8217 ; s insert <!> quot;を使用して出力を連結できる機能。しかし、左から右の方法ではcout <!> ltを説明できません。出力9 8 7 今、私はcoutのバッファがどのように機能するかについて混乱しています、誰かが私を助けることができますか?
解決
これはバグではなく、出力バッファリングとは関係ありません。
i--
およびi++
操作の実行順序は、同じ関数呼び出しのパラメーターとして複数回呼び出されると定義されません。
Iraimbilanjaの<!> quot; sequence points <!> quot;について詳しく説明する(おそらく正しい)ために、cout
バージョンは次と同等です。
(((cout << a) << b) << c)
実際には、それは単一のステートメントのように書かれていても、実際にはそれぞれのパラメーターが順番に評価される3つの別個の関数呼び出しです。
<<
演算子は実際にはostream& operator<<(ostream& os, int)
であるため、これを記述する別の方法は次のとおりです。
operator<< ( operator<< ( operator<< ( cout, a ), b ), c )
2つのパラメータが評価される順序は外部呼び出しでは定義されていないため(AFAIK)、右側の<!> quot; c <!> quotは完全に可能です。パラメータ(または、あなたの場合は<!> quot; <=> <!> quot;)は、左側のパラメータが評価される前に発生します。
他のヒント
の出力:
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
は指定されていません。これはC ++の一般的な落とし穴です。引数の評価順序は指定されていません。
coutの場合はそうではありません:単一の関数の引数ではなく、連鎖呼び出し(シーケンスポイント)を使用するため、評価順序は左から右に明確に定義されています。
編集:上記のコードの動作は実際には 未定義 。
可能であれば、gcc <!> gt; = 4に更新してみてください。4.0.1でこれを実行しただけで、ダンディが実行されます。