指针变量和引用变量之间的区别是什么?


当前回答

我总是根据C++核心指南中的这条规则来决定:

当“无参数”是有效选项时,优先选择T*而不是T&

其他回答

指针和引用之间有一个根本的区别,我没有看到任何人提到过:引用支持函数参数中的引用传递语义。指针,虽然它最初不可见,但它不可见:它们只提供值传递语义。这在本文中得到了很好的描述。

当做&rzej公司

我总是根据C++核心指南中的这条规则来决定:

当“无参数”是有效选项时,优先选择T*而不是T&

此外,作为内联函数的参数的引用的处理方式可能与指针不同。

void increment(int *ptrint) { (*ptrint)++; }
void increment(int &refint) { refint++; }
void incptrtest()
{
    int testptr=0;
    increment(&testptr);
}
void increftest()
{
    int testref=0;
    increment(testref);
}

许多编译器在内联指针版本1时实际上会强制写入内存(我们显式地获取地址)。然而,他们会将引用保留在更优化的寄存器中。

当然,对于未内联的函数,指针和引用生成相同的代码,如果函数未修改和返回内部函数,则通过值传递内部函数总是比通过引用传递内部函数更好。

“我知道引用是语法糖,所以代码更容易读写”

这引用不是实现指针的另一种方式,尽管它涵盖了大量的指针用例。指针是一种数据类型——通常指向实际值的地址。然而,它可以设置为零,或者使用地址算术等设置在地址之后的几个位置。对于具有自己值的变量,引用是“语法糖”。

C只有传递值语义。获取变量引用的数据的地址并将其发送到函数是一种通过“引用”传递的方法。引用通过“引用”原始数据位置本身在语义上简化了这一过程。因此:

int x = 1;
int *y = &x;
int &z = x;

Y是一个int指针,指向存储x的位置。X和Z表示相同的存储位置(堆栈或堆)。

很多人谈论过这两个(指针和引用)之间的区别,好像它们是同一个东西,用法不同一样。它们完全不同。

1) “指针可以被重新分配任意次数,而引用在绑定后不能被重新分配。”--指针是指向数据的地址数据类型。引用是数据的另一个名称。因此,您可以“重新分配”引用。你不能重新分配它所指的数据位置。就像你不能更改“x”所指的位置一样,你也不能更改“z”。

x = 2;
*y = 2;
z = 2;

相同的。这是一次重新分配。

2) “指针不能指向任何地方(NULL),而引用总是指向对象”——同样令人困惑。引用只是对象的另一个名称。空指针表示(语义上)它没有引用任何内容,而引用是通过表示它是“x”的另一个名称来创建的。自从

3) “你不能像用指针那样获取引用的地址”——是的,你可以。再次带着困惑。如果您试图查找用作引用的指针的地址,这是一个问题——因为引用不是指向对象的指针。他们就是目标。所以你可以得到对象的地址,也可以得到指针的地址。因为它们都在获取数据的地址(一个是对象在内存中的位置,另一个是指向对象在内存位置的指针)。

int *yz = &z; -- legal
int **yy = &y; -- legal

int *yx = &x; -- legal; notice how this looks like the z example.  x and z are equivalent.

4) “这里没有“引用算术”——同样有点混淆——因为上面的例子中z是对x的引用,因此两者都是整数,所以“引用”算术意味着例如将x引用的值加1。

x++;
z++;

*y++;  // what people assume is happening behind the scenes, but isn't. it would produce the same results in this example.
*(y++);  // this one adds to the pointer, and then dereferences it.  It makes sense that a pointer datatype (an address) can be incremented.  Just like an int can be incremented. 

什么是C++参考(针对C程序员)

引用可以被视为具有自动间接寻址的常量指针(不要与指向常量值的指针混淆!),即编译器将为您应用*运算符。

所有引用都必须使用非空值初始化,否则编译将失败。既不可能获得引用的地址——地址运算符将返回被引用值的地址——也不可能对引用进行算术运算。

C程序员可能不喜欢C++引用,因为当发生间接寻址时,或者当参数通过值或指针传递而不查看函数签名时,C++引用将不再明显。

C++程序员可能不喜欢使用指针,因为它们被认为是不安全的——尽管引用实际上并不比常量指针更安全,但在大多数情况下除外——缺乏自动间接寻址的便利性,并且具有不同的语义内涵。

考虑C++常见问题解答中的以下语句:

即使引用通常使用底层汇编语言,请不要将引用视为指向对象的有趣指针。引用是对象。它是不是指向对象的指针,也不是对象的副本。它是对象

但如果引用真的是对象,那么怎么会有悬空引用呢?在非托管语言中,引用不可能比指针更“安全”——通常没有办法跨范围可靠地别名值!

为什么我认为C++引用有用

来自C背景的C++引用可能看起来有点傻,但在可能的情况下,仍应使用它们而不是指针:自动间接寻址很方便,在处理RAII时引用变得特别有用,但这并不是因为任何已知的安全优势,而是因为它们使编写惯用代码不那么困难。

RAII是C++的核心概念之一,但它与复制语义进行了非平凡的交互。通过引用传递对象可以避免这些问题,因为不需要复制。如果语言中没有引用,则必须使用指针,这样使用起来更麻烦,从而违反了语言设计原则,即最佳实践解决方案应该比替代方案更容易。