일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 자바 thread 실행 순서 제어
- JAVA11
- hash table
- 수학
- heroku
- Kadane's Algorithm
- 카데인 알고리즘
- 자바 스레드 실행 순서 제어
- input
- Easy
- 자바입력
- R
- 사칙연산
- array
- SpringBoot 2
- scanner
- Today
- Total
DeFacto-Standard IT
포인터의 바이트 크기와 자료형을 지정하는 이유 본문
포인터의 크기는 무조건 4바이트가 아니다.
64비트 OS -> 8바이트
32비트 OS -> 4바이트
16비트 OS -> 2바이트
이와 같은 이유는 간단하다.
포인터가 저장하는 값은 '주소'이다.
8비트는 1바이트이다. 따라서 64비트는 8바이트이다.
즉, 주소 하나를 지정하는데 64비트를 쓰므로 64비트 운영체제라고 하는 것이고
주소 하나를 지정하는데 32비트를 쓰므로 32비트 운영체제라고 하는 것이고
주소 하나를 지정하는데 16비트를 쓰므로 16비트 운영체제라고 하는 것이다.
윈도우 XP의 경우 램을 4기가 이상을 인식하지 못하는 이유도, 램이 저장가능한 총 주소는 4기가라고 하더라도
OS자체에서는 그 이상의 값을 가지지 못하기때문이다.
결론은 포인터 변수는 주소 하나를 지정하는데 쓰이므로, 해당 OS가 몇bit OS 인지에 따라 다르다.
그렇다면 자료형에 관계 없이, 한 OS 내에서 모든 자료형의 포인터 변수 자체의 크기는 동일하다고 할 수 있다.
애초에 주소값만을 저장하는게 포인터기 때문이다.
그렇다면 왜 자료형을 붙이는 것일까.
그 이유는 '자료형의 크기'이다.
무슨 말이냐면, 예를 들어 배열을 사용할 때, 다음 배열 요소의 주소 시작값을 알 수 있다는 말이다.
예를들어서, 32비트 OS 기준으로 C언어에서 int 타입은 4바이트, char 타입은 1바이트이다.
사용자 정의 구조체 하나의 크기는, 안에 정의된 int나 char와 같은 노말타입 혹은 다른 구조체 필드나 배열이 몇 개가 있냐에 따라 달라진다.
가령 int 타입 필드 2개와 char 타입 필드 4개가 있는 Sub라는 구조체가 있다면
2개*4bit + 4개*1bit = 12바이트가 Sub 구조체 하나에 대한 크기이다.
위에서 설명 했듯이, Sub타입 포인터 자체의 크기는 Sub구조체의 크기가 아니라 OS에 따라 크기가 정해진다.
즉 int나 char나 Sub타입의 포인터 자체의 크기는, 컴파일하는 PC가 32비트 OS를 쓰면 4바이트, 64비트 OS를 쓰면 8바이트로 전부 동일하다는 것이다
하지만, Sub 구조체 엘리먼트를 포함하는 배열을 가리키는 포인터의 경우 int나 char로 지정못하고 반드시 Sub로 해야한다.
그 이유는 배열의 크기가 Sub 구조체의 크기 단위로 엘리먼트가 구분되기 때문이다.
만약 int형 포인터 변수로 Sub구조체를 가르키고, 다음 요소를 확인하게 코딩해버리면,
int 타입의 크기인 4바이트(포인터 변수 크기가 아닌 int 타입 자체의 크기) 만큼 움직이게 된다. 그러나 Sub구조체는 12바이트를 움직여야 다음 요소가 지정이 된다.
int형 포인터 변수를 쓰면 다음 Sub 엘리먼트가 아니라 여전히 첫 번째 엘리먼트의 중간에 4바이트 위치를 가리키게 된다.
따라서 Sub 포인터 변수를 써서 다음 요소를 확인해야 12바이트를 제대로 움직여 다음 요소를 가리킬 수 있다는 것이다.
이것이 포인터에 자료형을 기술하는 이유이다.