在C ++函数参数中使用&运算符:pass-by-rvalue-reference [duplicate]

问题描述 投票:0回答:3

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

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

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

如果有人详细解释,将会有所帮助。谢谢。

c++ pass-by-reference pass-by-rvalue-reference
3个回答
1
投票

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

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

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

回到你的优秀例子,int &value描述了一个l值参考,因为value指的是内存中的一个位置。

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

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

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

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

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


0
投票

因为increase1引用了int,所以调用者会自动通过引用发送值。

通过引用函数发送值与发送指针相同,除了

  • 你不必拿地址;它知道自动完成
  • 您可以像使用常规变量一样使用引用
  • 假定引用不为空。这很有用,因为这意味着您不必在带引用的函数内进行空值检查。

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


0
投票

这是一个参考。

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

引用就像一个必须首先初始化并且不能更改的指针。但您可以更改该地址的值。声明之后你不需要在它之前放一个*。

正确的声明示例:int &a=b;现在使用它,你只需写一个。当你改变a时,b会发生同样的变化

© www.soinside.com 2019 - 2024. All rights reserved.