在C ++函数参数中使用&运算符:传递右值引用

时间:2019-03-27 03:24:18

标签: c++ pass-by-reference pass-by-rvalue-reference

我对这段代码片段感到惊讶!调用方正在传递值,但是函数如何处理其地址?

void increase1(int &value) {
   value++;
}

int main() {
   int number = 5;
   increase1(number);
}

如果有人详细解释会很有帮助。谢谢。

3 个答案:

答案 0 :(得分:1)

'increase1(int&value)`采用'l-value reference'。在C ++ 11之前,我们仅了解“引用”。所有参考都是l值。

什么是l值? l值的简化定义是编译器可以提供地址的内容。因此,诸如value之类的变量具有物理存储位置(假定尚未优化掉其存储位置)。

标量,例如5或什至两个变量之和,例如x + y没有内存位置。编译器不在内存中存储5。相反,它将5移动到number的存储位置。编译器不会将x + y存储为内存位置。同样,在简化的基础上,5是一个概念,而(x + y)是一个概念-这些是r值。对R值的引用是第二种引用类型[此处未讨论]。

回到您的出色示例,int &value描述了一个左值引用,因为value引用了内存中的位置。

main()函数(假设没有优化)

  1. number声明为int并分配编号的存储空间。在大多数32位和64位系统上,为数字分配了4个字节的内存。
  2. 5是R值。编译器创建一条移动指令以将5移至数字的存储位置。
  3. main()现在通过传递数字的存储位置来调用increase1()。该变量通过引用传递,这意味着地址被传递到increase1main()知道要传递地址,因为`increase1()采用了一个左值引用。
  4. increase1()接收数字的地址,然后对其进行解引用以获取5值,然后将一个数字添加到已解引用的指针中,然后将结果存储回寻址为number的位置。

L值引用允许被调用方函数直接修改调用方拥有的存储。

请注意,存储地址是传递的。地址可以来自main()的堆栈,也可以来自堆(由new分配)。在此示例中,main()从堆栈中分配number,但不必从堆栈中分配。

一种非常冗长的说法,即将使用地址传递l值引用,除非编译器认识到可以通过优化更快地完成它。但是,如果编译器优化了引用的实际传递,则逻辑理解仍然有效。

答案 1 :(得分:0)

由于increase1引用了int,因此调用方会自动通过引用发送该值。

通过引用发送值的功能与发送指针的功能相同,除了

  • 您不必填写地址;它知道会自动执行
  • 您可以像使用常规变量一样使用引用
  • 假定引用不为空。这很有用,因为这意味着您不必在接受引用的函数中进行空检查。

如果引用来自指针,请在将其转换为引用之前检查以确保指针不为null。如果您已经知道指针不为null,则不必检查(当然)。

答案 2 :(得分:0)

这是参考。

`int a;   //variable
int @a;  //reference
int *a;  //pointer`

参考就像一个指针,您必须先对其进行初始化并且不能更改。但是您可以更改该地址上的值。在声明之后,您不需要在其前面加上*。

权利声明示例:     int &a=b; 现在要使用它,您只需编写 a 。当您更改a时, b

也会发生相同的更改