C 언어(13) - 다중포인터, 포인터의 연산

C 언어 강의, 다중포인터와 포인터의 연산

Featured image

🔚 짧게 하는 복습

✅ 1. 메모리 구조를 통한 포인터의 원리를 이해한다.

✅ 2. 자료형에 맞게 포인터 변수를 선언하는 법을 안다.

✅ 3. 포인터 변수의 역참조, 간접 참조 그리고 직접 참조를 이해한다.

혹시 기억이 안 난다면, 다시 돌아가자


이번 수업은 다중 포인터, 포인터와 정수, 포인터 간의 연산에 대해 다루어 볼 예정이다.

여기가 특히 많이 들 포기하는 부분인데, 이게 왜 쓰는지 모르고 배워야해서 그렇다.

이번 시간을 잘 배우면 다음 시간부터 배울 배열과 접목해서 유기적으로 이해가 되니까, 일단은 포인터의 심화 이론을 배우도록 하자.

쉽지 않은 분야인데, 천천히 복습하며 따라왔으면 좋겠다.


다중 포인터란?

저번 예제들 중, 이 예제에 대해 다시 보자.

여기서 주목했던 것 중 하나는 포인터도 변수이기에 포인터 변수도 시작 주솟값을 가진다라는 것이었다.

그렇다면 포인터를 가리키는 포인터도 만들 수 있을까?

아래 예제를 확인해보자.

놀랍게도 포인터의 포인터도 만들 수 있는 모습이다. 다만 포인터의 포인터를 만들 때는 선언 시 참조 횟수만큼 *을 더 붙여줘야 한다.

두 번 참조된 포인터를 이중 포인터, 세 번 참조된 포인터를 삼중 포인터, 2번 이상의 포인터들을 모두 다중 포인터라고 한다.

아래 코드와 같은 삼중 포인터도 가능하다. (현실적으로 삼중 포인터 이상의 다중 포인터는 쓸 일이 거의 없다.)

int p;
int *p2 = &p;
int **p3 = &p2;

포인터와 정수 연산

포인터의 연산은 제한되게 허용되어 있는데, 포인터와 정수 연산, 포인터끼리의 뺄셈만 허용된다.

포인터와 정수 연산 중에서도 덧셈, 뺄셈만 허용되는데, 이는 앞으로 나올 배열이라는 주제와 관련이 있다.

일단은 그냥 받아들이자.

포인터 변수의 값에 정수를 더하면, 주소값에 +정수가 되는 것이 아니라 주솟값 + 정수*변수의 자료형의 크기이 나온다.

이게 무슨 말인지 직접 코드로 확인해보자.

int형은 4씩 차이가 나고, char는 1씩, double은 8씩 제대로 연산되는 모습이다.

왜 주소값에서 +1bit, +2bit를 단순히 더하는 연산이 아니라 자료형에 맞게 연산이 되냐 하면

포인터 변수 내에서 주소 연산은 비트 연산으로 대체할 수 있고,

만약 포인터 변수 범위를 넘어나는 절대적인 주소 연산은 큰 의미가 없기 때문이다.

예를 들어 a를 가리키는 시작 주소에서 38bit 떨어진 주소 같은 연산을 해도, 그 주소가 변수의 시작 주소가 아니라면 의미가 없음.

더 자세한 내용은 역시 배열에 들어가면 알게 된다.


포인터끼리의 연산

여기가 더 특이하다. 포인터끼리의 연산은 덧셈도, 곱셈도 나눗셈도 모두 안된다.

다만 뺄셈은 허용이 되는데, 이 역시 단순히 주소값1 - 주소값2이 아니라 (주소값1 - 주소값2)/자료형의 크기이 나온다.

이건 또 왜 이럴까? 그 이유는 간단한데 두 변수의 사이에 같은 자료형의 변수가 몇 개가 더 들어갈 수 있는지 계산할 일이 있기 때문이다.

덧셈이 없는 이유는, 그런 계산을 할 상황이 없기 때문이다.

아직은 이해가 안 되지만, 다음 시간 배열을 배우면 조금 더 명쾌하게 이해가 될 것이다.


📖 오늘의 핵심(다 알기 전까지는 넘어가지 말자❗)

✅ 1. 다중 포인터를 이해한다.

✅ 2. 포인터와 정수의 덧셈, 뺄셈을 이해한다.

✅ 3. 포인터 간의 뺄셈을 계산한다.

⚠️ 두 계산 모두 자료형의 크기가 곱해지거나, 나뉘는 계산임을 까먹어선 안 된다.

💣 과제, 없음.