C++中用&和*声明的函数参数的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5816719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:56:16  来源:igfitidea点击:

Difference between function arguments declared with & and * in C++

c++functionpointerspass-by-reference

提问by tim

I typed the following example:

我输入了以下示例:

#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;
}   

In the function fI declare x and y as pointers of which I can get the value by using *x. When calling fI need to pass the address of my passed arguments, that is why I pass &a, &b. f2is the same except the definition is different.

在函数中,f我将 x 和 y 声明为指针,我可以使用*x. 调用时f我需要传递我传递的参数的地址,这就是为什么我通过&a, &b. f2除了定义不同,其他都是一样的。

Now my question is: Are they both really the same concerning memory management? Both not making any copy of the passed value but instead passing a reference? I wonder about f2because I couldn't read out the address of xin f2so I knowmore about x and y in f(there I know address AND value).

现在我的问题是:它们在内存管理方面真的一样吗?两者都没有复制传递的值而是传递引用?我想知道,f2因为我无法读出xin的地址,f2所以我对 x 和 y了解更多f(我知道地址和值)。

Thanks in advance!

提前致谢!

Edit: Okay thanks, after doing some more research, I found a quite useful topic:

编辑:好的,谢谢,经过更多研究,我发现了一个非常有用的主题:

Pointer vs. ReferenceThere's also a link to google coding guidelines http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Argumentswhich is quite usefulI feel (as I understood now, it's a form of subject taste) to make more clear

指针与参考还有一个链接到谷歌编码规则http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments这是相当useful我觉得(我现在明白,它是主体味道形式) 更清楚

采纳答案by Tony The Lion

f2is taking it's arguments by reference, which is essentially an aliasfor the arguments you pass. The difference between pointer and reference is that a reference cannot be NULL. With the fyou need to pass the address(using & operator) of the parameters you're passing to the pointer, where when you pass by reference you just pass the parameters and the alias is created.

f2通过引用获取它的参数,这本质上是您传递的参数的别名。指针和引用的区别在于引用不能为 NULL。随着f你需要通过地址你传递指针,就是当你通过引用传递,你只是传递的参数和创建别名的参数(使用和运营商)。

Passing by const reference (const double& ref) is preferred when you are not going to change the arguments inside the function, and when you are going to change them, use non-const reference.

const double& ref当您不打算更改函数内部的参数时,首选通过 const 引用 ( )传递,并且当您打算更改它们时,请使用非常量引用。

Pointers are mostly used when you need to be able to pass NULLto your parameters, obviously you'd need to check then inside your function if the pointer was not NULLbefore using it.

当您需要能够传递NULL给您的参数时,通常会使用指针,显然您需要在函数内部检查指针是否NULL在使用之前没有。

回答by philfr

This is just syntactic sugar to avoid having to use *everytime you reference the argument. You still can use &to have the address of xin f2.

这只是避免*每次引用参数时都必须使用的语法糖。您仍然可以使用in&的地址。xf2

回答by DanS

Another difference that hasn't been mentioned is that you cannot change what a reference refers to. This doesn't make a lot of difference in the function call example shown in the original question.

另一个未提及的区别是您无法更改引用所指的内容。这在原始问题中显示的函数调用示例中没有太大区别。

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

rYalways points to Yand cannot be moved.

rY始终指向Y且不能移动。

References can't be used to index into simple arrays like pointers.

引用不能用于索引像指针这样的简单数组。

回答by quamrana

In my head, parameters of functions are alwayspassed by value. Passing an intis easy to imagine, passing a doubleis just bigger and passing a structor classcould 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.

在我看来,函数的参数总是按值传递。传递 anint很容易想象,传递 adouble只是更大,传递 astructclass确实可能非常大。
但是传递指向某物的指针,好吧,您只是按值传递地址(对于 CPU 而言,指针通常是一个方便的大小,就像int.)
引用非常相似,当然我认为引用是一个指针,但使用语法糖使其看起来像它所指的对象已经被传递按价值。

You can also think of a reference as a constpointer, ie:

您也可以将引用视为const指针,即:

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.

因此,指针会加倍时间:它本身就是一个值,但是当您取消引用它时,它也可以指向另一个值,例如:*p
此外,拥有引用参数意味着你不能让它们在函数的生命周期内引用任何其他东西,因为没有办法表达它。

A reference is supposed not to be able to be initialised with null, but consider this:

一个引用应该不能用 初始化null,但考虑一下:

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 iwhich will cause an access violation.

这意味着在使用指针之前应该检查指针,但不能检查引用。的实现foo()可能会尝试读取或写入i将导致访问冲突。

In the above example the pointer pshouldhave been checked before being used in the call to foo:

在上面的例子中,在调用之前p应该检查过指针foo

if (p) foo(*p);

回答by ereOn

You should have been able to read xaddress in both functions.

您应该能够x在这两个函数中读取地址。

To do so in f2, you must of course prefix xby a &since there, xis a referenceto a double, and you want an address.

要在 中这样做f2,您当然必须x以 a 作为前缀,&因为那里x是对双精度的引用,并且您需要一个address

A worth noticing difference between references and pointers is that the former cannot be NULL. You mustpass something (valid) while when providing a pointer, you must specify in the documentation if passing NULL is allowed/well defined.

引用和指针之间值得注意的区别是前者不能为 NULL。在提供指针时,您必须传递一些东西(有效),如果允许/明确定义传递 NULL,则必须在文档中指定。

Another difference is a matter of readability: using references instead of pointers (when possible) makes the code less cluttered with *and ->.

另一个区别是可读性问题:使用引用而不是指针(如果可能)可以减少代码的混乱*->