본문 바로가기
프로그래밍/C언어

[C언어] #1. 자료형 타입과 scanf 함수에 대하여

by Crush on Study 2022. 1. 18.
반응형

printf("Welcome, Let's C Language.");  // 초등학생도 쉽게 이해시켜주는 C언어 글을 포스팅합니다.

 

안녕하세요. 비전공자 출신 SW Test 엔지니어 Crush on Study입니다. 

이번 글에서는 자료형 타입에 대한 소개와 scanf함수에 대해 설명하고자 합니다.

 

Q. 먼저 이전 시간에 배운 내용을 잠깐 복습해봅시다.

A. 1) 전처리구문과 헤더파일에 대해 배웠습니다.

- 전처리구문은 main함수 및 그 외의 함수들을 실행하기전에 먼저 컴퓨터가 인식하고 가야할 것들을 가리킵니다.

- 헤더파일은 함수를 선언하기 위한 기본적인 라이브러리들을 의미하며, 이는 사용자의 입맛에 따라 커스텀을 할 수도 있습니다. 이 때, 커스텀한 헤더파일은 " "로 표기하며, 기본 헤더파일은 < >로 표기합니다.

 

2) int main()와 printf , return에 대해 배웠습니다.

- int는 함수의 자료형 타입 / main은 함수의 이름 / ()는 매개변수 (여기선 비어있으므로 =void)의 자리임을 알게 되었습니다. 그리고 printf란 뒤에 나온 문장들을 화면에 출력시켜달라는 명령어임을 배웠습니다.

return은 함수의 자료형 타입이 void가 아닌 다른 자료형 타입이 선언되었을 경우 적어주는 함수의 '마침표' 같은 기능을 함을 배웠습니다.

 

 

딱 보고 기억 나는게 없다. 하면 바로 이 전글을 참고하세요. (설마 까먹으셨을까?)

https://crush-on-study.tistory.com/206

 

[C언어] #0. C언어를 왜 배워야 하는가? / "Hello World"

printf("Welcome, Let's C Language."); // 초등학생도 쉽게 이해시켜주는 C언어 글을 포스팅합니다. 안녕하세요. 비전공자 출신 SW Test 엔지니어 Crush on Study입니다. 오늘부터 티스토리에서도 C언어를 포스팅

crush-on-study.tistory.com

#1. 두번째 강의 소스코드

반응형
#include <stdio.h>

int main()
{   
    int tall;

	printf("How much your tall? : ");
    scanf_s("%d",&tall);

    printf("Your tall is %d",tall);

	return 0;
}

우리가 가장 먼저 볼 소스코드는 int tall;입니다.

int tall;
1. int tall; : ?? 이게 뭘 의미하나요? 이거는 tall이라는 함수를 int라는 자료형 타입으로 선언을 하겠다. 라는 의미입니다. tall의 값은 지정되어있진 않지만  일단 우리는 이 소스코드를 통해 tall을 탄생시켰습니다.

나는 값을 넣어주고 싶다. 하시면 int tall = 0; 이런 식으로 넣어도 됩니다. 0이 아니라 무슨 숫자를 넣든 상관없어요.

근데 여기서 주의해야할 점. 바로 int가 가지는 의미와 범위입니다.

앞에서 #0번 C언어 글에서 적었지만 int는 정수를 의미하는 integer의 약자입니다. 즉, 소수는 허용되지 않습니다. -200, 0, 26 같은 음의 숫자, 0 , 양의 숫자만 인정됩니다.  그리고 이 정수가 가지는 범위는 한정되어 있습니다.

자료형 변수의 메모리 크기 & 범위

위의 표를 봅시다. int가 가지는 범위는 -2147483648 ~ +2147483647 이라 나왔습니다. 만약 여러분들이 int tall에다가 집어넣은 값이 2147483647로 끝부분의 범위에서 +1만 더해주면요.

쓰레기 값

이런 결과값이 출력이 됩니다. 음? 2147483648를 입력했는데 왜 다른 값이?? 그야 int가 가지는 범위를 초과한 값을 입력했기 때문에 이상한 결과가 나온 겁니다. 우리는 이걸 '쓰레기 값'이라고 부릅니다. 

그럼 이걸 수정하려면 더 큰 범위를 가지는 자료형 변수로 수정해서 선언해야겠죠? float도 있고 long long도 있네요.

근데 이 둘을 보면 둘 다 범위는 int보다 큰데 메모리 크기에서 차이가 보입니다. float는 4byte고 long long은 8byte네요. 그러면 인간적으로 메모리를 덜 잡아먹는 자료형 변수를 사용하는게 효율적인 프로그램이 될 것입니다.

 

따라서 우리는 float를 사용해서 다시 소스코드를 고쳐보고 동일한 값을 넣어보도록 하겠습니다.

#include <stdio.h>

int main()
{   
    float tall;

	printf("How much your tall? : ");
    scanf_s("%f",&tall);

    printf("Your tall is %d",tall);

	return 0;
}

오 이제 원하는 값대로 나오네요. 그쵸? float가 실수형 타입이다보니 뒤에 소수점까지 나오긴했지만 그래도 입력한 값이랑 똑같이 나왔습니다.

 

* char같은 문자형 타입을 제외하곤 정수&실수에서는 'unsigned (자료형 타입)' 이라는 선언을 심심찮게 볼 수 있습니다. 이 의미는 음의 숫자를 제외하고 그 만큼을 양의 숫자의 바운더리에 추가해라! 라는 뜻입니다.

쉽게 말하자면 -10~10이라는 범위를 가진다는 aaa 라는 자료형 타입이 있다 하겠습니다. 이 때, unsigned aaa 라고 선언하면 범위는 0~20이 됩니다. 

 

 

추가로 볼 개념은 scanf입니다.

scanf
1. 버퍼 오버플로우 : 소스코드를 보시다 문득 의문이 드신게 있을 겁니다. 이번 글의 제목. 그리고 이 테이블에서의 제목은
scanf인데 왜? 소스코드에선 scanf_s를?? 적었을까요? 

일부 IDE (통합개발환경 툴)에서는 scanf를 적을 시, 컴파일 에러가 나는 경우가 있습니다. scanf 함수는 형식지정자에 맞춰서 값을 입력받고 이를 할당된 메모리 주소에 값을 넣습니다. 이 입력 인자로 받은 주소에 값을 저장하는 과정에서 할당된 메모리의 크기를 벗어날 위험이 있습니다. 이걸 바로 "버퍼 오버플로우"라 합니다. 현재는 scanf대신 scanf_s를 표준으로 삼곤 하는데 가끔은 scanf해도 에러가 안나는 버전이 있기도 합니다.
2. 형식지정자? : 위에서 빨갛게 칠한 단어. 형식지정자란 뭘까요? 소스코드를 보시면 int형 타입의 함수값을 입력받을 때는
scanf_s(%d")를  float형 타입의 함수값을 입력받을 때는 scanf_s(%f")를 선언해줬습니다.
즉, 형식지정자란 값을 입력받거나 출력할 때, 자료형 타입에 대응되는 '약속'들을 의미합니다. 이 부분이 C언어에서 몇 안되는 외울거리들 중 하나입니다. 여러번 복습하고 직접 코드를 짜보면서  표를 보지않고도 쓸 수 있도록 합시다.
3. 메모리 주소 : scanf_s에서 형식지정자를 정하고 뒤에 '&' 라는 기호를 적었습니다.  &라는 기호를 앰퍼샌드라고 부르는데요. C언어에서 &는 함수에 대한 메모리 주소를 호출하는데 사용합니다. 만약 scanf_s를 쓸 때, &를 적지 않으면 컴파일 에러는 뜨지 않으나 실행이 안되는 현상을 마주하게 됩니다. 까먹지 말고 꼭 표기합시다. 저도 가끔씩 까먹어요 ㅋㅋㅋ 

 

#define _CRT_SECURE_NO_WARNINGS

- 아, 나는 scanf_s 쓰기 싫다. 뭐하러 두 문자 더 추가해줘야하냐? scanf할랭!! 하시는 분들을 위한 전처리구문입니다.

위 전처리구문을 소스코드 제일 위에다 선언해주시면 scanf함수에 대한 에러를 무시하고 사용할 수 있게 해줍니다.

근데 코딩테스트 같은거 볼 때 그냥 scanf_s가 표준이니까 귀찮더라도 이거 씁시다 ㅎㅎ

 

 

복습

Q1. scanf_s 함수를 통해서 본인의 키랑 몸무게를 출력해보세요. 이 때, 키는 정수형 자료로  몸무게는 실수형 자료로 선언하세요.

Q2. 오늘 배웠던 자료형 타입의 표에서 가장 작은 메모리 크기를 가지는 자료형 타입은 무엇인가요?

반응형