제 32강) Call by ~

오늘은 "강의에서 다루지 않았던"의 두번째 시간입니다.

이번 시간에는 어떻게 보면 민감(?)하고 잘못된 설명들이 난무(?)하기도 하는 것을 다뤄보려고 합니다.

바로 Call By ~ 에 대해서 알아봅시다.



 1) Call by value

값을 직접 호출하는 방식을 "Call by value", 한국어로 "값에 의한 호출"이라고 합니다.

/* Call by value */
#include <stdio.h>
 
void printNum(int _num)
{
    printf("num: %d\n", _num);
}
 
int main(void)
{
    int num = 15;
    printNum(num);    // Call by value
    return 0;
}

위와 같이 직접 값(주소값이 아닌!!)을 전달하여 호출하는 것을 바로 "값에 의한 호출"이라고 합니다.

(printNum의 함수에 _num을 직접 값을 넣어서 호출)


이렇게 "값에 의한 호출"을 하게 되면 그 값은 "유지되지 않음"이 됩니다.

매개변수 인자로 값 그대로가 넘어가서 해당 프로시저의 내에서만 유효하게 되기 때문이죠.


C언어는 모든 호출을 "Call by value"로 합니다.

(ISO/IEC 9899:1999 6.5.2.2 Function calls, 4번 참조)



 2) Call by reference

"Call by reference" "참조에 의한 호출" 이라고 합니다.

위의 "Call by value"와는 다르게 값이 아닌 메모리 공간을 직접 참조합니다.

직접 해당 메모리 공간을 참조하여 사용하게 됩니다.


그런데 방금 "Call by value"에서 언급했듯이 C언어는 모든 호출이 "Call by value"입니다.

즉, C언어에서는 "Call by reference"라는 것이 없습니다.

이렇게 되면 바로 전에 배운 "스왑"에 대해서 의문을 가질 수 있습니다.

(31강 참조)

#include <stdio.h>
 
void swap(int* _num1, int* _num2)
{
    int tmp = *_num1;
    *_num1 = *_num2;
    *_num2 = tmp;
    printf("Swap!!\n");
}
 
int main()
{
    int num1 = 55, num2 = 13;
    printf("num1: %d(%p), num2: %d(%p)\n", num1, &num1, num2, &num2);
    swap(&num1, &num2);
    printf("num1: %d(%p), num2: %d(%p)\n", num1, &num1, num2, &num2);
 
    return 0;
}

스왑은 2가지의 인수가 들어와서 두 인수를 서로 바꾸는 기능을 합니다.


하지만 위에서 언급했듯이 기본적으로 "Call by value"는 값을 직접넣어서 호출하기 때문에 그 값은 유지되지 않는 것이 맞습니다.

그런데도 위의 "스왑"에서는 잘 바뀌었습니다.

원래 이렇게 바뀌는 것의 원리를 "Call by reference" 라고 합니다만, 위의 "스왑"은 "Call by reference"를 "흉내"낸것 즉, "구현"한것이라고 볼 수 있습니다.

그러므로 "Call by reference"는 아닙니다.

그 이유는 바로 C언어에서 포인터(주소)는 "Call by value"로 넘겨주기 때문입니다.

즉, _num1과 _num2의 주소가 value(값) 형태로 들어가게 됩니다.


고로 reference가 아닌 value가 됩니다.

이와 같이 포인터(주소)를 넘겨주는 것을 C언어에서는 "Call by Address"라고 표현하기도 합니다.



 다음 시간에는


또 다루지 않았던 것들을 가지고 찾아뵙겠습니다.

+ Recent posts