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
내 의견으로는 이것은 포인터가 가치에 의해 전달된다는 것을 분명히 증명합니다. 그렇지 않으면 ptr
될 NULL
함수 호출 후.
답변
C에서 참조로 전달은 변수 (포인터)의 주소를 전달하고 함수 내에서 해당 주소를 역 참조하여 실제 변수를 읽거나 쓰는 방식으로 시뮬레이션됩니다. 이것을 “C 스타일 패스 바이 레퍼런스”라고합니다.
답변
위 코드에는 참조로 전달이 없기 때문입니다. 포인터 (예 :)를 사용하면 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 의 값 을 전달합니다 .