처음에 포인터를 배울 때 포인터의 개념은 그렇게 어렵지 않았다. 하지만 실제로 사용하다보면 어디선가부터 꼬이기 시작하는데, 특히 이중포인터, 삼중포인터를 사용할 때 코드를 작성하면서도 이게 맞는지 헷갈렸다. 솔직히 헷갈릴 이유가 없는데 왜 그렇게 헷갈렸던 것일까? 그 이유는 별표(*) 의 사용법이 혼동되기 때문이다.
우리는 포인터를 배울 때
* 연산자는 역참조, 즉 실제 값을 가져오며,
& 연산자는 주소값을 가져온다고 배운다.
다음 포인터 선언과 사용을 보여주는 코드를 보자.
/*포인터 선언*/
int num = 10;
int *ptr = #
/*포인터의 사용*/
printf("%d \n", *ptr);
포인터의 선언을 할 때도 *연산자를 사용한다. 그리고 포인터를 사용할 때도 *연산자를 사용한다. 이 두가지 차이를 명확하게 구분할 수 있겠는가? int *ptr = # 라는 문장에서 *ptr 때문에 혼동이 시작된다. *는 분명 역참조 연산자이며, 실제 값을 의미하는데 = # 부분 때문에 실제 값 = 주소 값이 들어간다고 헷갈리기 시작한다. 결국 포인터를 통해 printf문을 실행할 때도 똑같이 *ptr라는 부분 때문에 "주소값이 출력되는건가? 아니면 10 이 출력되는 것인가" 헷갈리게 된다. 이 문제는 다중포인터를 사용하면서 더욱 심각해진다.
그래서 포인터를 어떻게 사용하면 헷갈리지 않을 수 있을까?
int num = 10;
int* ptr = # //1번
int * ptr = # //2번
int *ptr = # //3번
1번과 2번, 그리고 3번을 비교해보자. '포인터 선언문'에서 *연산자의 위치는 어디에 있어도 상관없다. 1~3번 모두 정상적으로 컴파일이 된다. 전부 문제없다면 오로지 사용자 입장에서 어떤것이 보기 좋을까? 개인차가 있겠지만, 포인터가 헷갈렸던 나는 1번 방법을 통해 선언하기로 결정했다.
int* ptr = # 라는 문장은
즉 (int를 가리키는 포인터) 변수 ptr에 num의 주소값이 저장된다 라고 간단명료하게 해석할 수 있다.
ptr이라는 변수 그 자체에는 num의 주소값이 저장되며, 이후 이 포인터를 사용하기 위해 *연산자를 사용하면 ptr에 있는 주소값을 통해 역참조 되고, 실제 값인 10이 불러온다고 생각하면 된다. 선언문에서 마지막에 붙어있는 *는 "~를 가리키는 포인터" 라고 치환해서 읽고 생각하면 된다.
int num = 10;
int* ptr = #
int** dptr = &ptr; //1번
int* * dptr = &ptr; //2번
int* *dptr = &ptr; //3번
int** dptr = &ptr; 라는 이중포인터 문장은
즉, (int*를 가리키는 포인터) 변수 dptr에 ptr의 주소값이 저장된다 라고 해석할 수 있다.
이쯤되면 삼중포인터도 문제없다.
int*** trptr = &dptr; 라는 삼중포인터 문장은
즉, (int**를 가리키는 포인터) 변수 trptr에 dptr의 주소값이 저장된다 라고 해석할 수 있다.
정리!
* 연산자의 사용법은 한 가지가 아니라 두 가지다!
1. 포인터 선언문에서 *연산자는 "~를 가리키는 포인터" 라는 의미를 가진다.
2. 포인터 사용문에서 *연산자는 실제 값을 의미한다. (역참조)
'정보기술 > C \ C++' 카테고리의 다른 글
Ubuntu C/C++) Command g++ not found 해결법 (0) | 2021.01.06 |
---|---|
[C] 포인터의 개념이 이해되지 않아요. (0) | 2020.12.26 |
Visual Studio Community 2015 / Visual Studio Code 다운로드 방법 (0) | 2016.11.28 |
Dev C++ 다운로드 및 설치 , 초기 실행법 (1) | 2016.11.22 |