Call by
Call by
함수를 호출할 때 넘겨주는 인자에 따라 Call by value, Call by Address, Call by Reference 세가지로 분류된다.
call by value
가장 기본적인 방법으로 함수를 호출해서 매개변수의 값을 복사해서 전달해주는 방식이다. 값을 복사? 그렇다.
Ex>int num1 = 10, num2 = 20;
Max(num1, num2);
위와 같이 num1과 num2라는 변수를 매개변수로 사용하면 num1과 num2라는 변수 자체가 가는 것이 아닌 안에 들어 있는 10, 20 이 두개의 값만이 전달 된다.
그렇다면 값만 전달되는 Call by value의 단점이나 문제점은 무엇이 있을까?
- 소스 코드 예시
void Inc(int a, int b);
int main()
{
1)int a, b;
cout << "숫자를 입력해주세요 :";
cin >> a;
cout << "입력한 값을 얼마만큼 증가시키겠습니까? :";
cin >> b;
2)Inc(a, b);
cout << "증가하여 " << a << "가(이) 되었습니다." << endl;
return 0;
}
3)void Inc(int a, int b)
{
4)a += b;
}
위와 같이 두 수를 입력한 후에 첫번째로 입력한 값에 두번째로 입력한 값을 더하는 함수를 만들었다. 결과는 어떻게 될까?
분명 a에 10을 넣고 b에 5를 넣었는데 a는 10이 되었다. 어떤 문제가 있을까?
1)번과 2)번은 동일한 a, b이다. 그렇다면 3)에 a,b나 4)번의 a, b와도 같을까? 전혀 다른 변수이다.
3)번의 a, b변수는 Inc()함수 안에서만 존재하는 변수이다. 단지 함수 호출시에 넘겨받은 인자 값을 a와 b라는 변수를 Inc함수 내에서 선언과 동시에 값을 받았을 뿐이다. 그래서 여기서 a에 b의 값을 더하더라도 main()함수에 있는 a에는 아무런 영향이 없는 것이다.
해결방법은 무엇일까? 해결방법은 결과 값을 반환 값으로 다시 넘겨주어 저장을 하는 방법이 있다. 허나 이 경우에도 문제가 있다. 반환 값은 단 한개의 값만 반환 할 수가 있다. 이 말은 위의 Inc()함수의 경우엔 a 하나의 변수만 변경하고자 했기때문에 반환 값으로 처리가 가능하다지만 여러개의 변수 값을 변경해야하는 경우는 어떻게 해야하는가?
이런 경우에 사용하는 것이 Call by Address, Call by Reference 이다.
Call by address
원래는 Call by Reference 하나였지만 c++에 있는 레퍼런스와 구분하고자 주소에 의한 참조. 포인터에 의한 참조가 Call by address로 따로 분류가 되었다.
위에 call by value의 문제점은 무엇이었는가? 매개변수로 사용한 변수 자체의 값을 변경할 수가 없다는 것이었다. 그렇다면 포인터를 사용하면 무엇이 달라는가?하는 의문이 생길 것이다.
- 소스 코드 예시
void Inc(int *a, int *b); // Call by Address이기때문에 포인터로 변경.
int main()
{
int a, b;
cout << "숫자를 입력해주세요 :";
cin >> a;
cout << "입력한 값을 얼마만큼 증가시키겠습니까? :";
cin >> b;
Inc(&a, &b); // 매개변수의 자료형이 int 포인터이기때문에 &연산자를 붙여줌.
cout << "증가하여 " << a << "가(이) 되었습니다." << endl;
return 0;
}
void Inc(int *a, int *b)
{
*a = *a + *b;
}
결과부터 확인하면 위와 같다. 어떻게 된 것일까? 이것도 엄연히 따지고 보면 주소 값을 복사해서 넘겨받은 것과 같다. 다만 주소 값을 따라 실제 a와 b를 참조하여 a의 값을 바꾸어준 것이다. 주소 값을 통해 참조하여 값을 변경하였기 때문에 Call by address라고 한다.
하지만 포인터를 사용한다고 해서 모두 Call by address가 될 수는 없다.
Ex> void Swap(int *a, int *b)
{
int *temp;
temp = a;
a = b; // a에 b의 주소 값을 넣음.
b = temp; // b에 a의 주소 값을 넣음.
}
위의 예시처럼 주소 값을 참조를 위한 도구가 아닌 값 자체로 사용하는 경우는 Call by value가 되며 a와 b의 값은 변하지 않는다. 참조하는데 사용하여야되는 점을 기억하자.
Call by reference
그렇다면 Call by reference는 무엇인가? call by reference는 레퍼런스에 의한 참조를 말한다.
- 소스 코드 예시
void Inc(int &a, int &b); // Call by reference이기때문에 레퍼런스로 변경.
int main()
{
int a, b;
cout << "숫자를 입력해주세요 :";
cin >> a;
cout << "입력한 값을 얼마만큼 증가시키겠습니까? :";
cin >> b;
Inc(a, b); // 레퍼런스이기때문에 변수명만 써주면 된다.
cout << "증가하여 " << a << "가(이) 되었습니다." << endl;
return 0;
}
void Inc(int &a, int &b)
{
a = a + b;
}
결과는 call by address와 동일하다. 레퍼런스 변수는 변수에 새로운 이름, 별명을 붙여서 같은 메모리를 바로 참조하는 것이라고 했었다. 그렇기 때문에 이는 직접적인 참조가 된다.
- 출처 : 열혈강의 C++ 언어본색
혼자 연구하는 C/C++ http://www.soenlab.com/
※ 공부한 내용을 정리하였기때문에 출처와 내용이 다를 수 있습니다.