回答

收藏

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

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

我知道引用是语法糖,所以代码更容易读写。: X: H  N  G. G! ~- y! L. Z; M/ {
但是指针变量和引用变量有什么区别呢?6 k: O& F/ Y; k; e+ w/ q# L
                                                                3 e/ E7 ]3 V3 w' M0 D
    解决方案:                                                                3 u# |- ^4 K# {$ c
                                                                [ol]可重新分配指针:[/ol]cpp   int x = 5;   int y = 6;   int *p;   p = &x;   p = &y;   *p = 10;   assert(x == 5);  assert(y == 10);
2 h) t5 _# B& n. M引用不能重新绑定,必须在初始化时绑定:5 f0 Z- ^  l1 ~8 o( N7 k6 y% W
cpp   int x = 5;   int y = 6;   int &q; // error   int &r = x;9 I( [- Y  z1 w
[ol]指针变量有自己的标志:一个独特的、可见的内存地址,可以用一元运算符获得,也可以用这个运算&一定量的空间用符测量sizeof。在参考中使用这些操作符将返回与参考绑定值相对应的值;参考自己的地址和大小是看不见的。由于参考以这种方式假设原始变量的身份,因此可以很容易地将参考视为同一变量的另一个名称。[/ol]```cpp6 n/ M6 v, Z' T* L# d2 h! I
            int x = 0;5 @6 Z: Y3 F& h/ Z7 ^6 ?5 \% _
            int &r = x;
5 D, J$ _! A5 D* i, H            int p = &x;
7 `! L2 C' A! H9 q            int p2 = &r;
8 \) |/ y# h# R9 ^& uassert(p == p二、 / &x == &r) c/ H- P! A4 P) V9 p2 c3 H6 q
            assert(&p != &p2);
! S1 z# y: t5 ~, }" ~% Q5 J) i& r            ```
! I. a5 n. L: L  y2 f& `[ol]您可以指向任何嵌套指针,以提供额外的间接指针。引用只提供一级间接。[/ol]```cpp+ Q( S' R/ U4 q8 x2 ~1 u( N
            int x = 0;& v) ]7 b' u" I% @  F
            int y = 0;8 W9 v4 `6 _5 j  _4 P& l3 M& D
            int p = &x;- x( d, k. q5 d- ^8 u6 ]
            int q = &y;5 V5 o. G" B- W' \. l
            int **pp = &p;1 M& R; ~, [, F& C) P. r5 l0 N! I
pp = 2;. v# i6 r+ H3 T' ]$ T  N
            pp = &q; // *pp is now q
* s3 n- n2 l# P2 W  K* c
pp = 4;6 F% b8 ~/ t4 O# k
assert(y == 4);' Y5 Q0 ^" m6 q; V
            assert(x == 2);
1 V' ~! u6 L3 w3 S+ ?  R1 v            ```
% K( `8 n0 V/ {# I8 ^[ol]指针可以分配nullptr,而引用必须绑定到现有对象。如果你足够努力,你可以绑定一个对 的引用nullptr,但这是未定义的,不一致。[/ol]```cpp
" E! }9 W  S! ?% g- c, e8 O7 M            /    the code below is undefined; your compiler may optimise it
# \: p% |& r. U4 F" m8 B                * differently,emit warnings,or outright refuse to compile it /
" h" e) F0 [1 l+ Lint &r = *static_cast<i>(nullptr);" w4 z2 b+ B& g5 r! t0 |6 U
// prints “null” under GCC 10
& M8 z, ~- ?- ?  d            std::cout/ G$ E7 m- c) G7 B" d& z  @
                           
) p" D5 n$ M- ^) |0 f1 J8 e( Zbool f(int &r) { return &r != nullptr; }* U. ^2 f7 z! M: M
// prints “not null” under GCC 10* `# S$ v9 e! C1 a0 E
            std::cout
- j- f. M( v9 `3 \& E, i7 [4 G$ P                           
8 u, n0 @) W5 q: C% |8 f' x6 R但是,你可以引用值为 的指针nullptr。
! E5 T. w+ C& U6 P0 A[ol]指针可以遍历数组;可以用  转到指针指向的下一项, 4转到第 5 元素。这与指针指向的对象大小无关。! R% \' D, d/ e" W( W' U
引用指针需要取消*可以直接访问其指向的内存位置。指向类/结构指针用于->访问其成员并引用使用..
& J5 N- }" i) [引用不能放入数组,但指针可以(用户@litb 提到)
& E- i2 J. B3 Y% I( v常量引用可以绑定到临时对象。指针不能(不是没有间接性):
5 N+ Y" \" n' s[/ol]cpp   const int &x = int(12); / legal C     int *y = &int(12); / illegal to take the address of a temporary.& f' V; y* m3 A5 u
这使得const &使用参数列表更方便。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则