[C언어] 이중포인터를 이용하여 배열을 교환하는 방법
배열 A와 배열 B를 바꾸고 싶은 경우를 생각해보자. 배열을 일일히 바꿔주는 것은 너무나 번거로운 일이다. 쉽게 바꾸기 위해 포인터가 기리키는 값만 바꾸어 주면 되는데, 이 때 함수를 사용하고자 한다면 이중포인터를 사용해야 한다.
'함수에서 굳이 왜 이중포인터를 사용해야 될까?'를 고민한 끝에 얻은 결론은 dereference(역참조)를 해야 함수 밖 값의 변화를 줄 수 있기 떄문이다.
자 먼저 더 쉬운 예를 보자.
변수 값 서로 바꾸기
#include <stdio.h>
void swapNumber(int first, int second) // 반환값 없음, int형 매개변수 두 개 지정
{
int temp; // 임시 보관 변수
temp = first;
first = second;
second = temp;
}
int main()
{
int num1 = 10;
int num2 = 20;
swapNumber(num1, num2); // 변수 num1과 num2를 넣어줌
printf("%d %d\n", num1, num2); // 10 20: swapNumber 함수와는 상관없이
// 처음 저장한 10과 20이 출력됨
return 0;
}
이 코드의 출력 값은 10 20 이다.
swapNumber 함수에서 분명 바꿔줬음에도 이런결과가 나온 것은 swapNumber 함수내에서 값을 바꿔줬지만, 이 변경은 함수 내에서만 유효하고 함수 밖으로 나올 땐 다시 원상복구 된다.
만약 함수를 통해 값을 변경하고자 한다면 변수들의 주소를 받아 포인터로 변경을 진행하면 된다.
#include <stdio.h>
void swapNumber(int *first, int *second) // 반환값 없음, int 포인터 매개변수 두 개 지정
{
int temp; // 임시 보관 변수
// 역참조로 값을 가져오고, 값을 저장함
temp = *first;
*first = *second;
*second = temp;
}
int main()
{
int num1 = 10;
int num2 = 20;
swapNumber(&num1, &num2); // &를 사용하여 num1과 num2의 메모리 주소를 넣어줌
printf("%d %d\n", num1, num2); // 20 10: swapNumber에 의해서 num1과 num2의 값이 서로 바뀜
return 0;
}
이 코드의 출력값은 20 10 이다. 이게 가능했던 이유는 함수내에서 dereference(역참조)를 통해 함수 밖에 있는 포인터가 가리키는 값 자체에 영향을 줬기 때문이다.
배열의 값 이중 포인터로 바꾸기
자 이제 워밍업이 끝났으니 같은 방식으로 배열을 바꾸기를 생각해보자.
#include <stdio.h>
void printArray(int* _array, int _len){
for (int i =0; i < _len; i++)
printf("%d ", _array[i]);
printf("\n");
}
void swapArray2(int* _arrayA, int* _arrayB){
int* temp = _arrayA;
_arrayA = _arrayB;
_arrayB = temp;
printArray(_arrayA, 5);
printArray(_arrayB, 5);
}
void main(void){
int arrayA[5] = {11, 12, 13, 14, 15};
int arrayB[5] = {21, 22, 23, 24, 25};
int* pA = arrayA;
int* pB = arrayB;
swapArray2(pA, pB);
printf("---------After swapArray()---------\n");
printArray(pA, 5);
printArray(pB, 5);
}
이렇게 바꾸면 함수내에서만 포인터(메모리 주소)가 바뀌고 함수 밖에선 arrayA와 arrayB의 값이 변하지 않는다.
그래서 함수 밖에서도 바꾸려면 포인터의 주소를 받아서 dereference를 통해 변경해야한다.
#include <stdio.h>
void printArray(int* _array, int _len){
for (int i =0; i < _len; i++)
printf("%d ", _array[i]);
printf("\n");
}
void swapArray(int** _arrayA, int** _arrayB){
int* temp = *_arrayA;
*_arrayA = *_arrayB;
*_arrayB = temp;
}
void main(void){
int arrayA[5] = {11, 12, 13, 14, 15};
int arrayB[5] = {21, 22, 23, 24, 25};
int* pA = arrayA;
int* pB = arrayB;
swapArray(&pA, &pB);
printf("---------After swapArray()---------\n");
printArray(pA, 5);
printArray(pB, 5);
}
짜잔 ! 이렇게 변경할 수 있다. 이게 제일 중요한 포인트이다.
물론 함수를 쓰지 않는다면 하기와 같이 일중포인터로 변경이 가능하다.
#include <stdio.h>
void printArray(int* _array, int _len){
for (int i =0; i < _len; i++)
printf("%d ", _array[i]);
printf("\n");
}
void main(void){
int arrayA[5] = {11, 12, 13, 14, 15};
int arrayB[5] = {21, 22, 23, 24, 25};
int* pA = arrayA;
int* pB = arrayB;
int* temp = pA;
pA = pB;
pB = temp;
printf("---------After swapArray()---------\n");
printArray(pA, 5);
printArray(pB, 5);
}
여담이지만,
1차원 배열은 사실 1차원 포인터이고 2차원 배열은 2차원 포인터이다.
그래서 n차원 배열의 첫번째 값을 얻으려면 dereference를 n번 해줘야 한다.
참조) 코딩 도장, 유튜브 채널 HPC Lab. KOREATECH
'정글 2기 > 자료구조(C언어)' 카테고리의 다른 글
[C언어] 레드-블랙 트리(Red-black Tree, RB Tree) (0) | 2021.09.09 |
---|---|
[C언어] 이진 탐색 트리(Binary Search Tree, BST) (0) | 2021.09.07 |
[C언어] 연결 리스트(Linked list) 구현 (0) | 2021.09.05 |
[C언어] 구조체 포인터 사용하기 (1) | 2021.09.04 |
댓글