在C++中用 & 和 * 声明的函数参数之间的差异
Difference between function arguments declared with & and * in 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
,因为我无法读出f2
中x
的地址,所以我对f
中的 x 和 y 有了更多的了解(我知道地址和值(。
编辑:在做了更多的研究之后,我发现了一个非常有用的话题:
指针与引用还有一个指向谷歌编码指南的链接 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments 我觉得这很useful
(正如我现在所理解的,这是一种主题品味的形式(来更清楚地说明
f2
通过引用获取其参数,这本质上是您传递的参数的别名。 指针和引用之间的区别在于引用不能为 NULL。 使用f
,您需要将要传递的参数的地址(使用和运算符(传递给指针,当您通过引用传递时,您只需传递参数并创建别名。
当您不打算更改函数内的参数时,首选通过常量引用 (const double& ref
( 传递,当您要更改它们时,请使用非常量引用。
指针主要用于需要能够NULL
传递给参数时,显然您需要在函数内部检查指针是否在使用之前未NULL
。
语法糖,以避免每次引用参数时都必须使用*
。您仍然可以使用 &
在 f2
中拥有 x
的地址。
在我的脑海中,函数的参数总是按值传递的。 通过一个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?
因此,指针确实会加倍时间:它本身就是一个值,但是当您取消引用它时,它也可以指向另一个值,例如:*p
。
此外,具有引用参数意味着您无法让它们在函数的生存期内引用任何其他内容,因为无法表达这一点。
引用应该不能用null
初始化,但请考虑以下情况:
void foo(int& i);
int* p = 0;
foo(*p);
这意味着在使用指针之前应检查指针,但无法检查引用。 foo()
的实现可能会尝试读取或写入i
这将导致访问冲突。
在上面的示例中,指针p
在调用foo
之前应该已经检查:
if (p) foo(*p);
另一个未提及的区别是您无法更改引用的内容。这在原始问题中显示的函数调用示例中没有太大区别。
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
,无法移动。
引用不能用于索引到指针等简单数组中。
您应该能够在这两个函数中读取x
地址。
要在 f2
中这样做,您当然必须以&
作为x
前缀,因为在那里,x
是对双精度的引用,并且您想要一个地址。
引用和指针之间值得注意的区别是前者不能为 NULL。您必须传递某些内容(有效(,而在提供指针时,您必须在文档中指定是否允许/明确定义传递 NULL。
另一个区别是可读性问题:使用引用而不是指针(如果可能(使代码不那么混乱,*
和->
。
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 当从函数参数中的临时值调用复制构造函数时
- 如何从"decltype()"获取函数参数的数量<funtion>?
- 如何将lambda作为模板类的成员函数参数
- 模板参数推导失败,函数参数/参数不匹配
- 如何在C++中将迭代器作为函数参数传递
- 将函数参数"const char*"转换为"std::string_view"是
- C++ 如何将数组值解压缩为函数参数
- 主函数参数的属性
- 具有两个间接寻址运算符 (C++) 的函数参数的用途
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 如何定义在用作函数参数时工作的类模板的转换
- 将函数参数完美转发到函数指针:按值传递呢?
- 为什么我不能将引用作为 std::async 的函数参数传递
- 什么..(省略号)作为函数原型中唯一的函数参数,C++?
- 是否可以就地构造一个固定大小的数组作为函数参数?
- 接受模板作为函数参数
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- Arduino 函数参数