강의, 책을 보면서 노트화 했던 것을 정리하는 포스팅입니다.
포인터는 무엇일까?
C 언어에서 포인터는 무엇일까요? 개념 자체는 단순해요. 그냥 메모리의 주소 값을 가질 수 있는 녀석이죠.
사용하는 이유는?
이러한 포인터를 사용하는 무엇일까요?
함수를 사용하지 않고, 동적 할당도 사용하지 않고, 모든 코드를 진입점 함수에 해당하는 main()에 모든 코드를 집어 넣으면 포인터를 사용할 필요가 없을지도 몰라요.
하지만 우리는 그렇게 코딩을 하지 않고, 유지 보수를 용이하게 하기 위해서 기능별로 소스 파일 만들고, 모듈화 하기 위해서 진입점 함수의 부분을 간략화 하는 등 일을 하기 때문에 포인터 라는 것이 필요해요.
포인터라는 문법이 없는 자바, C# 등 에서는 가비지 컬렉션이라고 불리는 녀석들이 알아서 메모리를 관리하기 때문에 필요가 없지만, C/C++ 에서는 메모리 관리를 개발자가 직접하기 때문에 포인터라는 문법이 존재하죠.
포인터 문법
포인터는 “*” 별표라는 기호를 이용해서 사용해요.
예를 들어서, char *a, int *b, float *c 라고 하면, 순서대로 char 형 포인터로 선언된 a, int형 포인터로 선언된 b, float형 포인터로 선언된 c로 볼 수 있어요.
이렇게 단일 포인터로 사용될 경우에는 포인터가 어떤 식으로 사용되는지 쉽게 알 수 있지만, 포인터를 이중,삼중으로 사용하게 되면, 이 포인터가 무엇을 의미하는지 알기 쉽지 않아요. 그거에 대해서 차근차근 알아볼 거에요.
그리고 “*” 별표는 포인터 변수라는 것을 의미하는 것 이외에도, 곱셈 기호로 사용하기도 하고, 역참조해서 해당 주소의 값에 접근할 때도 사용해요.
또한 모든 포인터는 대상체의 크기만큼 이동을 하게 되는데 이게 무슨 의미일까요? 한번 코드를 통해 알아봅시다.
1 |
|
7 line-> 200
8 line-> sizeof(i): 4
9 line-> sizeof(int): 4
10 line-> sizeof(p): 8
11 line-> sizeof( int * ): 8
12 line-> sizeof( *p ): 4
13 line-> p=0x7ffeea9fa848
14 line-> p+1=0x7ffeea9fa84c
맨 마지막의 메모리 주소 값은 환경에 따라 다를 수 있습니다.
변수 i를 100로 초기화를 했지만, 포인터 변수 p에 i의 주소 값을 집어 넣고, 포인터 변수 p를 역참조해서 200라는 값을 대입을 했어요.
그래서 변수 i의 값이 100에서 200로 변한 것이죠.
그리고 int 형의 크기, int 형 변수의 크기, int 포인터 형의 크기, int 포인터 형 변수의 크기, int 포인터 형 변수의 역 참조의 크기에 대해 알아봤어요.
int 형 같은 경우에는 IA-64 계열에서는 4바이트의 크기를 가지고 있어요. cpu의 종류에 따라 이 크기는 달라질 수도 있어요.
int 포인터 형 같은 경우에는 IA-64 계열에서는 8바이트, x86 계열에서는 4바이트를 가지고 있어요. 그리고 포인터 같은 경우에는 int 형이든, float 형이든 크기가 동일해요. 그 이유는 메모리 주소를 나타내기 때문이죠. 그렇다고 하더라도 int 포인터 형과 float 포인터 형을 섞어서 써도 된다는 말은 아니에요. 섞어서 사용하면 안됩니다.
제 cpu는 IA-64 계열이라서 int 형의 크기가 4바이트, int 포인터 형의 크기가 8바이트, int 포인터 형의 역참조 크기가 4바이트가 나옵니다.
int 포인터 형의 역참조 크기가 4바이트가 나오는 이유는 int 포인터 형이 가리키고 있는 녀석이 int 형이기 때문입니다. 그래서 4바이트 크기가 나오는 것입니다.
char 포인터 형의 역참조 크기는 몇 바이트가 나올까요? char 포인터 형의 크기는 IA-64 계열에서 int 포인터 형의 크기처럼 8바이트가 나오지만, 역참조의 크기는 4바이트가 아니라 1바이트가 나옵니다. 그 이유는 char 포인터 형의 역참조는 char 형을 가리키기 때문이죠.