2009-03-18 16 views
1

私は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) 

は、その後、私はVS2005下

#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; 
} 

、以下のコードを記述し、このように、出力は++ G下((GCC)3.4.2(MinGWの特殊

i=0 i++=-1 i--=0 
i=0 i++=-1 i--=0 
9 8 7 
9 8 7 

あります))、出力は、

i=0 i++=0 i--=1 
i=0 i++=-1 i--=0 
9 8 7 
9 8 7 

bうーんはスタックのようなものです。しかし、私はC++ Primer Plusを今日読んでおり、左から右に向かって、常にオブジェクト(cout)を返すと言われています。「これは、挿入を使って出力を連結できる機能です。しかし、左から右に向かって説明することはできません<出力9 8 7 今、私は傷のバッファがどのように働いているのか、誰か助けてくれますか?

答えて

3

これはバグではなく、出力バッファリングとは関係ありません。

i--i++操作の実行順序は、同じ関数呼び出しのパラメータとして2回以上呼び出されたときには定義されません。

手の込んだ(そしておそらく正しい)するには、「シーケンスポイント」のIraimbilanjaの言及、coutバージョンは同等です:効果的

(((cout << a) << b) << c) 

、それは、そのパラメータのそれぞれを順に評価され、実際には3つの別々の関数呼び出しですたとえ1つのステートメントのように書かれていても。

<<オペレータが本当にostream& operator<<(ostream& os, int)あるので、これを書いている別の方法がある:

operator<< (operator<< (operator<< (cout, a), b), c) 

外のため、それは(私の知る限り)ではありません呼び出すので、2つのパラメータが評価される順序が定義され、それがために完全に可能です左手のパラメーターが評価される前に右手の "c"パラメーター(またはあなたの場合 "i--")が起こるようにします。

+0

こんにちは、Alnitak、私は訂正バッファーが右から左に出力を得て、それから右から左に出すと思うという質問があります。しかし、私はあなたのコードでは、耳のバッファーは左から右に出力を得ると思う、それは本当ですか?ありがとう〜 – lucas

+0

g ++では、cout << "i =" << i << "i ++ =" << i ++ << "i - =" << i - << endl;出力 i = 0 i ++ = 0 i - = 1 vs2005では、出力は i = 0 i ++ = - 1 i - = 0 これを説明できますか? – lucas

+0

違いを説明することはできませんが、私が示した左から右の入れ子には自信があります。この関数はostream&operator <<(ostream&、)ですので、そのようにネストする必要があります。 – Alnitak

6

の出力:

printf("i=%d i++=%d i--=%d\n" , i , i++ ,i--); 

が指定されていません。これはC++の一般的な落とし穴です。引数の評価順序は不明です。

coutの場合はそうではありません。連鎖呼び出し(シーケンスポイント)を使用し、単一の関数への引数ではないため、評価の順序は左から右に明確に定義されます。

編集:デビッド・ソーンリーは、上記のコードの動作は事実undefinedであることを指摘しています。

+0

それは不特定より悪いです。それは未定義です。結果が評価の順序と一致することは保証されていませんが、通常は明白な実装を考えれば起こります。しかし、痛風の場合の説明は+1。 –

0

可能であれば、gcc> = 4に更新してみてください。私は4.0.1でこれを実行しました。ちょうどdandyを実行します。

+0

gcc 3.xは非常に古く、一般的には更新が良いアイデアかもしれませんが、この場合、結果はどれも「正しい」ものではありません。単なるコンパイラのバージョンから次のコンパイラのバージョンに変わる可能性があります。 – janneb

+2

これは未定義の振る舞いであり、(a)どのような振る舞いも標準に従うだけであり、(b)他のバージョンや他のコンパイラオプション、その他の周辺コード。 –

関連する問題