728x90

"Call by value"와 "call by reference"는 함수 호출 방식을 나타내는 용어

이 두 가지 방식의 주요 차이점: 함수에 인수를 전달하는 방법 & 함수가 인수를 처리하는 방법

 

1. Call by Value (값에 의한 호출):

  • 함수에 매개 변수로 ‘값’을 전달합니다.
  • 함수 내에서 매개 변수는 별도의 변수로 취급되며, 인수의 값이 복사되어 매개 변수에 저장됨
  • 따라서 함수 내에서 매개 변수의 값을 변경하더라도 호출자(caller/원본)의 변수는 영향을 받지 않음
  • C++에서 함수의 기본 호출 방식은 "call by value"
void modifyValue(int x) {
    x = x + 10;
}

int main() {
    int num = 5;
    modifyValue(num);
    std::cout << "num: " << num << std::endl; // 출력 결과: num: 5
    return 0;
}

 

2. Call by Reference (참조에 의한 호출):

 

"주소/참조 값을 전달받아서, 함수 외부에 선언된 변수직접 접근하는 형태의 함수 호출"

- 함수 입력으로 주소/참조 값이 전달되었다는 사실이 중요한 게 아니라

- 입력된 주소/참조 값을 통해 직접 외부 변수를 참조하여 모종의 행위(읽기/조작 등)을 했을 때 call-by-reference라 칭할 수 있음

  • 함수에 매개 변수로 ‘변수의 참조/주소’를 전달
  • 함수 내에서 매개 변수는 원래 변수와 동일한 메모리 위치를 참조하므로,
    함수에서 매개 변수를 수정하면 호출자(원본)의 변수가 직접 영향을 받음
  • C++에서는 매개 변수를 참조로 전달하려면 참조자(reference) 또는 포인터(pointer)를 사용해야 함

(1) 포인터 *를 활용 (주소)

void modifyValueByPointer(int* x) {
    *x = *x + 10;
}

int main() {
    int num = 5;
    modifyValueByPointer(&num);
    std::cout << "num: " << num << std::endl; // 출력 결과: num: 15
    return 0;
}

- 늘 느끼는 건데.. (?) 주소값은 메모리가 할당된 위치이고, 이 주소값 자체는 변하지 않고 고정됨.

반면, 해당 주소에 저장된 value 자체는 변형&조작의 대상이 됨.

 

- 단, 이하와 같은 방식으로, 포인터를 통해 value를 직접 조작하는 것을 막을 수 있다.

const int* ptr1 = &num; //ptr1를 이용해서 num의 value를 바꿀 수 없음 //*ptr1를 상수화시켰다는 의미

*주의할 점은, ptr = 2; ptr이 const 변수이기 때문에 컴파일 에러가 발생 하지만

 num = 2; num이 non-const 변수이기 때문에 정상이다. 즉, 포인터 변수가 가리키는 num 자체가 상수화가 되는 것이 아니다.

https://easycoding91.tistory.com/entry/C-%EA%B0%95%EC%A2%8C-const-%EC%9C%84%EC%B9%98%EC%9D%98-%EC%9D%98%EB%AF%B8%EC%99%80-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95

 

 

- (완전 별개의 이야기지만) 포인터 주소값 자체를 상수화시킬 수도 있다.

int* const ptr2 = &num; // num의 주소값인 ptr2 자체가 상수화됨

 

 

 

(2) 참조 &를 활용 (별명)

void modifyValueByReference(int& x) {
    x = x + 10;
}

int main() {
    int num = 5;
    modifyValueByReference(num);
    std::cout << "num: " << num << std::endl; // 출력 결과: num: 15
    return 0;
}

 

- int& x에서 &는 C++에서 "참조자"를 나타내는 연산자

- 자료형 바로 뒤에 &가 붙음!!! (변수명 앞에 &가 붙는 게 아니라 ~~~.)

- 참조자는 변수에 대한 별명(alias)이며, 원본 변수를 직접 참조하게 함.

이것은 값(value) 자체가 아니라 변수에 대한 참조(reference)를 함수에 전달함을 의미함

- int& x에서 x는 참조자의 이름이고, int는 참조할 변수의 데이터 타입을 나타냄 (int& x: "정수형 변수에 대한 참조를 받는다")

 

 

참조자를 사용할 때의 특징

  • 원본 변수의 별명: 참조자는 원본 변수의 별명으로 동작함, 따라서 참조자를 통해 값을 읽거나 수정하면 원본 변수에도 동일한 작업이 반영됨.
  • 포인터와 다른 점: 참조자 != 포인터.
    포인터는 메모리 주소를 저장하고 간접 참조를 통해 값을 읽고 쓰고 조작할 수 있지만,
    참조자는 변수에 직접적으로 연결되어 있으므로 포인터보다 사용하기 간편
  • 전달이 아닌 참조 전달: 함수에 참조자를 매개 변수로 전달하면 함수 내에서 원본 변수를 직접 조작할 있으며, 호출자의 변수도 변경됨( 성질은 포인터에서도 동일~)
728x90

+ Recent posts