문제

Cout은 며칠 전에 버퍼를 가지고 있다는 것을 알고 있습니다. Google에서 버퍼는 스택과 같다고 말합니다. ) 상단에서 bottem까지. 이와 같이,

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

스택 방식이 옳은 것 같습니다 ~, 나는 어제 C ++ 프라이머 플러스를 읽었으며, 왼쪽에서 오른쪽으로 Cout가 작동한다고 말합니다. 삽입을 사용하여 ". 그러나 왼쪽에서 오른쪽으로는 Cout을 설명 할 수 없습니다.

그 다음에 알 니 타크 "<< 연산자는 실제로 Ostream & Operator << (Ostream & os, int)이므로 다음과 같은 또 다른 방법은 다음과 같습니다. 연산자 << (연산자 << (연산자 << (cout, a), b), 씨 )",

가장 정당한 주장이 처음 평가되면 설명 할 수 있습니다.

이제 나는 Cout의 버퍼가 어떻게 작동하는지 혼란스러워합니다. 누군가 나를 도울 수 있습니까?

도움이 되었습니까?

해결책

당신은 많은 것을 섞고 있습니다. 지금까지 :

  • 구현 세부 사항 cout
  • 체인 된 전화
  • 전화 컨벤션

별도로 읽으십시오. 그리고 그들 모두에 대해 한 번에 생각하지 마십시오.

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

위의 줄은 정의되지 않은 동작을 호출합니다. FAQ를 읽으십시오 3.2. 참고, 당신이 관찰하는 것은 함수의 호출 규칙의 부작용과 특정 구현 (예 : 당신의 것)에 의해 스택에 매개 변수가 전달되는 방식입니다. 다른 기계에서 작업하는 경우 동일하지는 않습니다.

나는 당신이 버퍼링과 기능 호출 순서를 혼동하고 있다고 생각합니다. 당신이있을 때 cout 문과 여러 삽입이 이어집니다 << 실제로 여러 기능 호출을 호출하고 있습니다. 따라서 글을 쓰면 :

cout << 42 << 0;

정말 의미가 있습니다 : 당신은 전화,

cout = operator<<(cout, 42)

그런 다음 같은 연산자에게 다른 호출로 반품을 사용하십시오.

cout = operator<<(cout, 0)

위의 테스트 한 내용은 아무 말도하지 않습니다. cout의 내부 표현. 더 많은 것을 알기 위해 헤더 파일을 살펴 보는 것이 좋습니다.

다른 팁

일반적인 팁처럼, I 또는 I의 다른 사용과 같은 줄에서 I ++를 사용하지 마십시오.

문제는 기능 인수를 순서대로 평가할 수 있다는 것입니다. 따라서 기능 인수에 부작용이있는 경우 (예 : 증분 및 감소 작업)가 예상 한 순서대로 작동 할 것을 보장 할 수는 없습니다. 이것은 피해야 할 것입니다.

이 경우에도 마찬가지입니다.이 경우 Cout 사용의 실제 확장과 유사합니다.

function1 (function2 (foo), bar);

컴파일러는 function2를 호출하기 전에 BAR을 자유롭게 배치하거나 그 반대도 마찬가지입니다. 예를 들어 function2가 function1이 호출되기 전에 반환되도록 보장 할 수 있지만, 그들의 인수는 특정 순서로 평가되지는 않습니다.

이것은 당신이 다음과 같은 일을 할 때 문제가됩니다.

function1 (function2 (i ++), i);

"i ++"전후에 "i"를 평가하는지 여부를 지정할 방법이 없으므로 기대와는 다른 결과를 얻거나 다른 컴파일러 또는 동일한 컴파일러의 다른 버전에 대한 결과를 얻을 수 있습니다. .

결론, 부작용에 대한 진술을 피하십시오. 줄에서 유일한 진술이거나 동일한 변수 만 한 번만 수정하는 경우에만 사용하십시오. ( "선"은 단일 진술과 세미콜론을 의미합니다.)

당신이 보는 것은 정의되지 않은 행동입니다.

현지의 i 그리고 글로벌 c 시퀀스 포인트없이 여러 번 첨가/빼기. 이것은 당신이 얻는 가치가 무엇이든 될 수 있음을 의미합니다. 컴파일러, 아마도 프로세서 아키텍처 및 코어 수에 따라 다릅니다.

그만큼 cout 버퍼는 대기열로 생각할 수 있으므로 Alnitak이 옳습니다.

당신이 정의되지 않은 행동을보고 있음을 정확하게 지적하는 다른 답변 외에도 나는 그것을 언급 할 것이라고 생각했다. std::cout 유형의 객체를 사용합니다 std::streambuf 내부 버퍼링을 수행합니다. 기본적으로 버퍼를 나타내는 추상 클래스입니다 (크기는 구현에 따라 다르며 Unbufferd 스트림 버퍼의 경우 0이 될 수 있음). 하나를위한 것 std::cout 그것이 "오버플로"될 때 stdout으로 플러시되도록 작성됩니다.

실제로, 당신은 그것을 바꿀 수 있습니다 std::streambuf 와 관련된 std::cout (또는 그 문제에 대한 스트림). 이것은 당신이 모든 것을 만드는 것처럼 영리한 일을하고 싶다면 종종 유용합니다. std::cout 통화는 로그 파일이나 무언가로 끝납니다.

그리고 AS 더러워지게 말했다 당신은 전화를 다른 세부 사항과 혼동하는 것을 혼란스럽게하고 있으며, 그들은 전적으로 std :: cout의 버퍼링과 관련이 없습니다.

또한, 출력 패러다임 (printf and cout)을 혼합하는 것은 구현에 따라 다릅니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top