буфер и последовательность вывода cout и printf - PullRequest
1 голос
/ 18 марта 2009

Я знаю, что у 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), так что «Это функция, которая позволяет объединять вывод с помощью вставки ». Но путь слева направо не может объяснить cout

Ответы [ 3 ]

6 голосов
/ 18 марта 2009

Выход:

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

не указано. Это распространенная ошибка в C ++: порядок вычисления аргументов не указан.

Не так со случаем cout: он использует цепочечные вызовы (точки последовательности), а не аргументы для одной функции, поэтому порядок вычисления четко определен слева направо.

Редактировать: Дэвид Торнли указывает, что поведение приведенного выше кода на самом деле не определено .

3 голосов
/ 18 марта 2009

Это не ошибка и не имеет ничего общего с буферизацией вывода.

Порядок выполнения операций i-- и i++ не определяется, когда они вызываются более одного раза в качестве параметров для одного и того же вызова функции.

Чтобы уточнить (и, возможно, исправить) упоминание Ираимбиланджей о «точках последовательности», версия cout эквивалентна:

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

Фактически это фактически три отдельных вызова функций, каждый из параметров которых оценивается по порядку, даже если он написан как один оператор.

Оператор << на самом деле ostream& operator<<(ostream& os, int), поэтому можно написать еще один способ:

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

Поскольку для внешнего вызова не определено (AFAIK), в каком порядке оцениваются два параметра, вполне возможно, что правый параметр "c" (или в вашем случае "i--") произойдет до левого Параметр руки оценивается.

0 голосов
/ 18 марта 2009

если возможно, попробуйте обновить до gcc> = 4. Я только что запустил это на 4.0.1, и он выполняется просто денди.

...