буфер и последовательность вывода 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 функция, которая позволяет объединять вывод с помощью вставки " ;. Но путь слева направо не может объяснить cout & Lt; выход 9 8 7 Теперь я не понимаю, как работает буфер cout, кто-нибудь может мне помочь? Р>
Решение
Это не ошибка и не имеет ничего общего с буферизацией вывода.
Порядок выполнения операций i--
и i++
не определяется, если они вызывались более одного раза в качестве параметров для одного и того же вызова функции.
Чтобы уточнить (и, возможно, исправить) упоминание Ираимбиланджей " точек последовательности " ;, версия cout
эквивалентна:
(((cout << a) << b) << c)
По сути, это фактически три отдельных вызова функций, каждый из параметров которых оценивается по порядку, даже если он написан как один оператор.
Оператор <<
действительно ostream& operator<<(ostream& os, int)
, поэтому можно написать еще один способ:
operator<< ( operator<< ( operator<< ( cout, a ), b ), c )
Поскольку для внешнего вызова не определено (AFAIK), в каком порядке оцениваются два параметра, это вполне возможно для правого " c " Параметр (или в вашем случае " <=> ") должен иметь место до оценки параметра левой руки.
Другие советы
Вывод:
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
не указано. Это распространенная ошибка в C ++: порядок вычисления аргументов не указан.
В случае cout это не так: в нем используются цепочечные вызовы (точки последовательности), а не аргументы для одной функции, поэтому порядок вычисления четко определен слева направо.
Редактировать . Дэвид Торнли отмечает, что поведение приведенного выше кода на самом деле является undefined .
если возможно, попробуйте обновить до gcc > = 4. Я только что запустил это на 4.0.1, и он выполняется просто денди.