[C언어 강좌] #7-1 자료형(Data Type)


안녕하세요 파일입니다. 이전 강의에서 정수형은 int형, 실수형은 float형이라고 다룬 적이 있었죠?

자료형에 관한 표도 봤었구요. 그런데 자료형이 뭘까요?

 

앞에서 변수를 배웠습니다 그렇죠? 변수는 선언할 때 int a 처럼 앞에 데이터를 저장할 형식을 지정해줍니다.

이것이 자료형입니다.  자료형이란 변수의 저장하는 데이터의 형식입니다.

 

정수를 저장하고 싶다면 int, long, char 등을 사용하구요

실수를 저장하고 싶다면 float, double, long double 등을 사용합니다.

 

각 자료형에는 할당되는 메모리의 크기가 있습니다. 이것은 sizeof 함수를 이용해 구할 수 있습니다.

#include <stdio.h>
int main(void){
	//정수형 
	char n1 = 5;
	short n2 = 10;
	int n3 = 30;
	long n4 = 40;
	
	//실수형
	float n5 = 1.3;
	double n6 = 1.4;
	long double	n7 = 1.5;
	
	printf("------정수형------ \n");
	printf("%d, %d \n", sizeof(n1), sizeof(char));
	printf("%d, %d \n", sizeof(n2), sizeof(short));
	printf("%d, %d \n", sizeof(n3), sizeof(int));
	printf("%d, %d \n", sizeof(n4), sizeof(long));
	
	printf("------실수형------ \n");
	printf("%d, %d \n", sizeof(n5), sizeof(float));
	printf("%d, %d \n", sizeof(n6), sizeof(double));
	printf("%d, %d \n", sizeof(n7), sizeof(long double));
}

------정수형------
1, 1
2, 2
4, 4
4, 4
------실수형------
4, 4
8, 8
16, 16

--------------------------------
Process exited after 0.02011 seconds with return value 0
계속하려면 아무 키나 누르십시오 . . .

sizeof(변수)를 하면 변수의 메모리 크기가 나오고 sizeof(자료형)을 하면 자료형의 크기가 나옵니다.

출력 값을 보면 아시다시피 자료형과 변수의 메모리 크기는 같습니다.

저 출력 값은 바이트 값인데 int형은 4바이트의 크기로 출력을 한다는 것을 알 수 있습니다.

 

저 자료형의 크기는 컴퓨터가 몇 비트냐에 따라 다르게 나옵니다.

32비트 컴퓨터에서는 int 형이 4바이트(32비트)입니다.

그러면 64비트 컴퓨터에선 int형이 8바이트일까요? 그건 아닙니다.

 

64비트 운영체제에서는 int 가 32bit(4byte)로 고정되어 사용됩니다.

이유는 int형의 크기가 64비트 컴퓨터에서 8바이트일 이유가 없고.. 32bit 프로그램이 64bit로 옮겨가면서

모두 수정해야 할 상황이 생길 수 있기 때문이라고 합니다.

이에 관해선 인터넷에 정보들이 많으니 직접 찾아보시길 바랍니다.

 

정수형

자료형에 할당된 메모리 크기는 데이터를 표현할 수 있는 범위와 연관이 있습니다.

아래는 정수형 자료형의 표현 범위입니다. 

정수형 크기 데이터 표현범위
char 1바이트 -128 ~ +127
short 2바이트 -32768 ~ + 32767
int 4바이트 -2147483648 ~ + 2147483647
long 4바이트(32bit)/8바이트(64bit) -2147483648 ~ + 2147483647
long long 16바이트 -9223372036854775808 ~ +9223372036854775807  

 

데이터의 표현 범위를 구할 때는 $-2^{n-1}(최소)$ ~ $2^{n-1} - 1(최대)$ 의 공식으로 구해집니다.

이 공식을 외울 필요는 없습니다. 데이터의 표현 범위를 구해주는 라이브러리가 있습니다 이름은 limits.h(절댓값)입니다.

당연하겠지만 데이터 표현 범위가 넓을 수록 표현할 수 있는 수가 큽니다.

 

파일을 찾아보면 데이터 표현범위가 매크로 상수 #define으로 정의되어 있습니다.

상수는 대문자로 하는 게 관례라고 상수 편에서 배웠는데 기억나시나요 ^^?

 

#include <stdio.h>
#include <limits.h>
int main(void){
	printf("%d, %d \n", CHAR_MIN, CHAR_MAX); //Char 최대값 , 최소값
	printf("%d, %d \n", SHRT_MIN, SHRT_MAX);
	printf("%d, %d \n", INT_MIN, INT_MAX);
	printf("%ld, %ld \n", LONG_MIN, LONG_MAX);
	printf("%lld, %lld \n", LONG_LONG_MIN, LONG_LONG_MAX);
	printf("%lld, %lld \n", LLONG_MIN, LLONG_MAX);
}

-128, 127
-32768, 32767
-2147483648, 2147483647
-2147483648, 2147483647
-9223372036854775808, 9223372036854775807
-9223372036854775808, 9223372036854775807

--------------------------------
Process exited after 0.01935 seconds with return value 0
계속하려면 아무 키나 누르십시오 . . .

전처리기에서 limits.h 를 임포트 한 뒤 자료형 이름_MAX 또는 자료형 이름_MIN를 하면 최대 최소를 구할 수 있습니다.

직접 출력하면서 값을 확인해보세요 ^^ 

long을 출력할 땐 %ld, long long 을 출력할땐 % lld를 사용합니다.

LLONG과 LONG_LONG 은 같은 의미입니다.

 

특이한 점은 short를 출력할 때 SHORT 가 아닌 SHRT를 사용한다는 점이네요.

 

#include <stdio.h>
int main(){
	printf("%d \n", 2147483647);
	printf("%d \n", 2147483647+1); //오버플로우 발생
	printf("%u \n", 2147483647 * 2); //표현가능
	printf("%u \n", -1 * 2147483647 * 2); //표현불가 
}

2147483647
-2147483648
4294967294
2

--------------------------------
Process exited after 0.0227 seconds with return value 3
계속하려면 아무 키나 누르십시오 . . .

저번 printf 편에서 사용했던 서식 문자 % u를 사용했던 예제인데요.

% u를 사용하면 정수 값의 2배를 출력할 수 있는 대신 음수 값을 출력할 수 없다고 했습니다

 

이 u는 Unsinged의 약자입니다. 뜻하자면 '부호가 없는'입니다. 

우리가 대게 사용하는 자료형 int를 생각해봅시다.

 

int 앞엔 사실 singed 가 생략돼서 사용하는 건데요, singed는 부호가 있다는 의미로 음수, 0, 양수를

모두 표현할 수 있습니다. 하지만 unsinged 키워드가 붙게 되면 음수 부분의 출력 범위가 양수 부분으로 넘어가게 되고

양수 출력 범위는 2배가 되며 음수는 표현할 수 없게 됩니다. 위 예제를 보면% d 2배를 % u로

출력할 수 있지만 음수 값 출력이 안되는 걸 알 수 있습니다.

 

 

즉 키워드 unsinged 가 붙으면 0, 양수(기존 출력 범위의 2배)를 출력하게 됩니다.

limits.h 를 이용해 unsinged 값들의 데이터 표현 범위도 볼 수 있습니다.

 

#include <stdio.h>
#include <limits.h>
int main(void){
	printf("%u \n", UINT_MAX);
	printf("%lu \n", ULONG_MAX);
	printf("%llu", ULLONG_MAX);
}

4294967295
4294967295
18446744073709551615
--------------------------------
Process exited after 0.01927 seconds with return value 0
계속하려면 아무 키나 누르십시오 . . .

직접 출력 값들을 확인해보세요~ 어때요 양수 표현 범위가 2배가 되었죠 ^^?

ULONG 출력 시 %lu, ULONG_LONG 출력시 % llu를 사용합니다.

그냥 % d 가 % u로 바뀐 게 전부예요.

 

MIN 값을 구하려면 오류가 날건대 이건 의미가 없기 때문입니다. 음수는 표현이 안되니 최솟값은 어차피 0이겠죠..

 

 

크기가 작은 자료형은 최적화에 도움이 될까?

우리가 물건을 담을 때 사과 하나를 담는다면 봉지 하나만 있으면 됩니다. 큰 카트는 필요 없죠

그러면 컴퓨터에서 1이라는 정수를 담을 때도 int형이 아닌 메모리 크기가 더 작은 char 값에 담는 게 더 효율적일까요?

그렇지는 않습니다. 컴퓨터에서는 정수형 중에서도 int형을 가장 빠르게 처리하기 때문입니다.

 

컴퓨터가 한 번에 64,32 비트씩 연산하는데 char 은 1바이트 차지하고 int형은 4바이트(32비트) 차지하므로

char로 변수를 만들게 되면

char로 쪼개는 과정이 한 번 더 일어납니다. 그래서 조금 더 시간이 걸리게 됩니다. 물론 이것을 체감하긴 어렵겠지만;;

최적화를 위한 자료형의 크기 고려보다는 각 자료형의 호환성을 잘 고려하면서 프로그래밍하는 것이 좋습니다.

 

char a = 10; 일 때도 10이 자동으로 int형으로 변환된 뒤 char형태로 변환되어 대입됩니다.

 

오버플로우와 언더플로우

각 자료형 데이터 표현 범위의 최댓값보다 큰 값을 저장하면 오버플로우가 발생하고 최솟값보다 작은 값을 저장하면

언더플로우가 발생하게 됩니다.

 

https://blog.naver.com/ljc1928/220605605310

 

이때 오버플로우가 발생하면 최솟값부터 다시 새고, 언더플로우가 발생하게 되면 최댓값부터 다시 샙니다.

즉 수가 순환하게 되는데 위 사진을 참고해주세요.

 

#include <stdio.h>
#include <limits.h>
int main(void){
	char a = 130; //char 값의 최대표현범위는 127
	char b = -129; //char 값의 최소표현범위는 -128
	
	//a는 최대값의 3만큼 초과
	//b는 최소값보다 1작음 
	printf("%d %d", a,b);
}

 

COMMENT WRITE