C & C++

C언어 포인터를 input으로 받는 함수 선언 (pass by pointer) : swap 함수 예제 비교

jimmy_AI 2021. 12. 20. 15:12
반응형

C언어 pass by value vs pass by pointer 차이

안녕하세요.

이번 포스팅에서는 C언어에서 포인터를 함수의 인자로 받는 

pass by pointer 선언 방식의 사용 이유와 예제에 대해서 살펴보도록 하겠습니다.

 

swap 함수 포인터 사용 예제

가장 기본적인 예제를 통해서 포인터를 인자로 받는 이유에 대해서 살펴보겠습니다.

두 정수 변수의 값을 서로 바꾸는 swap 함수를 예시를 보겠습니다.

#include <stdio.h>

void swap(int a, int b){
  int t = a;
  a = b;
  b = t;
}

void swap2(int *a, int *b){
  int t = *a;
  *a = *b;
  *b = t;
}

int main(){
  int num_1 = 3;
  int num_2 = 5;
  
  // pass by value
  swap(num_1, num_2);
  printf("pass by value\n");
  printf("num_1 : %d, num_2 : %d\n", num_1, num_2);

  // pass by pointer
  swap2(&num_1, &num_2);
  printf("pass by pointer\n");
  printf("num_1 : %d, num_2 : %d\n", num_1, num_2);

}

일반 정수 인자를 input으로 받아 바꾼 swap 함수(pass by value)

포인터를 인자로 받고 두 포인터의 위치를 바꾼 swap2 함수(pass by pointer)

주목해보겠습니다. 결과는 어떻게 됬을까요?

pass by value 결과로 바꾼 결과는 정상적으로 두 변수가 swap되지 않았지만,

pass by pointer 결과로 바꾼 결과는 두 변수가 정상 swap되었음을 확인할 수 있었습니다.

 

이 이유는 쉽게 설명하면 다음과 같습니다.

 

pass by valuenum_1, num_2에 저장된 값만 읽어들여 지역변수 a, b에 저장합니다.

이 후, 위에서 새롭게 선언된 지역변수 a, b에 대해서 값을 바꾸고

지역변수는 함수를 빠져나가면 삭제되므로,

원래 변수인 num_1, num_2는 값이 바뀌지 않고 남아있게 됩니다.

 

반면, pass by pointernum_1, num_2의 포인터 주소를 가져와서,

이 두 주소가 가리키는 포인터 주소를 서로 바꾸어줍니다.

그렇게 되면, 실질적으로 num_1, num_2 변수가 저장하고 있는 값도

바뀌게 되는 결과를 낳게되는 것이지요.

 

그림으로 요약하면 다음과 같은 상황이라고 볼 수 있겠습니다.

 

반응형

swap 함수 포인터 사용 잘못된 경우

다만, 포인터 변수를 input으로 넣었다고 항상 정상적으로 swap이 이루어지는 것은

아니라는 점에 주의하셔야 합니다.

두 포인터 주소를 직접 바꿔주어야 한다는 점에 유의하며,

아래의 잘못된 예시를 살펴보겠습니다.

// 잘못 선언된 케이스(pass by value와 마찬가지 결과)
void swap(int *a, int *b){
  int* t = a;
  a = b;
  b = t;
}

위와 같은 경우는 pass by pointer처럼 보일 수 있으나,

실제로는 pass by value와 같은 효과를 지닌 경우이기에 유의하셔야합니다.

지역 변수로 포인터 주소 값을 가지는 변수만 불러와 해당 지역 변수 사이에서

값 교체만 진행하고, 실질적으로 원래 변수(num_1, num_2)를 가리키는 포인터는

바뀌지 않은 경우라고 이해해주시면 좋을 듯 합니다.

 

 

 

함수에서 이중 포인터를 input으로 받아 문자열 바꾸기

심화된 케이스인 이중 포인터를 input으로 받는 예시를 살펴보겠습니다.

이 경우는 문자열 전체끼리 위치를 swap하는 경우로 보시면 되는데요.

이중 포인터로 문자열 전체를 swap하는 예시 코드는 아래와 같습니다.

#include <stdio.h>

void swap(char** a, char** b){
char* t = *a;
*a = *b;
*b = t;
}

int main(){
  char* str_1 = "hello";
  char* str_2 = "world";

  printf("%s, %s\n", str_1, str_2);
  swap(&str_1, &str_2);
  printf("%s, %s\n", str_1, str_2);

}

다만, 위 경우 char str_1[] 형식으로 선언한 문자열 배열 형식의 경우 오류가 발생할 수도 

있음에 참고해주세요.

 

또한, 정수형 자료 배열 등 다른 자료형에 대한 배열에는 위 방법 적용이 어렵다는 점도

참고해주시면 좋을 듯 합니다.

 

C언어에서는 pass by refernece 방식은 지원하지 않아 변수 swap을 원할 경우 위와 같이

선언을 해주어야 합니다. 정수형 외에 실수형 등 다른 자료형에도 위와 같은 방법을 적용하는

예시는 동일합니다.