2014-09-19 3 views
-5

가 질문에 모든 규칙 다음 아래의 코드를 가지고 :출력은 무엇이며 그 이유는 무엇입니까? 내가 범위를 통과했다

#include <stdio.h> 
int main() 
{ 
    int x = 1, y = 2, z = 3; 
    printf(" x = %d, y = %d, z = %d \n", x, y, z); 
    { 
     int x = 10; 
     float y = 20; 
     printf(" x = %d, y = %f, z = %d \n", x, y, z); 
     { 
      int z = 100; 
      printf(" x = %d, y = %f, z = %d \n", x, y, z); 
     } 
    } 
    return 0; 
} 

나는 마지막 인쇄 변경하는 경우 : 나는 다음과 같은 출력을 얻을

printf("x = %d, y = %d, z = %d \n", x, y, z); 

을하는 I 이해가 안 : (Ideone link)

x = 10, y = 0, z = 1077149696 

을 그래서, 당신은 왜 Z 인쇄가 그 값 설명 할 수 있을까?

+1

printf'는'사용 vargs' 및 기대 '때문에 내 가정은'%의 d' : 현대 컴파일러에, GCC 또는 그 소리처럼, 그것은 당신의 형식 사양이 잘못 불평 것

주 'float y '의 경우 float의 첫 번째 4 바이트를 0으로 읽고 후반의 4 바이트를 다음'% d '인 z로 읽음으로써 z는 정의되지 않은 값을 출력합니다. – texasbruce

+2

이 코드는 ideone의 예제와 동일하지 않습니다. – Galik

+0

-1이 코드는 완전히 작동하며 결과를 가져온 ideone의 코드와 다릅니다. ideone 코드에는 버그가 있습니다. – Galik

답변

9

x, y 및 z는 대부분의 지역 정의로 해석됩니다.

잘못된 printf % 지정자를 사용하면 동작이 정의되지 않습니다.

y는 float이지만 % d를 사용하여 인쇄하고 있습니다 (이후 줄에서).

printf은 varargs를 사용하고 잘못된 지정자 (이 경우 % d 대신에 % d)를 사용하여 스택을 손상 시키면 스택이 손상되고 스택 데이터의 잘못된 해석 (잘못된 오프셋에서)으로 인해 많은 고통이 초래됩니다. 이 UB

이 컴퓨터 (한 가지 가능한 설명)에 발생 될 수있는 무엇인가를 디코딩

. default argument promotion 때문에 비트 패턴 (16 진수) 0x4034000000000000이 20.0f에 대해 스택으로 푸시됩니다. 귀하의 리틀 엔디 언 머신에서의 sizeof int는 4 바이트입니다. float를 int로 인쇄 할 때 0x00000000이 소비되고 int로 해석되어 0을 나중에 인쇄하면 %d은 0x40340000을 int로 해석하고 1077149696을 인쇄합니다. 최종 100 (0x00000064)은 사용되지 않은 상태로 남고 printf는 반환합니다.

그러나 이것에 의존하지 말고 행동이 잘 정의 된 코드를 작성하십시오.

+1

친애하는 Downvoters, 제가 뭔가 잘못 작성 했습니까? –

+1

필자가 생각하기에, 적어도 질문에 대한 코드를 보면'printf' 형식의 문자열은 괜찮아 보입니다. 실제로 링크의 코드를 언급하고 있습니까? 여기에 ideone에 대한 질문의 코드가 있습니다. http://ideone.com/k6TCB7 – juanchopanza

+1

'가장 안쪽에있는 인쇄물이 무엇인지 생각했습니다.'라는 줄 바로 뒤의 코드는 질문에서. –

0

z = 1077149696
% d를 사용하여 부동 소수점 값을 인쇄하는 것은 정의되지 않은 동작입니다.
사용 "% f를"당신이 사용하고 대신

  1. 모든 변수는 저장 유형이 "자동"또는 "자동".
  2. 자동 변수의 범위는 변수가 선언 된 블록 안에 있습니다.
  3. 중첩 된 블록이있는 경우 가장 바깥 쪽 블록에 선언 된 변수는 다른 모든 블록에서 볼 수 있습니다.
  4. 블록에 외부 블록에서 선언 된 변수와 일치하는 변수가 선언 된 경우 외부 변수 "블록에서"즉 (로컬로) 덮어 씁니다.

총계 : 자동 변수는 변수가 선언 된 블록에 대해 로컬입니다.

2

@ mohit-jain이 정확합니다.

잘못된 형식 지정자를 사용하면 스택에 대한 잘못된 매개 변수 해석이 발생하여 정의되지 않은 컴파일러 관련 동작이 발생합니다.

$ clang test.c 
test.c:12:54: warning: format specifies type 'int' but the argument has type 'float' 
     [-Wformat] 
      printf(" x = %d, y = %d, z = %d \n", x, y, z); 
            ~~    ^
            %f 
1 warning generated. 
관련 문제