什么是int&mean

Alf*_*ong 18 c++ types pointers

一个C++问题,

我知道

int* foo(void)
Run Code Online (Sandbox Code Playgroud)

foo将返回一个指向int类型的指针

怎么样

int &foo(void)
Run Code Online (Sandbox Code Playgroud)

什么回来了?

非常感谢!

Cam*_*ner 37

它返回对int 的引用.引用类似于指针,但有一些重要的区别.我建议你阅读指针,引用,对象和原始数据类型之间的差异.

"有效的C++"和"更有效的C++"(均由Scott Meyers提供)对差异以及何时使用指针与引用有一些很好的描述.

编辑:有许多答案说"引用只是语法糖,更容易处理指针".他们当然不是.

请考虑以下代码:

int a = 3;
int b = 4;
int* pointerToA = &a;
int* pointerToB = &b;
int* p = pointerToA;
p = pointerToB;
printf("%d %d %d\n", a, b, *p); // Prints 3 4 4
int& referenceToA = a;
int& referenceToB = b;
int& r = referenceToA;
r = referenceToB;
printf("%d %d %d\n", a, b, r); // Prints 4 4 4
Run Code Online (Sandbox Code Playgroud)

该行p = pointerToB改变了值p,即它现在指向不同的内存.

r = referenceToB做一些完全不同的事情:它将值分配给b以前的值a.它根本没有变化r.r仍然是对同一块内存的引用.

差异很微妙但非常重要.

如果您仍然认为引用只是指针处理的语法糖,阅读Scott Meyers的书籍.他可以比我更好地解释这种差异.


小智 5

在这里要小心……你正在走 C/C++ 路线。有一个非常明显的区别,但并不总是这样:

C++:这通常意味着引用。例如,考虑:

void func(int &x)
{
   x = 4;
}

void callfunc()
{
    int x = 7;
    func(x);
}
Run Code Online (Sandbox Code Playgroud)

因此,C++可以按值传递或按引用传递。

然而,C没有这样的按引用传递功能。& 的意思是“addressof”,是一种从变量中构造指针的方法。但是,请考虑:

void func(int* x)
{
   *x = 4;
}

void callfunc()
{
    int x = 7;
    func(&x);
}
Run Code Online (Sandbox Code Playgroud)

看似相似,却有着本质的不同。您在C中所做的是传递指针的副本。现在这些东西仍然指向同一个内存区域,所以效果就像指向内存的引用传递一样,但它不是传入的引用。它是对内存中某个点的引用。

试试这个(编译为 C):

#include <stdio.h>

void addptr(int* x)
{
    printf("Add-ptr scope 1:\n");
    printf("Addr: %p\n", x);
    printf("Pointed-to-memory: %d\n", *x);
    *x = *x + 7;
    x++;
    printf("Add-ptr scope 2:\n");
    printf("Addr: %p\n", x);
    printf("Pointed-to-memory: %d\n", *x);
}

int main(int argc, char** argv)
{
    int a = 7;
    int *y = &a;
    printf("Main-Scope 2:\n");
    printf("Addr: %p\n", y);
    printf("Pointed-to-memory: %d\n", *y);
    addptr(y);
    printf("Main-Scope 2:\n");
    printf("Addr: %p\n", y);
    printf("Pointed-to-memory: %d\n", *y);
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

如果 C 有通过引用传递,传入的指针地址,当被改变时addptr应该反映在 中main,但它不是。指针仍然是值。

所以,Ç没有具有参照机制的任何通行证。在 C++ 中,这是存在的,这就是 & 在函数参数等中的含义。

编辑:您可能想知道为什么我不能轻松地用 C++ 进行这个演示。那是因为我无法更改引用的地址。在所有。从他非常好的参考指南中

如何重新设置引用以使其引用不同的对象?

没门。

您无法将引用与所指对象分开。

与指针不同,一旦引用绑定到一个对象,它就不能“重新定位”到另一个对象。引用本身不是一个对象(它没有身份;获取引用的地址会给你指涉对象的地址;记住:引用是它的指涉对象)。

从这个意义上说,引用类似于诸如 int* const p 之类的 const 指针(而不是指向诸如 int const* p 之类的 const 指针)。但是请不要将引用与指针混淆;从程序员的角度来看,它们是非常不同的。

根据要求,在返回参考文献时:

#include <iostream>

using namespace std;

int& function(int f)
{
   f=f+3;
   return f;
}

int main(int argc, char** argv)
{
    int x = 7;
    int y;
    y = function(x);
    cout << "Input: " << x << endl;
    cout << "Output:" << y << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

任何好的编译器都应该以某种形式给你这个警告信息:

exp.cpp:7:11: 警告:对与局部变量“f”关联的堆栈内存的引用返回

这是什么意思?好吧,我们知道函数参数被压入堆栈(注意:实际上不是在 x64 上,它们进入寄存器然后进入堆栈,但它们在 x86 上实际上是在堆栈上)并且这个警告说的是创建对这样的引用一个对象不是一个好主意,因为它不能保证留在原地。事实证明这只是运气。

那么什么给呢?试试这个修改后的版本:

#include <iostream>

using namespace std;

int& function(int& f)
{
    f=f+3;
    return f;
}

int main(int argc, char** argv)
{
    int x = 7;
    int y;
    y = function(x);
    cout << "Input: " << x << endl;
    cout << "Output:" << y << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

运行这个,你会看到两个值都更新了。什么?好吧,他们都指的是同一个东西,那个东西正在被编辑。


tro*_*foe 1

它返回对 int 变量的引用。