2016-11-06 1 views
0
#include<iostream> 
#include<stdio.h.> 
using namespace std; 
int main() 
{ 
    float f=11.11; 
    printf("%d",f); 
} 

devC++에서 다음 코드를 실행하면 출력 -536870912가됩니다. 온라인 튜토리얼에서 동일한 코드를 실행할 때 컴파일러는 모든 실행마다 다릅니다. 뒤에있는 이유는 무엇일까요? 당신이하지 그것이 정의되지 않은 동작의 할 경우float 값을 출력하기 위해 % d insde printf를 사용하면 예기치 않은 결과가 발생합니다.

+0

참고 : C 컴파일러가 아닌 C++ 컴파일러를 사용하여 컴파일하고 있습니다. –

답변

2

그것은 부동의,

printf("%f" , f); 

를 사용합니다. 값 -1로 int를 부호없는 int로 변환하려고하면 이해할 수 있습니다.

큰 가치가 있습니다.

+0

'f'는 적어도 C99 이후로'double'이'float'이 아닌 것을 기대합니다. – alk

+0

@alk 'double'보다 작은 값과 변수는 varargs 인수에서'double'으로 승격되므로 별 문제가되지 않습니다. –

2

인수가 형식 지정자와 일치하지 않으면 undefined behaviour입니다. float를 인쇄하려면 %f을 입력하십시오.

printf("%f",f); 

좋은 컴파일러로 쉽게 이러한 종류의 오류를 포착 할 수 있어야합니다. GCC는 다음을 생성합니다.

warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=] 

추신 : 귀하의 stdio.h 헤더에 빠진 점이 있습니다.

+0

'f'는 적어도 C99 이후로'float'이 아니라'double'을 기대합니다. – alk

+0

참으로 printf는 자동으로 두 배로 승격합니다 – Glick

1

묻고있는 것인지 확실하지 않습니다. 11을 인쇄하지 않은 이유는 무엇입니까? 또는 왜 다른 컴파일러에서 다른 대답을 인쇄 했습니까?.

다른 인쇄본이 설명한 것처럼 %d은 부동 소수점을 인쇄하지 않으며 printf 호출에서는 전달 된 유형과 예상되는 유형 간의 불일치를 수정하는 자동 변환이 없습니다.

다른 컴파일러에서 다른 것을 인쇄 한 이유는 의 정의되지 않은 동작입니다. 이는 아무 일도 발생할 수 없음을 의미합니다. 휠에 올라갈 때까지 전방 휠에있는 모든 너트를 느슨하게 할 때까지 들어가서 고속으로 도로를 내리십시오. 이 떨어지면 제어력이 떨어지고 충돌 할 수 있습니다. 도랑. 우연히 새 차를 가져 와서 내일 똑같은 일을한다고 가정 해 봅시다. 우연히 나무에 충돌하는 경우는 예외입니다. 이 시점에서 취할 수있는 두 가지 방법이 있습니다.

  1. 어떤 미묘한 요인으로 인해 하루에 도랑에 충돌하고 다른 날에는 나무가 깨지게 만드십시오. 왜 더 반복적이지 않았습니까?
  2. 다시 이와 같은 어리석은 실험을 시도하지 않기로 결심하십시오.

    printf("%d",f); 
    

    다음 포맷에 의해 주어진 변환 지시자 (들)에 의해 지정된 printf 다른 매개 변수 (들)에 전달 : 변환 지정자 여기에서 변수의 타입간에 불일치가

+0

UB의 좋은 예입니다. SO의 워드 프로세서에 들어갈 수있다 .. – alk

+0

그러면 왜 printf ("% c", 65) – harishbisht29

+0

@ harishbisht29에서 작동 하는가?'% c'는'int'를 받아들이 기 때문에 * 정의되어있다. 또한'printf'를 호출 할 때 인자에 자동 변환이 발생하기 때문에'char'와'short'는'int'로 승격되고'float'는'double'으로 승격됩니다. 이것들은 보통의 인수 프로모션 (*)이나 그와 비슷한 것으로,'printf'와 같이 다양한 수의 인수를 받아들이는 함수에 적용됩니다. 따라서 고정 프로토 타입이 없습니다. –

0

string은 정의되지 않은 동작을 발생시킵니다. 그 순간부터 모든 일이 일어날 수 있습니다.

수정하려면 올바른 변환 지정자를 사용하십시오.

부동 소수점 변수의 경우 변환 지정자 f을 사용합니다 (double이 필요함). 그러나 floatprintf과 같은 가변 함수에 전달되면 floatdouble으로 승격됩니다.