c언어 실수와 정수에 관련해서 런타임 오류 도와주세요...ㅠ
글쓴이: kimsunboy / 작성시간: 화, 2020/04/28 - 9:28오후
#include <stdio.h> int main() { double a; int b; a=4.123; printf("a의 실수값:%lf\n",a); printf("a의 정수값:%d\n",(int)a); b=4; printf("b의 실수값:%lf\n",b); printf("b의 정수값:%d\n",b); printf("실수값으로 출력해보기:%lf\n",(5/9)*(a+b)); printf("정수값으로 출력해보기:%lf\n",(a+b)); return 0; } <code/> 에 대해 정수과 실수에 관련해 공부를 해 보려고 이것저것 하다 컴파일을 했는데... a의 실수값:4.123000 a의 정수값:4 b의 실수값:4.123000 b의 정수값:4 실수값으로 출력해보기:0.000000 정수값으로 출력해보기:8.123000 이렇게 출력이 됩니다. 변수b에 4라는 값을 넣었는데 실수값으로 출력하는 과정에서 제가 생각하기에 4.0이 나와야 할 것이 왜 4.123이 나온건지에 대해 도와주세요ㅠㅠ
Forums:
아래 블로그에 설명이 잘 되어 있습니다.https:/
아래 블로그에 설명이 잘 되어 있습니다.
https://dokkiblog.tistory.com/80
https://moolgogiheart.tistory.com/58
앗 감사합니다
앗 감사합니다
이 문제는 variadic function의 parameter 문제 같습니다.
b를 (double) b로 타입 캐스팅 해서 printf를 부르면 4.0000 어쩌고가 출력됩니다. 그렇지 않으면 4.123이 출력되요.
제 생각엔 printf가 variadic function이기 때문에 생기는 일 같습니다. 이걸 질문자 분이 이해하시기 쉽지 않을 것 같은데.. 익명 사용자님은 이미 이해하셨겠고요.
C에는 variadic function이라는 게 있습니다. 임의의 타입의 객체를 임의의 갯수대로 넘겨주는데, 넘겨 받은 쪽에서 뭐가 넘어오는지 알아야 합니다. printf는 varidic function의 일례입니다.
printf는 뭐가 넘어오는지 알기 위해서 format string을 이용합니다. 이 경우에는 %lf가 있으니 double이 넘어 오겠거니 생각하죠. 그런데 실제 넘긴 건 int인 b 입니다.
"%lf"는 언어 차원의 뭔가가 아니라 그냥 printf 하고 약속한 거라서 컴파일러는 printf가 double을 기대하고 있음을 알지 못합니다. 그냥, 아무 거나 몇 개고 넘겨도 되는데 지금 int가 넘어간다고만 생각하죠.
int는 대충 4바이트를 차지합니다. double은 8 바이트를 차지하죠. 그리고 int가 4바이트에 0과 1을 놓는 방식은 double과 상이합니다.
따라서 컴파일러는 caller가 int 타입의 상수 4를 의도하는 4 바이트를 셋팅해서 printf에 넘겨주도록 코드를 생성한 거고, printf는 %lf를 보고 b가 넘어온 자리의 크기가 4가 아니라 8 바이트라고 생각하면서, 거기에서 8 바이트를 가져다가 double처럼 해석을 하게 됩니다.
그래서 차이가 생기는 거 같습니다.
첨언하자면 int를 기대할 때 int를 정확하게 처리하도록 되어 있겠지만, double 대신 int가 넘어올 때 어떻게 처리할지는 정의가 안 되어 있을 수도 있습니다. 그래서 나이브하게 printf를 구현한다면 int의 4 바이트 + 다음 쓰레기값 4바이트를 묶어 double로 해석한 결과를 출력할 텐데 반드시 그렇다고 볼 수는 없겠고요.
그리고 좀더 자세히 말하자면, caller쪽 코드는 variadic argument를 stack에 쌓고 시작 주소만 넘겨주거나 할 겁니다. callee 쪽에서는 그 시작 주소를 받아서, 적절하게 하나 하나 떼어 내어 받아가야 합니다. 흔히 하는 방법은 첫 인자로 string 같은 거 넘겨주고, 거기에 뭐뭐가 들어 있는지 정보를 적으면, callee는 첫 인자는 string으로 해석해서 먼저 넘어오는 인자들의 타입과 순서를 확인한 뒤, 거기에 맞춰 하나씩 떼어 쓰는 거겠죠.
댓글 달기