Base

Pointer, Call by Reference, Call by Value

Dr.Mlem 2024. 9. 22. 23:33

Q1.

Call by reference, 포인터. 두 단어 사이의 관계는 어떤 관계야?



Call by reference포인터는 프로그래밍에서 밀접하게 연결된 개념이지만, 두 개념이 정확히 무엇인지 구분해서 이해하는 것이 중요합니다. 각각의 개념과 그 사이의 관계를 차근차근 설명해 드릴게요.

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

Call by reference는 함수를 호출할 때, 변수의 실제 주소(참조)를 넘겨주는 방식입니다. 이 방식으로 함수를 호출하면, 함수 안에서 매개변수를 통해 전달된 변수의 원본 값을 변경할 수 있습니다.

즉, 함수에서 매개변수로 받은 값을 수정하면, 원래 호출한 곳에서 사용한 변수의 값도 함께 변경됩니다.

예시 (C/C++):

cpp

void changeValue(int *num) {
    *num = 10;
}

int main() {
    int a = 5;
    changeValue(&a);  // 'a'의 주소를 전달함
    // a의 값이 10으로 바뀜
    return 0;
}

이 예시에서 changeValue 함수는 a 변수의 참조를 전달받아, 함수 내부에서 값을 변경하면 실제로 main 함수의 a의 값이 변경됩니다.

핵심 개념:

  • Call by reference 방식에서는 함수에 전달된 원본 값이 직접 수정됨.
  • 이 방식은 참조나 포인터를 사용하여 구현됨.

2. 포인터 (Pointer)

포인터메모리 주소를 저장하는 변수입니다. 즉, 포인터는 다른 변수의 값을 가리키거나 참조하는 데 사용됩니다. 포인터를 이용하면 특정 메모리 위치의 값을 직접 변경할 수 있습니다.

포인터를 사용해 함수를 호출할 때는 보통 Call by reference 방식으로 동작하게 됩니다. 왜냐하면 포인터를 통해 변수의 주소(참조)를 전달하고, 이를 이용해 원본 변수를 수정할 수 있기 때문입니다.

예시 (C/C++):

cpp

 

void changeValue(int *num) {
    *num = 10;
}

int main() {
    int a = 5;
    changeValue(&a);  // 'a'의 주소를 전달함
    // a의 값이 10으로 바뀜
    return 0;
}

이 코드에서 &a는 변수 a의 주소를 전달하고, 포인터 num은 그 주소를 가리킵니다. 따라서 포인터를 통해 원본 변수 a의 값을 수정할 수 있습니다.

핵심 개념:

  • 포인터는 변수의 메모리 주소를 저장하는 변수.
  • 포인터는 다른 변수의 값을 간접적으로 수정하는 데 사용됨.

3. Call by Reference와 포인터의 관계

Call by reference포인터를 이용해 구현되는 경우가 많습니다. 특히 C/C++에서는, 포인터를 사용하여 변수를 참조하고 그 값을 변경할 수 있는 방식이 call by reference의 기본 메커니즘입니다.

즉, Call by reference는 함수를 호출할 때 원본 변수의 값을 수정할 수 있도록 변수의 주소를 넘겨주는 방식이고, 포인터는 이런 참조를 가능하게 해주는 도구입니다.

관계 요약:

  • 포인터는 변수를 참조(주소)하는 방법을 제공하는 도구.
  • Call by reference는 함수 호출 시 원본 변수의 주소(참조)를 전달하여, 그 변수를 직접 수정할 수 있게 하는 호출 방식.
  • Call by reference는 내부적으로 포인터를 사용하여 구현되는 경우가 많음.

4. Call by Reference와 포인터의 차이

둘의 차이점은 개념적 레벨에 있습니다:

  • Call by reference는 함수 호출 방식에 대한 개념입니다. 이 방식에서는 변수의 주소가 전달되어, 함수가 직접 원본 변수에 접근하고 수정할 수 있게 됩니다.
  • 포인터는 단순히 메모리 주소를 저장하고, 그 주소에 있는 값을 참조하거나 변경하는 데 사용되는 변수입니다.

따라서 포인터는 call by reference를 구현하는 데 사용될 수 있는 기술적인 도구 중 하나입니다.

추가 예시: 참조 vs 포인터 (C++에서의 참조)

C++에서는 참조(Reference)와 포인터를 구분합니다. 포인터는 메모리 주소를 저장하는 변수로 간접 참조가 가능하고, 참조는 특정 변수의 별명(alias)처럼 작동합니다.

예시 (참조 vs 포인터):

cpp

 
int a = 5;
int &ref = a;  // 참조: ref는 a의 또 다른 이름
int *ptr = &a; // 포인터: ptr은 a의 주소를 가리킴
  • ref는 변수 a의 참조입니다. ref를 통해 a에 바로 접근하고 수정할 수 있습니다.
  • ptr은 a의 주소를 저장하는 포인터입니다. 포인터는 *ptr을 사용하여 a에 접근하고 수정할 수 있습니다.

결론

  • Call by reference는 함수를 호출할 때 원본 변수의 주소를 전달해 변수를 직접 수정하는 방식입니다.
  • 포인터는 변수의 메모리 주소를 저장하는 변수로, 원본 데이터를 간접적으로 수정하는 데 사용할 수 있습니다.
  • Call by reference는 종종 포인터를 사용하여 구현됩니다.

 

 

Q2.
call by value는 call by reference랑 어떤 차이야?



Call by valueCall by reference는 함수에 인자를 전달할 때 사용하는 두 가지 주요 방식입니다. 이 방식들은 함수가 매개변수를 처리하는 방법과, 함수 호출 후에 원본 변수에 미치는 영향에 차이가 있습니다. 두 개념의 차이를 하나씩 설명해 보겠습니다.

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

Call by value 방식에서는 값 자체를 함수에 전달합니다. 즉, 함수에 인자로 넘겨준 변수의 복사본이 만들어져 함수에 전달되며, 함수는 이 복사본을 사용하여 연산을 수행합니다. 원본 변수는 절대 변경되지 않습니다.

주요 특징:

  • 함수에 복사본을 전달하므로, 함수가 해당 매개변수의 값을 변경해도 원본 변수에는 아무런 영향이 없습니다.
  • 원본 변수와 함수 내부에서 사용하는 매개변수는 서로 다른 메모리 공간을 사용합니다.

예시 (C/C++):

cpp
 

void modifyValue(int num) {
    num = 10;  // 복사된 'num'의 값을 변경, 원본 변수는 변경되지 않음
}

int main() {
    int a = 5;
    modifyValue(a);  // 'a'의 복사본이 전달됨
    // 'a'는 여전히 5임
    return 0;
}

위 예시에서 modifyValue 함수는 a의 복사본을 받아서 사용합니다. 함수 내부에서 num의 값을 10으로 바꾸더라도, 원본 변수 a는 그대로 5로 유지됩니다.

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

반면에 Call by reference변수의 주소 또는 참조를 함수에 전달합니다. 즉, 함수에 인자로 전달된 변수의 원본 값에 직접 접근하고 수정할 수 있게 됩니다. 함수가 매개변수를 통해 값을 변경하면, 그 변경 사항은 원본 변수에도 즉각 반영됩니다.

주요 특징:

  • 함수는 변수의 주소를 받으므로, 원본 변수를 직접 수정할 수 있습니다.
  • 함수 내부에서 사용하는 매개변수와 원본 변수는 같은 메모리 공간을 사용합니다.

예시 (C/C++):

cpp
 

void modifyValue(int &num) {  // 참조로 받음
    num = 10;  // 원본 변수의 값이 변경됨
}

int main() {
    int a = 5;
    modifyValue(a);  // 'a'의 참조를 전달함
    // 'a'는 10으로 변경됨
    return 0;
}

위 코드에서는 modifyValue 함수가 변수 a의 참조를 받아서, 함수 내부에서 값을 변경하면 원본 변수 a의 값이 10으로 변경됩니다.

3. Call by Value vs Call by Reference: 차이점

특징Call by ValueCall by Reference

전달 방식 변수의 을 복사하여 함수에 전달 변수의 주소 또는 참조를 전달
원본 변수에 미치는 영향 함수가 변수의 값을 변경해도 원본 변수는 영향 없음 함수가 변수의 값을 변경하면 원본 변수도 변경됨
메모리 사용 함수 내에서 매개변수의 복사본이 생성됨 원본 변수와 같은 메모리 공간을 사용
주 용도 함수가 원본 값을 변경할 필요가 없을 때 사용 함수가 원본 값을 직접 변경해야 할 때 사용

4. Call by Value와 Call by Reference의 비교: 예시

Call by Value 예시:

cpp
 
 
void modifyValue(int num) {
    num = 20;  // 'num'의 복사본을 변경
}

int main() {
    int x = 10;
    modifyValue(x);  // 'x'의 복사본이 전달됨
    // 'x'의 값은 여전히 10
    return 0;
}

위 코드에서는 modifyValue 함수는 x의 복사본을 받아서 20으로 변경하지만, 함수가 끝난 후 x는 여전히 10으로 남아 있습니다.

Call by Reference 예시:

cpp
 

void modifyValue(int &num) {
    num = 20;  // 원본 변수의 값이 변경됨
}

int main() {
    int x = 10;
    modifyValue(x);  // 'x'의 참조를 전달함
    // 'x'의 값은 20으로 변경됨
    return 0;
}

이 코드에서는 modifyValue 함수가 x의 참조를 받습니다. 함수가 끝난 후 x의 값이 20으로 변경됩니다.

5. 언어별 차이

  • C/C++: 두 방식 모두 명시적으로 사용할 수 있습니다. Call by value는 기본적으로 모든 함수 호출에 적용되며, Call by reference는 포인터나 **참조(Reference)**를 사용해서 구현됩니다.
  • Java: Java는 Call by value 방식만 지원합니다. 하지만, Java에서 객체를 전달할 때는 객체의 참조 값이 복사되기 때문에, 객체의 내부 상태는 변경될 수 있지만 참조 자체는 바뀌지 않습니다. 즉, Java는 엄밀히 말하면 참조에 의한 값 전달 (Call by value of reference) 방식을 사용합니다.
  • Python: Python은 객체에 대한 참조를 전달하는 방식으로 동작합니다. 따라서 변경 가능한 객체(예: 리스트, 딕셔너리 등)를 함수에 전달하면 원본이 수정될 수 있습니다. 하지만 변경 불가능한 객체(예: 정수, 문자열 등)는 Call by value처럼 동작합니다.

6. 결론

  • Call by value는 변수의 복사본을 전달하여 함수가 그 복사본을 수정하더라도 원본 변수는 영향을 받지 않는 방식입니다.
  • Call by reference는 변수의 주소나 참조를 전달하여 함수가 원본 변수를 직접 수정할 수 있는 방식입니다.

두 방식은 함수가 매개변수를 어떻게 처리하고, 호출한 곳에 어떤 영향을 미칠지에 따라 사용됩니다. Call by value는 원본 데이터의 안전성을 보장하며, Call by reference는 성능적으로 더 효율적일 수 있지만, 원본 데이터가 수정될 수 있다는 위험이 있습니다.

'Base' 카테고리의 다른 글

IS A 관계  (0) 2024.09.23
클래스 다이어그램에서 리턴타입 void의 생략  (0) 2024.09.23
점화식  (0) 2024.09.23
변수의 선언, 변수의 초기  (0) 2024.09.19
다중 대입 연산자  (1) 2024.09.16