回答

收藏

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

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

我知道引用是语法糖,所以代码更容易读写。
5 t8 X) J! W; F8 Q5 b! L7 g但是指针变量和引用变量有什么区别呢?; R, G9 v3 w* Z3 y
                                                               
: E2 K# t. u4 c9 \8 U% J7 A1 w    解决方案:                                                                , l) w7 P) J# ]
                                                                [ol]可重新分配指针:[/ol]cpp   int x = 5;   int y = 6;   int *p;   p = &x;   p = &y;   *p = 10;   assert(x == 5);  assert(y == 10);
$ @& A1 Q3 K0 _; m; `4 R( S引用不能重新绑定,必须在初始化时绑定:
' l2 i, y; j2 d0 \7 ccpp   int x = 5;   int y = 6;   int &q; // error   int &r = x;, ?$ {6 \% e3 M  A8 o& P, g
[ol]指针变量有自己的标志:一个独特的、可见的内存地址,可以用一元运算符获得,也可以用这个运算&一定量的空间用符测量sizeof。在参考中使用这些操作符将返回与参考绑定值相对应的值;参考自己的地址和大小是看不见的。由于参考以这种方式假设原始变量的身份,因此可以很容易地将参考视为同一变量的另一个名称。[/ol]```cpp
0 X8 e9 u6 W9 P! M, Z  [: g  o            int x = 0;
2 @+ _, }5 e' j9 J0 i            int &r = x;9 v( D' ^# H$ O+ O" r9 J  M
            int p = &x;4 J6 I. \5 {. j1 i( n+ e) X
            int p2 = &r;
: o2 `( F6 f6 V, r8 |: ^+ iassert(p == p二、 / &x == &r
# o* K2 b1 Z" U1 f7 b6 M            assert(&p != &p2);
9 h  e+ Q) Q- D0 v$ {3 ]  _- [            ```+ Q3 ]. y: e1 z( q2 G* d. N
[ol]您可以指向任何嵌套指针,以提供额外的间接指针。引用只提供一级间接。[/ol]```cpp! a) b# F( N5 m! P; r6 R( V
            int x = 0;! e/ M; E% U  @% @
            int y = 0;+ P0 {1 J; J" _& I
            int p = &x;
, J2 C% o5 X$ S. }  N9 Y            int q = &y;9 x5 \% y" j5 W" o% u
            int **pp = &p;2 ^) S$ |* p  G* B
pp = 2;/ l1 M: d: y6 r
            pp = &q; // *pp is now q* T( z* y1 w8 w( o: Q- P8 n
pp = 4;/ S. h: A" \! q8 A6 E3 R) D
assert(y == 4);" h* I6 Q& ~# r3 r5 I- d
            assert(x == 2);
7 ]" F3 I& o3 O            ```$ Q9 l- \# y1 {$ ?
[ol]指针可以分配nullptr,而引用必须绑定到现有对象。如果你足够努力,你可以绑定一个对 的引用nullptr,但这是未定义的,不一致。[/ol]```cpp! t- O7 F1 O' U5 ]) ?& Q
            /    the code below is undefined; your compiler may optimise it
# U5 l5 O  |5 q. w( A3 K                * differently,emit warnings,or outright refuse to compile it /9 s! W7 H4 R7 q$ H
int &r = *static_cast<i>(nullptr);( p& f& _% s' N
// prints “null” under GCC 10  [5 [( p$ X: `# S# a) u9 x
            std::cout# g3 A" ^$ ~& q; p- d
                            5 k. V- x- J# d6 G2 g( u( X! h
bool f(int &r) { return &r != nullptr; }8 B4 s0 p( d! `1 j
// prints “not null” under GCC 10! j# j! v+ l2 y1 g! o2 E* U
            std::cout
, P# q5 D4 n5 {+ n& J7 t                           
: N/ o  i+ U( f+ q+ g但是,你可以引用值为 的指针nullptr。
, U3 A5 N& X5 n6 L! i3 ~[ol]指针可以遍历数组;可以用  转到指针指向的下一项, 4转到第 5 元素。这与指针指向的对象大小无关。; ^  S, [' R0 ^, R0 N2 |$ p6 l
引用指针需要取消*可以直接访问其指向的内存位置。指向类/结构指针用于->访问其成员并引用使用..* p: c3 J% ~1 h  W' {) P
引用不能放入数组,但指针可以(用户@litb 提到)" n) ]8 H! q/ N) q: H' Y
常量引用可以绑定到临时对象。指针不能(不是没有间接性):! d  e6 I: l0 \% Z
[/ol]cpp   const int &x = int(12); / legal C     int *y = &int(12); / illegal to take the address of a temporary.5 ^& f  B) ?7 N
这使得const &使用参数列表更方便。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则