컴퓨터 프로그래밍/C

C언어 Call by Value / Call by Address

나노콛 2019. 7. 23. 10:46

Call by Value
(값에 의한 전달)

 

#include <stdio.h>
void Swap(int a, int b)
{
	int tmp;

	printf("2. x = %d y = %d\n", a, b);

	tmp = a;
	a = b;
	b = tmp;

	printf("3. x = %d y = %d\n", a, b);
}

int main(int argc, char const *argv[])
{
	int x = 10, y = 20;

	printf("1. x = %d y = %d\n", x, y);

	Swap(x, y);

	printf("4. x = %d y = %d\n", x, y);
	return 0;
}

x y의 값을 바꾸는 Swap() 함수를 정의했습니다.

 

결과는 함수 내부에서만 결과가 바뀌었고
결론적으로 x y는 바뀌지 않았습니다.

그 이유는

Swap() 함수 내부에서 선언된 변수는 함수를 빠져나오면 소멸하기 때문입니다.


Call by Address(call by reference)
(주소에 의한 전달)

 

#include <stdio.h>
void Swap(int* a, int* b)
{
	int tmp;

	printf("2. x = %d y = %d\n", *a, *b);

	tmp = *a;
	*a = *b;
	*b = tmp;

	printf("3. x = %d y = %d\n", *a, *b);
}

int main(int argc, char const *argv[])
{
	int x = 10, y = 20;

	printf("1. x = %d y = %d\n", x, y);

	Swap(&x, &y);

	printf("4. x = %d y = %d\n", x, y);
	return 0;
}

별(포인터)이 몇 개 붙었습니다.

동작 순서대로 파악해 보겠습니다.

int main(int argc, char const *argv[])
{
	int x = 10, y = 20;

	printf("1. x = %d y = %d\n", x, y);  //10 20

	Swap(&x, &y); //x y의 주소를 인자로 넣어준다.

 

void Swap(int* a, int* b)  //풀어서 쓰면 이해하기 편합니다.
{                          //int * a = &a, int * b = &b
	int tmp;

	printf("2. x = %d y = %d\n", *a, *b);  //*역 참조 연산자
                                           //(포인터변수가 가리키는 곳의 값을 의미)
                                           //a는 변수x의 주소값이 들어가 있습니다.
                                           //역참조 연산자로 인해서 변수x의 값을 가리킵니다.

	tmp = *a;  //*a는 x의주소값이 가지고 있는 곳의 값을 의미합니다. tmp = 10;
	*a = *b;
	*b = tmp;

	printf("3. x = %d y = %d\n", *a, *b); //20 10 값이 변동됨
}

 

printf("4. x = %d y = %d\n", x, y);// 주소에 의해서 값이 변동되었다. 20 10
	
    return 0;
}

위의 소스를 디버깅해서 정확하게 파악해보겠습니다.


int main(int argc, char const *argv[])
{
	int x = 10, y = 20;

초기화하기 전 쓰레기 값
초기화 이후

int main(int argc, char const *argv[])
{
	int x = 10, y = 20;

	printf("1. x = %d y = %d\n", x, y);  //10 20

	Swap(&x, &y);

Swap 함수를 만나서 함수 내부로 들어가면

void Swap(int* a, int* b)
{
	int tmp;

	printf("2. x = %d y = %d\n", *a, *b);

	tmp = *a;

함수에서 x y의 주솟값을 보내주어 a b에는 주솟값이 들어가 있다는 것이 확인

 

tmp에 *a의 값을 넣어줘서 tmp가 10

 

void Swap(int* a, int* b)
{
	int tmp;

	printf("2. x = %d y = %d\n", *a, *b);

	tmp = *a;
	*a = *b;

*a = *b를 하게 되면서 

a의 값이 20이 되었습니다. 주소는 다르다는 것을 확인!

 

void Swap(int* a, int* b)
{
	int tmp;

	printf("2. x = %d y = %d\n", *a, *b);

	tmp = *a;
	*a = *b;
	*b = tmp;

	printf("3. x = %d y = %d\n", *a, *b);
}

*b = tmp 하여 b는 10이 되었습니다.

Swap() 함수를 빠져나오면서 함수 내 변수 메모리는 소멸됩니다.

	Swap(&x, &y);

	printf("4. x = %d y = %d\n", x, y);
	return 0;
}

x y가 서로 바뀌었습니다.


주소를 이용해서 값이 변경되었기 때문에
실제 변수의 값이 변했습니다.

scanf("%d",&num);

scanf 함수에서 왜 &연산자를 쓰는지 하는 궁금증이
인자 전달시 주소 전달로 함수 내부에서 기능이 끝나고 실제 값이 변할 수 있다는 것을
확인할 수 있습니다.

728x90