C언어 데이터 타입의 크기는 컴파일러의 옵션에 따라 달라질 수 있습니다.
요즘 컴퓨터는 대부분 64bit 인데, 컴파일러의 기본 세팅은 32bit에 맞춰서 컴파일됩니다.
그게 가능한 이유는, 64bit에서 32bit 하위호환이 가능하기 때문입니다.
대체적으로 우리가 사용하는 컴퓨터에는 인텔이나 AMD의 cpu를 사용하는데, 이것들을 x86 아키텍쳐라고하고, x86아키텍쳐의 64bit 판이 x86_64 입니다.
x86_64 아키텍쳐는 하위호환이 가능해서, x86_64 아키텍쳐에 64bit 운영체제여도, 32bit 연산이 가능합니다.
Type | Size | Range |
char | 1 byte | [-127, +127] |
signed char | 1 byte | [-127, +127] |
unsigned char | 1 byte | [0, 255] |
각 타입들의 사이즈와 범위의 관계는?
char 타입의 사이즈는 1 byte인데, 1byte는 8bits이고, 8bits로 표현할 수 있는 수의 범위가 곧 각 타입들의 범위가 됩니다.
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2진수 00000000는 10진수 0이구요,
0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
2진수 00000011는 10진수 3이구요,
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
2진수 11111111는 10진수로 255입니다.
그래서 unsigned char 타입의 크기는 1byte(8bits)니까 이 크기로 표현할 수 있는 수의 범위는 0부터 255입니다.
signed char 타입의 범위는 -127부터 +127 입니다.
8bits 중 가장 왼쪽 비트가 1일때 음수가 되는데,
-1은 1111 1111
-2는 1111 1110
-3은 1111 1101 입니다.
-2(1111 1110)에 2를 더하면 0000 0000이 되고
-3(1111 1101)에도 3을 더하면 0000 0000이 됩니다.
음수 범위의 끝인 -127은 10000001 입니다.
이렇게 음수 표시를 하는 이유는 연산의 범위가 8비트로 제한되기 때문입니다.
컴퓨터에서는 프로세서가 저장할 수 있는 비트의 수가 제한됩니다.
즉 자릿수가 무한대가 되지 않고 숫자가 계속 증가하다가 다시 0이 되는 순간이 오기 때문에 최상위 비트 MSB가 1일 때를 음수로 정할 수 있습니다.
(github.com/gurugio/book_assembly_8086_ko/blob/master/number.md)
Type | Size | Range |
int | 2 or 4 bytes | [-32,768, 32,767] or [-2,147,483,648, 2,147,483,647] |
unsigned int | 2 or 4 bytes | [0, 65,535] or [0, 4,294,967,295] |
long | 8 bytes or (4bytes for 32 bit OS) | [-9223372036854775808, 9223372036854775807] 8 bytes |
unsigned long | 8 bytes or (4bytes for 32 bit OS) | [0, 18446744073709551615] 8 bytes |
long int | 4 bytes | [-2147483648, +2147483647] |
unsigned long int | 4 bytes | [0, 4294967295] |
long long int | 8 bytes | [-9,223,372,036,854,775,807, +9,223,372,036,854,775,807] |
unsigned long long int | 8 bytes | [0, 18446744073709551615] |
int 타입의 사이즈는 16bit에서는 2bytes, 32bit에서는 4 bytes, 64bit에서는 8 bytes의 크기를 가집니다.
그래서 환경에 따라 int 타입이 표현할 수 있는 수의 범위가 달라집니다.
자신의 환경에서 직접 크기를 확인하고 싶다면 sizeof(type) 함수를 사용합니다.
type define
확실히 하고 싶다면, 컴파일러 gcc나 clang에 stdint.h 를 사용 할 수 있습니다.
int16_t n1;
int32_t n2;
int64_t n3;
Pointer
모든 포인터 크기는 고정되어 있습니다.
주소의 값을 저장하는 타입이기 때문입니다.
포인터의 크기도 컴파일러의 옵션에 따라 달라질 수 있습니다.
보통의 경우 32bit로 컴파일 되어서 포인터의 크기는 4 bytes 입니다.
64bit로 컴파일할 경우, 8 bytes 입니다.
32bit 에서 포인터의 크기가 4 bytes 인 이유.
32bit로 표현할 수 있는 범위의 숫자는 0부터 4294967296까지 입니다.
32bit cpu의 주소 공간의 크기는 4294967296개이고, 한번에 주소 값을 4294967296개까지 가질 수 있습니다.
그럼 포인터의 주소값은 0부터 4294967296가 될 수 있기 때문에 포인터의 크기가 4 bytes여야 합니다.
64bit에서는 가능한 주소 공간의 크기를 모두 제공하지 않고 하위 48bit만 사용합니다. 왜냐하면 그만큼 많이 필요하지 않기때문입니다.
'C' 카테고리의 다른 글
c로 식사하는 철학자 문제 풀기 (2) | 2021.07.27 |
---|