인프런 커뮤니티 질문&답변

장준모님의 프로필 이미지
장준모

작성한 질문수

홍정모의 따라하며 배우는 C언어

4.10 scanf() 함수의 사용법

scanf 함수의 서식 지정자 질문

작성

·

458

0

위 코드를 보면 int형인 ch에 scanf함수를 써서 %c인 문자형으로 입력을 시켜봤습니다

그래서 printf함수로 %c와 %d 출력을 동시에 해 봤는데

문자형으로는 출력이 정상적으로 나오지만 

정수형으로는 출력이 -1이 나옵니다(다른 값을 입력해도 -1이 나옴) 

질문 1) 아스키코드대로 문자형으로 a가 나왔으면 정수형으로는 97이 나와야 하는것 아닌가요?

질문 2) 디버깅을 해서 변수 ch에 저장된 값이 무엇인지 확인을 해보았으나 Autos 항목에서 ch의 value가 0'\0'으로 확인됩니다 (다시 입력을 했을 시엔 쓰레기값이 뜸)

출력은 정상으로 되는데 Value에 쓰레기 값이 들어있는건 무슨 경우인가요? 왜 그런거죠?

답변 3

3

질문자님과 동일한 코드에 a 를 입력한 상태입니다. 

ch 의 value 가 0'\0' 으로 확인된다고 말씀하셔서 의아한데 ch 값은 위와 같습니다.

사진은 ch 의 메모리입니다.

ch에 a 를 입력하면 다음과 같이 61 cc cc cc 이 들어가게 됩니다. 

총 4 칸을 차지 하고 있는데 한 칸 당 1byte 라고 생각하시면 됩니다. ch 는 int 이므로 4 byte 라 4 칸을 차지하고 있습니다.

이 값들은 모두 16진수입니다. 한 칸(1byte)를 두 자리의 16진수로 값을 나타낸 것이에요! 

cc cc cc cc  <- 이게 쓰레기값으로 가득 차있는 상태입니다.

a 의 아스키코드값인 97 을 16진수로 변환하면 61 입니다.

즉, a 를 입력하면 a 의 값이 4 칸을 차지하는 int ch 의 1 칸을 차지하게 되는 것입니다.

그래서 a를 ch 에 입력한 후에 61 cc cc cc 가 됩니다. int 가 차지하는 4 칸 중 한 칸에 a 값이 들어간 것이나 마찬가지에요.

ch 에는 61만 들어가는 것이 아닙니다. 4 칸을 쓰는 변수이기 떄문에 61 cc cc cc 가 ch 의 값이 됩니다.

만약 ch  가 char 였다면 char 는 1byte 이니 앞에 '61' 이 한 칸만 읽어내므로 문제 없이  a 라고 잘 받아들였을 것입니다. 그러나 ch 를 int 로 선언하셨기 때문에 '61' 만이 아닌 'cccccc61' (메모리는 오른쪽에서부터 거꾸로 읽습니다.)  이렇게 4칸이 ch 값이나 마찬가지인 것입니다. 이 4byte의 'cccccc61'은 10진수로 변환하면 3,435,973,729 입니다. 이는 int 가 표현할 수 있는 범위를 넘어섰죠. 그래서 오버플로우가 발생하고 최종적으로 이 'cccccc61' 이 사진과 같이 10진수로 변환되면 -858993567 이 되는 것입니다.

컴퓨터 환경에 따라 메모리 상태가 다 다를 것이니 제 컴퓨터에서의 ch 메모리는 저런 상태였다고만 이해해주세요! 동일한 코드로 제 컴퓨터에서 실행했을 땐 -858993567 결과가 나왔지만 아마 질문자님의 환경에선 다른 결과로 실행될 수도 있습니다.(그래도 앞에 한칸에만 아스키코드가 저장되고 읽는건 4byte 로 읽히는 원리는 같을 것입니다.)  디버그 - 창 - 메모리를 통해 한번 메모리 들여다봐보세요 ㅎㅎ

printf 로 출력할 때 정상적으로 a 가 출력됐던 이유는 "%c" 가 1byte 만 읽어서 그런 것입니다. 즉, 앞에 '61' 한칸 만 읽어서 정상적으로 a 를 출력할 수 있었던거에요! 

결론은 4 byte 크기를 하나의 데이터로 정의하는 변수에 1byte 의 char 를 저장해서 생긴 일입니다. scanf 에서 "%c"를 통해 1byte 만 읽어들여 int 인 ch 에 저장하셨기 때문입니다. int 는 4byte 이기 떄문에 a 문자를 저장한다고 해서 앞의 1byte 만 고려해주지 않습니다. 원래 있던 나머지 3 칸의 쓰레기값들과 a 의 아스키코드값 1칸이 하나의 데이터로서 합쳐져서 이런 요상한 결과가 나오는 것입니다.  

장준모님의 프로필 이미지
장준모
질문자

완벽한 답인것 같아요 ㅎㅎ 헷갈릴때마다 다시 들어와서 보겠습니다! 감사합니다

1

준모님! 안녕하세요.
인프런 운영팀 자미입니다.

질문 답변 모니터링 하다 헷갈릴 때마다 다시 보신다고 하셔서 (ㅎㅎ) 북마크 기능 슬쩍- 제안드려요!! 
여기 우측에 북마크 (1 표시된 부분이요!) 누르시면 다음 번에 북마크한 질문&답변을 모아서 한번에 확인할 수 있어요!!

관련 내용은 여기서 확인하실 수 있어요 :)
> 링크 : https://www.inflearn.com/notices/175752

앞으로도 인프런 잘 이용해주세요! 감사합니다.

1

제가 보기에는 printf문의 인자를 넣지 않아서 생긴 문제인것 같습니다.

printf("%c %d",ch,ch);

처음 ch는 %c에 할당이 되고 두번째 ch 인자가 %d에 할당이 되어서 나오게 됩니다.

와 같이 뒤의 인자가 2개가 와야지 정상적으로 동작할 것으로 보입니다.

궁금한점 있으면 질문주세요.

감사합니다.

장준모님의 프로필 이미지
장준모
질문자

아 저런 멍청한 실수를 했네요 ㅋㅋㅋ 감사합니다다혹시 질문2에 대한 답도 해주실 수 있나요??

#include <stdio.h>
int main() {
	int ch;
	scanf("%c", &ch);
	printf("%c %d\n", ch, ch);
	return 0;
}
//입력: a
//출력: 32609

제경우 코드를실행시켰더니 97대신 32609가 출력됩니다.

3줄의 int ch; 를 char ch;로 바꾸면 잘 실행됩니다.

뭐가 잘못되었을까요?

답변 참고해주시면 될 것 같아요! 💛

장준모님의 프로필 이미지
장준모

작성한 질문수

질문하기