알고리즘 문제를 풀 때 주로 C++의 STL을 사용하다보니 포인터를 잘 안쓰게 된 것 같다.
그러다 학교 알고리즘 수업에서 STL을 사용하지 않고 직접 필요한 자료구조를 구현하여 문제를 풀어보라는 교수님의 말씀에 포인터 개념을 다시 정리하기로 했다.
포인터는 두 가지 의미가 있다.
int main() {
int a = 10;
int *p = &a; // 이 때의 '*'는 포인터 타입을 말한다.
printf("%d", *p); // 이 때의 '*'는 포인팅하는 포인터를 말한다.
}
여러가지 이유가 있을 것 같다. 그 중에서 이번 포스트에서는 두 가지 케이스를 다뤄볼 것이다.
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int a = 10, b = 20;
cout << a << ' ' << b << '\n';
swap(&a, &b);
cout << a << ' ' << b << '\n';
int size;
cin >> size;
int *arr = (int *)malloc(sizeof(int) * size); // 입력 받은 size 값 만큼 동적으로 배열의 크기가 할당
}
const int ROWSIZE = 4;
const int COLSIZE = 5;
void printArr(int **arr)
{
for (int i = 0; i < ROWSIZE; i++)
{
for (int j = 0; j < COLSIZE; j++)
{
cout << arr[i][j] << ' ';
}
cout << '\n';
}
}
int main()
{
int **arr = (int **)malloc(sizeof(int *) * ROWSIZE);
for (int i = 0; i < ROWSIZE; i++)
{
arr[i] = (int *)malloc(sizeof(int) * COLSIZE);
}
int cnt = 0;
for (int i = 0; i < ROWSIZE; i++)
{
for (int j = 0; j < COLSIZE; j++, cnt++)
{
arr[i][j] = cnt;
}
}
printArr(arr);
for (int i = 0; i < ROWSIZE; i++)
{
delete arr[i];
}
delete arr;
}
typedef struct Node
{
int data;
Node *left;
Node *right;
} node;
void insert(node **root, int data)
{
if (*root == NULL)
{
*root = (node *)malloc(sizeof(node));
(*root)->data = data;
(*root)->left = NULL;
(*root)->right = NULL;
return;
}
if ((*root)->data > data)
insert(&(*root)->left, data);
else
insert(&(*root)->right, data);
}
void preOrder(node *root)
{
if (root == NULL)
return;
cout << root->data << '\n';
preOrder(root->left);
preOrder(root->right);
}
void destruct(node **root)
{
if (*root == NULL)
return;
destruct(&(*root)->left);
destruct(&(*root)->right);
delete *root;
*root = NULL;
}
int main()
{
node *root = NULL;
insert(&root, 20);
insert(&root, 10);
insert(&root, 30);
preOrder(root);
destruct(&root);
}
여기서 insert 함수와 destruct 함수의 파라미터에는 왜 투포인터를 사용해야 할까?
void insert(node **root, int data)
{
if (*root == NULL)
{
*root = (node *)malloc(sizeof(node)); // 여기에 브레이크 포인트를 걸었다고 합시다
(*root)->data = data;
(*root)->left = NULL;
(*root)->right = NULL;
return;
}
if ((*root)->data > data)
insert(&(*root)->left, data);
else
insert(&(*root)->right, data);
}
int main() {
node *root = NULL;
insert(&root, 20);
...
}
브레이크 포인트 걸린 초기 모습
malloc으로 할당 한 후의 모습
만약 insert 함수 파라미터에 포인터를 두개 붙이지 않고 한개만 붙이고 브레이크 포인트에 걸린 초기 모습
만약 insert 함수 파라미터에 포인터를 두개 붙이지 않고 한개만 붙이고 malloc으로 할당 한 후의 모습
잘 못된 부분이나 이해가 안되는 부분은 댓글 달아주세요!