2009-03-18 13 views
1

나는 cout과 printf가 현재 버퍼를 가지고 있고, 버퍼가 스택과 같다고 생각하고, 오른쪽에서 왼쪽으로 cout과 printf의 결과를 얻는다. (콘솔 또는 파일에) 상단에서 bottem으로. 이처럼버퍼와 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에서

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

++ ((GCC) 3.4.2 (와 Mingw-특별하다)), 출력은

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++ 작업의 실행 순서는 동일한 함수 호출에 대한 매개 변수로 두 번 이상 호출 될 때 정의되지 않습니다.

는 "순서 포인트"의 Iraimbilanja의 언급을 정교 (그리고 아마도 올바른)하려면 cout 버전에 해당합니다 : 효과적으로

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

, 실제로 순서대로 평가되는 세 개의 함수 호출, 그 각 매개 변수의 비록 단일 문장처럼 쓰여졌지만.

<< 연산자는 정말 ostream& operator<<(ostream& os, int), 그래서이 글을 쓰는 또 다른 방법은 다음과 같습니다

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

외부에 있기 때문에하는 것은 (AFAIK) 두 개의 매개 변수를 평가 주문하는 정의가 완벽하게 가능 그렇지 않은 전화 왼손 매개 변수가 평가되기 전에 오른쪽 "c"매개 변수 (또는 귀하의 경우 "i--")가 발생합니다.

+0

안녕하세요, Alnitak, 내가 생각하는 큐 아웃 버퍼가 오른쪽에서 왼쪽으로 출력을 얻은 다음 오른쪽에서 왼쪽으로 넣을 것입니다. 하지만 당신의 코드에서, cout 버퍼가 왼쪽에서 오른쪽으로 결과를 얻는다 고 생각합니다. 사실입니까? 감사합니다 ~ – 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++의 공통적 인 함정입니다. 인수 평가 순서가 지정되지 않았습니다.

대소 문자를 구분하지 않는 경우 : 단일 함수에 대한 인수가 아닌 연결 호출 (시퀀스 포인트)을 사용하므로 평가 순서는 왼쪽에서 오른쪽으로 정의됩니다.

편집 : 데이빗 쏜리는 위의 코드의 행동이 사실 undefined에 있음을 지적한다.

+0

그것은 지정되지 않은 것보다 더 나쁩니다. 그것은 정의되지 않았습니다. 결과가 평가 순서와 일치한다는 보장은 없지만 일반적으로 명백한 구현을 고려할 때 발생합니다. 그러나, 그 경우의 설명에 +1. –

0

가능한 경우 gcc> = 4로 업데이트 해주세요. 4.0.1에서이 파일을 실행하고 그냥 멋쟁이를 실행합니다.

+0

gcc 3.x는 매우 오래되었고 일반적으로 업데이트하는 것이 좋은 아이디어 일 수 있지만이 경우 결과는 "올바른"것이 아닙니다. 그것은 지정되지 않았으며, 지정되지 않은 동작에 의존하는 것은 컴파일러 버전마다 다를 수 있습니다. – janneb

+2

이것은 정의되지 않은 동작이므로 (a) 모든 동작은 표준에 따라 정당하며 ​​(b) 다른 버전, 다른 컴파일러 옵션 또는 다른 컴파일러 옵션에서 기대하는 동작을 제공하는지 여부를 알지 못합니다. 다른 주변 코드. –