남들이 안해본것을 해서 궁극적인 지식의 완성을 목표로 하는 블로그입니다. 제품리뷰 , IT, 프로그래밍 관련글을 포스팅합니다. 또한 자기만 읽으려고 만든 정리 노트식의 글들을 싫어합니다. 비전공자나 처음 본 사람도 최대한 이해할 수 있도록 프로그래밍 관련 글들을 쉽게 적으려고 노력하고 있습니다. 보안 계통과 컴퓨터의 Low-Level 한 분야에 관심이 많습니다.
안녕하세요 파일입니다. 이전 강의에서 정수형은 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로 옮겨가면서
모두 수정해야 할 상황이 생길 수 있기 때문이라고 합니다.
이에 관해선 인터넷에 정보들이 많으니 직접 찾아보시길 바랍니다.
자료형에 할당된 메모리 크기는 데이터를 표현할 수 있는 범위와 연관이 있습니다.
아래는 정수형 자료형의 표현 범위입니다.
데이터의 표현 범위를 구할 때는 $-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); }
[C언어 강좌] #7-1 자료형(Data Type)
안녕하세요 파일입니다. 이전 강의에서 정수형은 int형, 실수형은 float형이라고 다룬 적이 있었죠?
자료형에 관한 표도 봤었구요. 그런데 자료형이 뭘까요?
앞에서 변수를 배웠습니다 그렇죠? 변수는 선언할 때 int a 처럼 앞에 데이터를 저장할 형식을 지정해줍니다.
이것이 자료형입니다. 자료형이란 변수의 저장하는 데이터의 형식입니다.
정수를 저장하고 싶다면 int, long, char 등을 사용하구요
실수를 저장하고 싶다면 float, double, long double 등을 사용합니다.
각 자료형에는 할당되는 메모리의 크기가 있습니다. 이것은 sizeof 함수를 이용해 구할 수 있습니다.
sizeof(변수)를 하면 변수의 메모리 크기가 나오고 sizeof(자료형)을 하면 자료형의 크기가 나옵니다.
출력 값을 보면 아시다시피 자료형과 변수의 메모리 크기는 같습니다.
저 출력 값은 바이트 값인데 int형은 4바이트의 크기로 출력을 한다는 것을 알 수 있습니다.
저 자료형의 크기는 컴퓨터가 몇 비트냐에 따라 다르게 나옵니다.
32비트 컴퓨터에서는 int 형이 4바이트(32비트)입니다.
그러면 64비트 컴퓨터에선 int형이 8바이트일까요? 그건 아닙니다.
64비트 운영체제에서는 int 가 32bit(4byte)로 고정되어 사용됩니다.
이유는 int형의 크기가 64비트 컴퓨터에서 8바이트일 이유가 없고.. 32bit 프로그램이 64bit로 옮겨가면서
모두 수정해야 할 상황이 생길 수 있기 때문이라고 합니다.
이에 관해선 인터넷에 정보들이 많으니 직접 찾아보시길 바랍니다.
정수형
자료형에 할당된 메모리 크기는 데이터를 표현할 수 있는 범위와 연관이 있습니다.
아래는 정수형 자료형의 표현 범위입니다.
데이터의 표현 범위를 구할 때는 $-2^{n-1}(최소)$ ~ $2^{n-1} - 1(최대)$ 의 공식으로 구해집니다.
이 공식을 외울 필요는 없습니다. 데이터의 표현 범위를 구해주는 라이브러리가 있습니다 이름은 limits.h(절댓값)입니다.
당연하겠지만 데이터 표현 범위가 넓을 수록 표현할 수 있는 수가 큽니다.
파일을 찾아보면 데이터 표현범위가 매크로 상수 #define으로 정의되어 있습니다.
상수는 대문자로 하는 게 관례라고 상수 편에서 배웠는데 기억나시나요 ^^?
전처리기에서 limits.h 를 임포트 한 뒤 자료형 이름_MAX 또는 자료형 이름_MIN를 하면 최대 최소를 구할 수 있습니다.
직접 출력하면서 값을 확인해보세요 ^^
long을 출력할 땐 %ld, long long 을 출력할땐 % lld를 사용합니다.
LLONG과 LONG_LONG 은 같은 의미입니다.
특이한 점은 short를 출력할 때 SHORT 가 아닌 SHRT를 사용한다는 점이네요.
저번 printf 편에서 사용했던 서식 문자 % u를 사용했던 예제인데요.
% u를 사용하면 정수 값의 2배를 출력할 수 있는 대신 음수 값을 출력할 수 없다고 했습니다
이 u는 Unsinged의 약자입니다. 뜻하자면 '부호가 없는'입니다.
우리가 대게 사용하는 자료형 int를 생각해봅시다.
int 앞엔 사실 singed 가 생략돼서 사용하는 건데요, singed는 부호가 있다는 의미로 음수, 0, 양수를
모두 표현할 수 있습니다. 하지만 unsinged 키워드가 붙게 되면 음수 부분의 출력 범위가 양수 부분으로 넘어가게 되고
양수 출력 범위는 2배가 되며 음수는 표현할 수 없게 됩니다. 위 예제를 보면% d 2배를 % u로
출력할 수 있지만 음수 값 출력이 안되는 걸 알 수 있습니다.
즉 키워드 unsinged 가 붙으면 0, 양수(기존 출력 범위의 2배)를 출력하게 됩니다.
limits.h 를 이용해 unsinged 값들의 데이터 표현 범위도 볼 수 있습니다.
직접 출력 값들을 확인해보세요~ 어때요 양수 표현 범위가 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형태로 변환되어 대입됩니다.
오버플로우와 언더플로우
각 자료형 데이터 표현 범위의 최댓값보다 큰 값을 저장하면 오버플로우가 발생하고 최솟값보다 작은 값을 저장하면
언더플로우가 발생하게 됩니다.
이때 오버플로우가 발생하면 최솟값부터 다시 새고, 언더플로우가 발생하게 되면 최댓값부터 다시 샙니다.
즉 수가 순환하게 되는데 위 사진을 참고해주세요.
'프로그래밍 강좌 > C' 카테고리의 다른 글
COMMENT WRITE