easy software

C언어 Call-By-Value / Reference 이해 본문

C언어/포인터와 배열

C언어 Call-By-Value / Reference 이해

JAVA 웹개발자 2015. 1. 19. 21:14

안녕하세요. 오늘 전해드릴 내용은 중요한 개념중의 하나인 Call-By-Value / Reference 입니다.

 

용어가 중요한게 아닌, 개념이 중요하니 잘 이해해보세요.

 

생각보다 상당히 쉬운 내용입니다.

 

 

Call-By-Value 란?

 

값에 의한 호출이라고 정의할 수 있습니다.

 

예제를 통해 설명드리겠습니다.

 

int main(void){

 

int val1 = 10;

int val2 = 20;

 

swap(val1, val2);

 

printf("val1 : %d \n", val1);

printf("val2 : %d \n", val2);

 

return 0;

}

 

void swap(int a, int b){

int temp = a;

a = b;

b = temp;

 

printf("a : %d \n", a);

printf("b : %d \n", b);

}

 

main에서 변수 선언 후 swap이라는 함수를 호출하고 있습니다.

 

이 함수는 val1과 val2에 저장된 값을 변경하려고 구현한 함수입니다.

 

즉, 이 함수를 구현한 프로그래머는 val1 = 20, val2 = 10이 저장되기를 기대한 겁니다.

 

swap함수를 호출하면서 val1과 val2를 매개변수로 전달한 것 까진 이해가 되시죠?

 

그리고 swap함수 내에서는 전달받은 값을 a와 b에 저장하고 있습니다.

 

그리고 a와 b의 자리를 바꿔주고 있습니다.

 

하지만 이 프로그래머는 큰 실수를 저질렀네요.

 

그 이유를 설명드리겠습니다.

 

main에서 선언한 val1과 val2의 값을 swap의 a와 b가 받았습니다.

 

이 매개변수로 전달되는 값은 val1과 val2의 값을 복사해서 a와 b에 저장한 것입니다.

 

그러므로 val1과 val2는 swap내부의 a와 b와는 전혀 남남인 변수가 되는 것입니다.

 

복사를 했기 때문이지요.

 

swap함수 내에서 a와 b의 자리를 바꿨지만, main함수내의 val1과 val2의 저장된 값은

 

변경되지 않은 것입니다.

 

그래서 main의 printf를 호출하면 그대로 val1 = 10, val2 = 20이 출력됩니다.

 

 

Call-By-Reference 란?

 

Call-By-Value는 값을 전달했지만, Call-By-Reference는 주소를 전달합니다.

 

포인터를 아신다면 바로 이해되는 내용인데요,

 

& 연산자를 사용하여 주소를 전달하면, 그 해당하는 메모리의 값에 접근할 수 있습니다.

 

즉, 함수에 주소를 전달해서 함수 내부에서도 main의 실제 값에 접근하게 할 수 있다는 뜻입니다.

 

다시 정리하면, 값을 복사해서 함수에 전달하는 것이 아닌 주소를 전달해서

 

함수 내부에서도 그 주소의 값을 참조하게 할 수 있다는 소리죠.

 

설명이 잘 이해되지 않을 수 있으니,

 

위의 swap함수를 Call-By-Reference로 응용해보도록 하겠습니다.

 

 

int main(void){

 

int val1 = 10;

int val2 = 20;

 

printf("변경전 val1 : %d \n", val1);

printf("변경전 val2 : %d \n", val2);

 

swap(&val1, &val2); //&연산자를 이용, 주소를 swap에 전달

 

printf("변경후 val1 : %d \n", val1);

printf("변경후 val2 : %d \n", val2);

 

return 0;

}

 

void swap(int* a, int* b){ //주소를 가리킬 수 있도록 포인터 변수를 사용!!(중요합니다)

int temp = *a; //temp에 *a가 가리키고있는 값을 넣어라

*a = *b; //*a가 가리키고있는 값을 *b가 가리키고있는 값으로 변경해라

*b = temp; //*b가 가리키고있는 값을 temp의 값으로 변경해라

}

 

 

위의 코드에 달린 주석을 보시면 이해가 되시나요?

 

함수호출시 주소를 전달해주고, 함수 내부에서는 포인터 변수를 사용해서

 

main의 실제값을 가리키고 있는 것입니다.

 

그러므로 프로그래머가 원했던 main의 실제 값을 변경할 수 있는 프로그램이 된 것이죠.

 

swap함수 호출 후의 printf문에서는 실제로 그 출력 결과를 확인하실 수 있습니다.

Comments