Pergunta

Eu sei que o cout e o printf têm buffer hoje, e diz -se que o buffer é um pouco como uma pilha e obtenha a saída de cout e printf da direita para a esquerda e depois colocá -los para fora (no console ou arquivo) de cima para Bottem. Assim,

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)

Então eu escrevo um código abaixo,

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

Sob o VS2005, a saída é

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

Em G ++ ((GCC) 3.4.2 (Mingw-Especial)), a saída é,

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

Parece que o buffer é como uma pilha. No entanto, eu li C ++ Primer Plus Hoje, e diz -se que o trabalho cout da esquerda para a direita, sempre que devolva um objeto (cout), então "esse é o recurso que permite concatenar a saída usando a inserção". Mas da maneira da esquerda para a direita não pode explicar o cout <saída 9 8 7 Agora estou confuso sobre como o buffer de Cout trabalha, alguém pode me ajudar?

Foi útil?

Solução

Este não é um bug, nem é nada a ver com o buffer de saída.

A ordem de execução do i-- e i++ As operações não são definidas quando são chamadas mais de uma vez como parâmetros para a mesma chamada de função.

Para elaborar (e possivelmente correto) a menção de Iraimbilanja a "pontos de sequência", o cout A versão é equivalente a:

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

Efetivamente, na verdade são três chamadas de função separadas, cada um dos cujos parâmetros são avaliados em ordem, mesmo sendo escritos como uma única declaração.

o << O operador é realmente ostream& operator<<(ostream& os, int), então outra maneira de escrever isso é:

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

Como para a chamada externa, não é (Afaik) definiu qual ordem os dois parâmetros são avaliados, é perfeitamente possível para o parâmetro "C" à direita (ou no seu caso "i--") Para acontecer antes que o parâmetro da mão esquerda seja avaliado.

Outras dicas

A saída de:

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

não é especificado. Esta é uma armadilha comum de C ++: a ordem de avaliação de argumentos não é especificada.

Não é assim com o caso Cout: ele usa chamadas encadeadas (pontos de sequência), não argumentos para uma única função, portanto, a ordem de avaliação é bem definida da esquerda para a direita.

Editar: David Thornley ressalta que o comportamento do código acima é de fato Indefinido.

Se possível, tente atualizar para GCC> = 4. Acabei de executar isso no 4.0.1 e ele executa apenas dândy.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top