一尘不染

C++中的指针变量和引用变量有什么区别?

c++

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

但是指针变量和引用变量有什么区别呢?


阅读 299

收藏
2022-01-13

共1个答案

一尘不染

  1. 可以重新分配指针:

cpp int x = 5; int y = 6; int *p; p = &x; p = &y; *p = 10; assert(x == 5); assert(y == 10);

引用不能重新绑定,必须在初始化时绑定:

cpp int x = 5; int y = 6; int &q; // error int &r = x;

  1. 指针变量有它自己的标识:一个可以用一元运算符获取的独特的、可见的内存地址和可以用该运算&符测量的一定量的空间sizeof。在引用上使用这些运算符会返回一个与引用绑定的值相对应的值;引用自己的地址和大小是不可见的。由于引用以这种方式假定原始变量的身份,因此可以方便地将引用视为同一变量的另一个名称。

```cpp
int x = 0;
int &r = x;
int p = &x;
int
p2 = &r;

assert(p == p2); // &x == &r
assert(&p != &p2);
```

  1. 您可以将任意嵌套的指针指向提供额外间接级别的指针。引用仅提供一级间接。

```cpp
int x = 0;
int y = 0;
int p = &x;
int
q = &y;
int **pp = &p;

pp = 2;
pp = &q; // *pp is now q
pp = 4;

assert(y == 4);
assert(x == 2);
```

  1. 可以分配指针nullptr,而引用必须绑定到现有对象。如果你足够努力,你可以绑定一个对 的引用nullptr,但这是未定义的,并且不会表现得一致。

```cpp
/ the code below is undefined; your compiler may optimise it
* differently, emit warnings, or outright refuse to compile it
/

int &r = *static_cast(nullptr);

// prints “null” under GCC 10
std::cout
<< (&r != nullptr
? “not null” : “null”)
<< std::endl;

bool f(int &r) { return &r != nullptr; }

// prints “not null” under GCC 10
std::cout
<< (f(*static_cast(nullptr))
? “not null” : “null”)
<< std::endl;
```

但是,您可以引用值为 的指针nullptr

  1. 指针可以遍历数组;您可以使用++转到指针指向的下一项,并+ 4转到第 5 个元素。这与指针指向的对象大小无关。

  2. 需要取消引用指针*才能访问它指向的内存位置,而可以直接使用引用。指向类/结构的指针用于->访问其成员,而引用使用..

  3. 引用不能放入数组,而指针可以(用户@litb 提到)

  4. 常量引用可以绑定到临时对象。指针不能(不是没有一些间接性):

cpp const int &x = int(12); // legal C++ int *y = &int(12); // illegal to take the address of a temporary.

这使得const &在参数列表等中使用更方便。

2022-01-13