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


当前回答

指针是保存另一个变量的内存地址的变量,其中引用是现有变量的别名。(已存在变量的另一个名称)

1.指针可以初始化为:

int b = 15;
int *q = &b;

OR

int *q;
q = &b;

其中作为参考,

int b=15;
int &c=b;

(在一个步骤中声明和初始化)

指针可以分配给null,但引用不能可以对指针执行各种算术运算,而没有所谓的参考算术。指针可以重新分配,但引用不能指针在堆栈上有自己的内存地址和大小,而引用共享相同的内存地址

其他回答

如果遵循传递给函数的参数的约定,则可以使用引用和指针之间的差异。Const引用用于传递到函数中的数据,指针用于传递出函数的数据。在其他语言中,您可以使用诸如In和out之类的关键字来明确表示这一点。在C++中,您可以(按照约定)声明等价的。例如

void DoSomething(const Foo& thisIsAnInput, Foo* thisIsAnOutput)
{
   if (thisIsAnOuput)
      *thisIsAnOutput = thisIsAnInput;
}

使用引用作为输入和指针作为输出是Google风格指南的一部分。

除非我需要以下任何一项,否则我会使用参考资料:

空指针可以用作哨兵价值,通常是一种廉价的方式避免函数重载或使用嘘声。你可以在指针上做算术。例如,p+=偏移量;

不能像指针一样取消引用,当取消引用时,

引用和指针都是通过地址工作的。。。

so

你可以这样做

int*val=0xDEADBEEF;*val是0xDEADBEEF的值。

你不能这样做int&V=1;

*不允许使用val。

它占用多少空间并不重要,因为你实际上看不到它占用的任何空间的任何副作用(不执行代码)。

另一方面,引用和指针之间的一个主要区别是,分配给常量引用的临时变量在常量引用超出范围之前一直有效。

例如:

class scope_test
{
public:
    ~scope_test() { printf("scope_test done!\n"); }
};

...

{
    const scope_test &test= scope_test();
    printf("in scope\n");
}

将打印:

in scope
scope_test done!

这是允许ScopeGuard工作的语言机制。

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

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

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.