C ++에서 & 및 *로 선언 된 함수 인수의 차이점
다음 예를 입력했습니다.
#include <iostream>
double f(double* x, double* y)
{
std::cout << "val x: " << *x << "\n";
std::cout << "val y: " << *y << "\n";
return *x * *y;
}
double f2(double &x, double &y)
{
std::cout << "val x: " << x << "\n";
std::cout << "val y: " << y << "\n";
return x * y;
}
int main()
{
double a, b;
a = 2;
b = 3;
std::cout << f(&a, &b) << "\n";
std::cout << f2(a, b) << "\n";
return 0;
}
함수에서 f
x와 y를 사용하여 값을 얻을 수있는 포인터로 선언 *x
합니다. 호출 할 때 f
전달 된 인수의 주소를 전달해야하므로 &a, &b
. f2
정의가 다른 것을 제외하고는 동일합니다.
이제 내 질문은 다음과 같습니다. 메모리 관리와 관련하여 둘 다 실제로 동일합니까? 둘 다 전달 된 값의 복사본을 만들지 않고 대신 참조를 전달합니까? 내가 궁금해 f2
내가의 주소를 읽을 수 있기 때문 x
에 f2
내가 그렇게 알고 더 x와 y에 대한의 f
(I 주소와 값이 알고있다).
미리 감사드립니다!
편집 : 감사합니다. 더 많은 조사를 한 후 매우 유용한 주제를 찾았습니다.
포인터 대 참조 Google 코딩 가이드 라인 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments에 대한 링크도 있습니다. 이것은 useful
제가 지금 이해했듯이 주제 취향의 한 형태입니다. ) 더 명확하게
f2
참조로 인수를 가져 오는 것입니다. 이는 본질적으로 전달하는 인수 의 별칭 입니다. 포인터와 참조의 차이점은 참조가 NULL 일 수 없다는 것입니다. 와 함께 포인터에 전달하는 매개 변수 f
의 주소 (& 연산자 사용)를 전달해야합니다. 참조로 전달할 때 매개 변수를 전달하면 별칭이 생성됩니다.
const double& ref
함수 내에서 인수를 변경하지 않을 때는 const 참조 ( )로 전달하는 것이 선호되고, 인수를 변경할 때는 상수가 아닌 참조를 사용합니다.
포인터는 NULL
매개 변수 에 전달할 수 있어야 할 때 주로 사용되며 , 포인터가 NULL
사용하기 전에 없는 경우 함수 내부를 확인해야 합니다.
이것은 *
인수를 참조 할 때마다 사용할 필요가 없도록하기위한 구문상의 설탕 일뿐 입니다. 당신은 여전히 사용할 수 &
의 주소를 가지고 x
있는이 f2
.
언급되지 않은 또 다른 차이점은 참조가 참조하는 것을 변경할 수 없다는 것입니다. 이것은 원래 질문에 표시된 함수 호출 예제에서 많은 차이를 만들지 않습니다.
int X(10), Y(20);
int *pX = X;
int& rY = Y;
*pX = 15; // change value of X
rY = 25; // change value of Y
pX = Y; // pX now points to Y
rY
항상 가리키고 Y
이동할 수 없습니다.
참조는 포인터와 같은 간단한 배열로 인덱싱하는 데 사용할 수 없습니다.
In my head, parameters of functions are always passed by value. Passing an int
is easy to imagine, passing a double
is just bigger and passing a struct
or class
could be very big indeed.
But passing a pointer to something, well, you're just passing an address by value. (A pointer is often a convenient size for the CPU just like an int
.)
A reference is very similar, and certainly I think of a reference as a pointer, but with syntactic sugar to make it look like the object its referring to has been passed by value.
You can also think of a reference as a const
pointer, ie:
int i;
int j;
int* p = &i; // pointer to i
int* const cp = p; // cp points to i, but cp cannot be modified
p = &j; // OK - p is modified to point to j
*cp = 0; // OK - i is overwritten
cp = &j; // ERROR - cp cannot be modified
int& ri = i; // ri refers to i
ri = 1; // i is overwritten
ri = j; // i is overwritten again
// Did you think ri might refer to j?
So, a pointer does double time: It is a value in its own right, but it can also point to another value when you dereference it, eg: *p
.
Also, having reference parameters means that you cannot make them refer to anything else during the lifetime of the function because there's no way to express that.
A reference is supposed not to be able to be initialised with null
, but consider this:
void foo(int& i);
int* p = 0;
foo(*p);
This means that pointers should be checked before you use them, but references cannot be checked. The implementation of foo()
could try to read from or write to i
which will cause an access violation.
In the above example the pointer p
should have been checked before being used in the call to foo
:
if (p) foo(*p);
You should have been able to read x
address in both functions.
To do so in f2
, you must of course prefix x
by a &
since there, x
is a reference to a double, and you want an address.
A worth noticing difference between references and pointers is that the former cannot be NULL. You must pass something (valid) while when providing a pointer, you must specify in the documentation if passing NULL is allowed/well defined.
Another difference is a matter of readability: using references instead of pointers (when possible) makes the code less cluttered with *
and ->
.
ReferenceURL : https://stackoverflow.com/questions/5816719/difference-between-function-arguments-declared-with-and-in-c
'Nice programing' 카테고리의 다른 글
WPF 용 Visual Studio 디자이너를 수동으로 다시로드하는 방법 (0) | 2021.01.07 |
---|---|
MySQL : 싫어요 (0) | 2021.01.07 |
전화 시간이 아닌 "네트워크"시간 ( "네트워크 제공 값 사용"이라는 "자동"설정에서)을 어떻게 얻을 수 있습니까? (0) | 2021.01.07 |
Firefox에서 스크롤바를 숨기는 방법? (0) | 2021.01.07 |
목록 멤버 노출을위한 IEnumerable vs IReadonlyCollection vs ReadonlyCollection (0) | 2021.01.07 |