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

tim*_*tim 55 c++ pointers function pass-by-reference

我输入以下示例:

#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;
}   
Run Code Online (Sandbox Code Playgroud)

在函数中,f我将x和y声明为指针,我可以通过使用获取值*x.在调用时f我需要传递我传递的参数的地址,这就是我通过的原因&a, &b.f2除了定义不同之外,它们是相同的.

现在我的问题是:它们在内存管理方面是否真的相同?两者都不是传递值的任何副本,而是传递引用?我想知道f2,因为我无法读出的地址xf2,所以我知道在更多关于x和y f(在那里我知道地址和值).

提前致谢!

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

指针与参考 还有一个链接到谷歌编码指南http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments这是useful我的感觉(我现在明白,这是一种主题品味的形式)更清楚

Ton*_*ion 56

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

const double& ref当你不打算更改函数内部的参数时,首选const引用()是首选,当你要更改它们时,使用非const引用.

当您需要能够传递NULL参数时,主要使用指针,显然,如果指针NULL在使用之前,您需要检查函数内部.

  • 好吧,如果需要,他们可能需要 **能够** 传递 null。显然,他们不会一直通过它。 (2认同)
  • 问:“指针和引用之间的区别是引用不能为 NULL”。最简单明了的答案,何时应该使用 * 与 &amp; 作为函数参数。别名永远不能为 NULL。 (2认同)

phi*_*lfr 14

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

  • 我个人认为这不仅仅是那个.它声明参数不能为空且不是可选的.使用指针你永远无法分辨,必须经常检查.通过引用,函数签名可以强制执行程序员的意图,并生成更清晰的代码,从而更准确地反映该意图. (9认同)

Dan*_*anS 10

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

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
Run Code Online (Sandbox Code Playgroud)

rY始终指向Y并且无法移动.

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


qua*_*ana 6

在我看来,函数的参数总是按值传递.通过一个int很容易想象,通过一个double更大,传递一个struct或者class可能非常大.
但是将指针传递给某个东西,好吧,你只是按值传递一个地址. (对于CPU来说,指针通常是一个方便的大小int.)
引用非常相似,当然我认为引用作为指针,但使用语法糖使它看起来像它所引用的对象已经通过按价值.

您还可以将引用视为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?
Run Code Online (Sandbox Code Playgroud)

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

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

void foo(int& i);

int* p = 0;
foo(*p);
Run Code Online (Sandbox Code Playgroud)

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

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

if (p) foo(*p);
Run Code Online (Sandbox Code Playgroud)