回答

收藏

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

技术问答 技术问答 255 人阅读 | 0 人回复 | 2023-09-12

我知道引用是语法糖,所以代码更容易读写。
" Y* _% i0 j! J) Z9 |' [/ S! l但是指针变量和引用变量有什么区别呢?2 b- x* E5 k7 s! K( g/ }4 `2 m
                                                               
2 Y0 k+ H/ N  _; P  Z    解决方案:                                                               
3 h5 A/ L, _  f" `' j$ \# r8 t                                                                [ol]可重新分配指针:[/ol]cpp   int x = 5;   int y = 6;   int *p;   p = &x;   p = &y;   *p = 10;   assert(x == 5);  assert(y == 10);$ x" Y, O% @0 ?, _& k+ R
引用不能重新绑定,必须在初始化时绑定:' C. m4 b1 m- h8 s, X: R8 n/ {
cpp   int x = 5;   int y = 6;   int &q; // error   int &r = x;) ]1 F0 _+ A2 q
[ol]指针变量有自己的标志:一个独特的、可见的内存地址,可以用一元运算符获得,也可以用这个运算&一定量的空间用符测量sizeof。在参考中使用这些操作符将返回与参考绑定值相对应的值;参考自己的地址和大小是看不见的。由于参考以这种方式假设原始变量的身份,因此可以很容易地将参考视为同一变量的另一个名称。[/ol]```cpp% _7 j1 c- ?8 {0 F0 b8 M7 U
            int x = 0;% H* h6 s% F( O/ V" [
            int &r = x;7 b" a. n" N! l! k5 t0 A) R
            int p = &x;  r1 q$ K" w! y/ q1 h6 F
            int p2 = &r;
0 ?7 ^2 X5 a9 U' oassert(p == p二、 / &x == &r# }, X5 _  R  F$ a$ k
            assert(&p != &p2);/ _* F* b1 H, p* q/ c( Q
            ```
1 X% n! e9 F; c9 ^5 J1 c/ e( v[ol]您可以指向任何嵌套指针,以提供额外的间接指针。引用只提供一级间接。[/ol]```cpp
6 i$ L- e: v9 d3 }7 m* W0 w            int x = 0;  S( ^. \# K5 G3 ]: T! `
            int y = 0;  b# ~9 O/ ^: Q7 k$ C
            int p = &x;+ I/ i8 d" C' H) u2 t6 D; K- O
            int q = &y;
! D) G/ P/ U3 i) h+ m) F            int **pp = &p;2 L  Q, k9 D  {3 r7 Z# D1 i
pp = 2;
8 g3 _2 i7 D3 v/ A4 `* H            pp = &q; // *pp is now q  Y: H' L- P4 `
pp = 4;5 F! S6 t" r8 e
assert(y == 4);8 d* C; \6 Y' I
            assert(x == 2);* m7 m: d7 E' @
            ```; N5 i2 t2 j4 D% F
[ol]指针可以分配nullptr,而引用必须绑定到现有对象。如果你足够努力,你可以绑定一个对 的引用nullptr,但这是未定义的,不一致。[/ol]```cpp
0 c8 e+ X7 \2 A" {& k1 I            /    the code below is undefined; your compiler may optimise it! ?  K9 `- s1 K& O6 x4 n
                * differently,emit warnings,or outright refuse to compile it /
) q% V3 j' B3 i" E+ zint &r = *static_cast<i>(nullptr);
! M8 Q2 ~) [$ M- j4 c6 ]' v// prints “null” under GCC 10
. h' G: P& m% V            std::cout
0 N* W9 V0 k; _9 D                           
* K5 h' M' n5 u& Z9 Cbool f(int &r) { return &r != nullptr; }. b8 {6 D( Q0 j/ Z8 [! G" t/ U
// prints “not null” under GCC 10$ L0 ^* E- F7 s0 J) m
            std::cout
; a: H# P. W. O1 T5 U5 m; ~                           
1 ^% @2 v0 z  M% b8 |+ y9 W但是,你可以引用值为 的指针nullptr。
% l" N" U9 g/ r1 W. r+ d[ol]指针可以遍历数组;可以用  转到指针指向的下一项, 4转到第 5 元素。这与指针指向的对象大小无关。
  U% \+ s& U0 }; F( X; x  L引用指针需要取消*可以直接访问其指向的内存位置。指向类/结构指针用于->访问其成员并引用使用..
( T3 m! Y9 l  y, T# ^引用不能放入数组,但指针可以(用户@litb 提到)
. \: F; b9 I% `2 c+ x常量引用可以绑定到临时对象。指针不能(不是没有间接性):
( y9 V! q+ t; g6 N4 H6 Z) Q[/ol]cpp   const int &x = int(12); / legal C     int *y = &int(12); / illegal to take the address of a temporary.6 s6 z4 ]! F) R( s
这使得const &使用参数列表更方便。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则