Странные выходы перепутали std :: cout - PullRequest
1 голос
/ 20 апреля 2011

C ++ std :: cout кажется интересной вещью.Сегодня я попробовал следующую программу на моем компиляторе C ++:

cout<<"!"<<"@"<<endl;
cout<<"!"<<cout<<"@"<<endl;
cout<<"!"<<(cout<<"@")<<endl;

И результаты довольно любопытны:

!@
!0x601068@
@!0x601068

Первая строка - пешеходная;второе понятно;Тем не менее, третья строка за пределами моего понимания.Может ли кто-нибудь объяснить результат?Спасибо всем заранее, ребята!

Ziyao Wei

Ответы [ 5 ]

5 голосов
/ 20 апреля 2011

Эта строка:

cout<<"!"<<(cout<<"@")<<endl;

Сначала выполняется:

(cout << "@")

Примечание. Сначала он мог выполнить что-то еще, но компилятор оптимизировал это подвыражение и нашел егоможет переместить это в начало оператора без нарушения каких-либо ограничений.

Результатом этого выражения является поток (cout).Таким образом, результирующее выражение:

cout<<"!"<< cout <<endl;

Это приводит к:

@!<pointer>
2 голосов
/ 20 апреля 2011

Скобки влияют на порядок вычисления здесь, как и в любом другом выражении (<< является оператором).Поскольку выражение имеет <a href="http://en.wikipedia.org/wiki/Side_effect_%28computer_science%29" rel="nofollow"> побочные эффекты , эти побочные эффекты возникают в том же порядке, что и выражение выражения.

1 голос
/ 20 апреля 2011

Эта третья строка иллюстрирует синтаксический сахар, который является оператором вставки.

По существу, выражение (cout<<"@") вычисляется первым, в результате получается @, который возвращает сам поток cout.

Только тогда ! сначала, а затем выражение отправляется на cout.

Это эквивалентно:

operator<<( operator<<( operator<<(cout,"!"), ( operator<<(cout,"@") ) ), endl);
                                                ^------------------^

Выделенный раздел является выражениемкоторый должен быть оценен до вызова каких-либо функций.

0 голосов
/ 20 апреля 2011

Если вы понимаете вторую строку, почему третья смущает вас?

Прежде всего, вычисляется выражение в скобках (но порядок вычисления не указан), поэтому записывается @на стандартном выходе;такое выражение возвращает ссылку на cout, как это всегда происходит с операторами вставки, поскольку в противном случае они не могли бы быть соединены в цепочку.

Теперь, когда эта часть выражения вычислена, все происходит как обычно: что включенострока пишется слева направо: сначала !, затем значение, возвращаемое из выражения в скобках (т. е. ссылка на cout, а затем endl.

0 голосов
/ 20 апреля 2011

Мое предположение - в скобках в 3-й строке сначала выполняется cout<<"@", что ставит @ в начале строки.Затем выполняется cout.operator<<("!"), который ставит ! на место.И затем ostream, возвращаемый cout.operator<<("!"), запускает свой operator<<(), которому присваивается ostream, возвращаемое cout<<"@", таким образом выводя 0x601068.

...