[c] C에서 참조로 전달

C가 참조로 변수 전달을 지원하지 않으면 왜 작동합니까?

#include <stdio.h>

void f(int *j) {
  (*j)++;
}

int main() {
  int i = 20;
  int *p = &i;
  f(p);
  printf("i = %d\n", i);

  return 0;
}

산출:

$ gcc -std=c99 test.c
$ a.exe
i = 21 



답변

포인터 의 값 을 메소드에 전달한 다음 참조하는 정수를 얻기 위해 역 참조하기 때문입니다.


답변

그것은 참조에 의한 전달이 아니며 다른 사람들이 언급 한 것처럼 값에 의한 전달입니다.

C 언어는 예외없이 가치를 전달합니다. 포인터를 매개 변수로 전달한다고해서 참조로 전달되는 것은 아닙니다.

규칙은 다음과 같습니다.

함수가 실제 매개 변수 값을 변경할 수 없습니다.


함수의 스칼라 매개 변수와 포인터 매개 변수의 차이점을 살펴 보겠습니다.

스칼라 변수

이 짧은 프로그램은 스칼라 변수를 사용하여 값별 패스를 보여줍니다. param공식 매개 변수라고 variable하며 함수 호출시 실제 매개 변수라고합니다. param기능의 증가 는 변하지 않습니다 variable.

#include <stdio.h>

void function(int param) {
    printf("I've received value %d\n", param);
    param++;
}

int main(void) {
    int variable = 111;

    function(variable);
    printf("variable %d\m", variable);
    return 0;
}

결과는

I've received value 111
variable=111

통과 기준의 환영

코드 조각을 약간 변경합니다. param포인터입니다.

#include <stdio.h>

void function2(int *param) {
    printf("I've received value %d\n", *param);
    (*param)++;
}

int main(void) {
    int variable = 111;

    function2(&variable);
    printf("variable %d\n", variable);
    return 0;
}

결과는

I've received value 111
variable=112

그러면 매개 변수가 참조로 전달되었다고 믿을 수 있습니다. 아니었다. 값으로 전달되었으며 param 값은 주소입니다. int 타입 값이 증가했고, 그것이 참조에 의한 함수 호출이라고 생각하게 만드는 부작용입니다.

포인터-값으로 전달

그 사실을 어떻게 증명 / 증명할 수 있습니까? 스칼라 변수의 첫 번째 예제를 시도해 볼 수 있지만 스칼라 대신 주소 (포인터)를 사용합니다. 그것이 도움이 될 수 있는지 봅시다.

#include <stdio.h>

void function2(int *param) {
    printf("param's address %d\n", param);
    param = NULL;
}

int main(void) {
    int variable = 111;
    int *ptr = &variable;

    function2(ptr);
    printf("ptr's address %d\n", ptr);
    return 0;
}

결과적으로 두 주소가 동일합니다 (정확한 값에 대해 걱정하지 마십시오).

결과 예 :

param's address -1846583468
ptr's address -1846583468

내 의견으로는 이것은 포인터가 가치에 의해 전달된다는 것을 분명히 증명합니다. 그렇지 않으면 ptrNULL함수 호출 후.


답변

C에서 참조로 전달은 변수 (포인터)의 주소를 전달하고 함수 내에서 해당 주소를 역 참조하여 실제 변수를 읽거나 쓰는 방식으로 시뮬레이션됩니다. 이것을 “C 스타일 패스 바이 레퍼런스”라고합니다.

출처 : www-cs-students.stanford.edu


답변

위 코드에는 참조로 전달이 없기 때문입니다. 포인터 (예 :)를 사용하면 void func(int* p)주소별로 전달됩니다. 이것은 C ++에서 참조로 전달됩니다 (C에서는 작동하지 않음).

void func(int& ref) {ref = 4;}

...
int a;
func(a);
// a is 4 now


답변

변수의 주소를 역 참조 연산자 를 사용하여 값을 조작하는 함수에 전달하기 때문에 예제가 작동합니다 .

C는 참조 데이터 유형을 지원하지 않지만 예제와 같이 포인터 값을 명시 적으로 전달하여 참조 별 전달을 시뮬레이션 할 수 있습니다.

C ++ 참조 데이터 유형은 강력하지 않지만 C에서 상속 된 포인터 유형보다 안전하다고 간주됩니다. 다음은 C ++ 참조 를 사용하도록 조정 된 예입니다 .

void f(int &j) {
  j++;
}

int main() {
  int i = 20;
  f(i);
  printf("i = %d\n", i);

  return 0;
}


답변

으로 포인터 (주소 위치) 를 전달합니다 .

“업데이트하고 싶은 데이터가있는 곳이 여기에 있습니다.”라고 말하는 것과 같습니다.


답변

p는 포인터 변수입니다. 그 값은 i의 주소입니다. f를 호출하면 i의 주소 인 p 의 값전달합니다 .