본문 바로가기
CS

[CS] Call By Value와 Call By Reference (값에 의한 호출, 참조에 의한 호출)

by 워뇨옹2 2021. 9. 30.
728x90
반응형

Call By Value

아마 프로그래밍을 배우게 된다면, 처음으로 접하는 컴퓨터 공학 지식이 될 것이다.

나도 대학교 1학년 첫 언어인 C언어를 배우며 접하게 되었다.

 

간단한 예시를 보자.

int main() {
    int a = 10;
    int b = 5;
    
    swap(a,b);
    printf("a = %d", a);
    printf("b = %d", b);
    return 0;
}

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

 

대표적인 Call By Value에 대한 예제이다. (언어를 바꿔도 결과는 같다.)

a와 b에 각각 값을 할당해주고, swap이라는 함수를 통해 두 변수의 값을 바꿔준다.

그리고 a와 b를 출력해보자.

a = 5, b = 10이 나올거라 기대하지만, a = 10, b = 5로 값은 변하지 않는다.

 

분명 함수에 두개의 변수를 제대로 넘겨줬고, temp까지 사용해 a의 값과 b의 값을 바꿔줬는데?

왜 값이 바뀌지 않을까?

 

결론부터 말하자면, swap에서 사용하는 a와 b는 main에서 사용하는 a와 b가 아니다.

swap에서의 a는 main에서 넘겨온 a의 '값을' 복사만한다. (b도 마찬가지이다.)

 

이렇게만 말해서는 아직 감이 안잡힐수도 있다. 때문에 예시를 들어보겠다.

 

직원A(main)가 보고서 두개(a,b)를 인쇄할 일이 생겼다.

지금은 바쁘기 때문에 부하직원B(swap)에게 보고서(a, b)를 대신 인쇄해달라했다.

두 개의 보고서 날짜가 바뀌어있기 때문에, 보고서의 날짜를 제대로 수정해서 출력하라고 지시헀다.

 

이 때, 직원A는 보고서 원본 파일을 넘겨주지 않고, 복사한 보고서(swap의 a, b) 파일들을 넘겨주었다.

부하직원B는 보고서의 복사본 날짜를 제대로 수정한 뒤 출력하여 A에게 넘겨주었다.

 

이처럼 존재하는 변수 '자체'를 넘겨주는 것이 아니라, 변수의 '값'을 넘겨주어 함수를 실행하는 것이다.

직원A는 보고서의 내용을 정확하게 넘겨주었지만, 원본 보고서 파일은 수정되지 않았기 때문에 

부하직원B가 날짜를 수정해서 저장해놓았더라도, 원본 파일의 날짜는 바뀌지 않는 것이다.

 

이렇게 값에 의해 호출하는 것을 Call By Value라고 한다.

 

그렇다면 위 예시에서 원본 파일을 넘겨주는 건? 

그렇다. 변수 자체를 넘겨주는 Call By Reference가 된다.

 

Call By Reference

정확히는 변수가 참조하고 있는 주소를 넘겨주는 것이다.

위의 코드처럼 int a = 10; 이라고 선언하는 순간, a는 컴퓨터 메모리 어딘가에 저장이 된다.

그 메모리 주소를 swap에게 넘겨준다면 값을 복사하지 않고, 곧장 a가 있는 메모리 구역에 가서

a를 제어할 것이다.

 

C에서의 코드는 다음과 같다.

int main() {
    int a = 10;
    int *ptrA = &a;
    
    int b = 5;
    int *ptrB = &b;
    
    swap(ptrA,ptrB);
    printf("a = %d", *ptrA);
    printf("b = %d", *ptrB);
    return 0;
}

void swap(int *ptrA, int *ptrB) {
    int temp = *ptrA;
    *ptrA = *ptrB;
    *ptrB = temp;
}

코린이들이 제일 많이 코딩을 포기하는 포인터가 나왔지만, 신경쓰지 않아도 된다.

어차피 C개발자는 안할거잖아.

 

위와 같이 ptrA, ptrB라는 포인터 변수를 만들어 a, b의 주소값을 담아준다.

그 후, swap 함수에 포인터 변수를 넘겨주면 ptrA, ptrB 자체의 값이 변하게 된다.

 

때문에 main함수에서 포인터 변수들의 값을 출력하면 

a = 5, b = 10이 출력이 되는 것이다.

 

보고서의 예를 다시 들어보자면 다음과 같다.

 

직원A(main)가 보고서 두개(a,b)를 인쇄할 일이 생겼다.

지금은 바쁘기 때문에 부하직원B(swap)에게 보고서(a, b)를 대신 인쇄해달라했다.

두 개의 보고서 날짜가 바뀌어있기 때문에, 보고서의 날짜를 제대로 수정해서 출력하라고 지시헀다.

 

이 때, 직원A는 보고서 원본 파일이 존재하는 폴더의 위치(ptrA, ptrB)를 알려주었다.

부하직원B는 알려준 위치로 접속하여 보고서 원본파일의 날짜를 제대로 수정하고 출력하여

직원A에게 넘겨주었다.

 

아까와는 다르게 직원A는 보고서를 넘겨줄 때, 원본 파일이나 복사본을 넘겨준게 아니라 파일이 존재하는

폴더의 위치를 넘겨주었다. 이를 통해 부하직원B는 그 경로로 들어가 작업을 하고, 결과적으로 원본 파일이

바뀌게 되는 것이다.

 

한마디로 메모리에 할당된 주소를 넘겨주고, 그 주소를 따라들어가 변수를 조작하는 것이다.

 

이 정도로 Call By Value와 Call By Reference를 알아보았다.

예시에는 C언어를 썼지만, 어떤 언어를 사용하던 알아야하는 기초적인 CS지식이다.

 

모든 변수를 포인터화 할 수 있는 C, C++과는 다르게, 메모리에 직접적으로 관여할 수 없는 다른 언어들은

기본 자료형, 참조 자료형에 따라 Call By Value, Call By Reference가 결정된다.

 

기본 자료형으로는 int, float, character, boolean 등이 있는데, 자세한 건 다음에 또 작성해봐야겠다.

 

무엇보다 원리를 정확히 알고 있으면, 언어가 달라져도 Call By Value와 Call By Reference를 구분하고

원하는 기능을 제대로 구현할 수 있을 것이다.

728x90
반응형

'CS' 카테고리의 다른 글

[Computer Science] 비동기 프로그래밍이란? with Thread  (0) 2021.09.24