我对这段代码片段感到有点惊讶!调用者正在传递值,但函数如何处理其地址?
void increase1(int &value) {
value++;
}
int main() {
int number = 5;
increase1(number);
}
如果有人详细解释会很有帮助。谢谢你。
我对这段代码片段感到有点惊讶!调用者正在传递值,但函数如何处理其地址?
void increase1(int &value) {
value++;
}
int main() {
int number = 5;
increase1(number);
}
如果有人详细解释会很有帮助。谢谢你。
'increase1(int& value)` 采用“左值参考”。在 C++11 之前,我们只了解了“引用”。所有参考均指向 l 值。
什么是左值?左值的简化定义是编译器可以提供地址的东西。所以,一个变量,例如value
,有一个物理存储位置(假设它的内存位置没有被优化掉)。
一个标量,如 5 甚至两个变量之和,例如x + y
没有内存位置。编译器不会将 5 存储在内存中。相反,它将 a 移动5
到 的存储位置number
。编译器不存储x + y
为内存位置。同样,在简化的基础上,5
是一个概念, (x + y) 是一个概念——这些是 r 值。对 R 值的引用是第二种类型的引用 [此处不讨论]。
回到您的出色示例,int &value
描述了一个左值引用,因为value
它指的是内存中的一个位置。
main() 函数(假设没有优化)
number
为 int 并为数字分配存储。在大多数 32 位和 64 位系统上,为数字分配 4 个字节的内存。5
到数字的内存位置。main()
increase1()
现在通过传递数字的存储位置来调用。变量是通过引用传递的,这意味着地址被传递给increase1
. main()
知道传递地址,因为 `increase1() 采用左值引用。increase1()
接收 number 的地址并将其取消引用以获得 5 值,将取消引用的指针加 1,然后将结果存储回寻址为 的位置number
。L 值引用允许被调用函数直接修改调用者拥有的存储。
请注意,存储地址是传递的。地址可以来自 main() 的堆栈,也可以来自堆(由 new 分配)。在示例中, main()number
从堆栈中分配,但不必从堆栈中分配。
一种非常冗长的说法,即使用地址传递左值引用,除非编译器认识到它可以通过优化更快地做到这一点。如果编译器优化了引用的实际通道,那么逻辑理解仍然有效。
这是一个参考。
`int a; //variable
int @a; //reference
int *a; //pointer`
引用就像一个指针,必须先初始化并且不能更改。但是您可以更改该地址的值。在声明之后,您不需要在它前面加上 *。
正确的声明示例:
int &a=b;
现在要使用它,您只需编写一个. 而当你改变a时, b也会发生同样的变化
因为increase1
需要引用 an int
,所以调用者会自动通过引用发送值。
通过引用发送值的功能与发送指针相同,除了
如果引用来自指针,请在将其转换为引用之前检查以确保指针不为空。如果您已经知道指针不为空,那么您不必检查(当然)。