你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

指针的应用

[复制链接]
gaosmile 发布时间:2021-1-19 12:10
很多人遇到指针就糊涂,搞不清到底指向什么,其实是你没搞清楚 * 修饰谁,还有一些关键字修饰谁。7 _. Z6 K& l0 P9 P9 x' X8 H
看下面的例子,定义一个无符号字符变量x,然后同时定义一个可以指向x的指针p,即可以将x的地址放到指针变量p里面,然后又定义了一个可以存放p地址的指针pp:
  1. % c. ~4 y2 c; [# E: z5 W% a
  2. #include "stdio.h"
    : T% g! N! A4 m
  3. int main(void)
    * V' C4 E! F( p% G* l$ H
  4. {2 e; U0 O8 Z( R  l1 {9 N
  5. //无符号字符变量x,指向无符号字符变量类型的指针p,指向指针类型p的指针pp.1 M) R. u+ N0 O# R" m5 ^
  6. unsigned char x,*p,**pp;6 R( k$ G$ F, x, r6 d
  7.         x=12;9 B& ^) H; C) K# K7 ~$ s0 N
  8.         p=&x;
    " x0 a& Y/ }# Z) R4 B* S
  9.         pp=&p;
    * Q+ z/ b2 l# i4 Q& r) U/ }* d
  10. //const是修饰指针指向的对象属性,意思是指针kp只能指向一个const常量,而kp可以被修改指向不同的const常量,但是不能通过kp指针修改指向变量的值。
    - u* j/ n3 _1 A4 C2 _! p
  11. int const *kp,k=20,kv=32;
    ) j* j" f3 O; S9 g
  12.         kp=&k;+ l3 j/ q3 o" b* _) ~
  13.         kp=&kv;
    , d. O3 }; V; ], M
  14. //const是修饰指针mp,mp将指向固定的地址,因此在定义的时候就应该指定好该地址,之后无法修改该指针内的地址。- b* Q7 @. V& Z1 d0 }
  15. int mv=14;2 a( I/ d& \. P) E
  16. int *const mp=&mv;
    " w' e" T; i- L. y- y  M
  17. //可以让kp指向mv的地址,但是不能通过kp,修改mv的值;        / g$ J% i, ]+ `# G3 h6 T! T
  18.         kp=&mv;) z( S1 U) g+ l) h# D9 s
  19. /*( c/ `4 K; F+ ~5 x+ n
  20.         总结:        const *p 表示*p是一个整体,即指针p指向的某个变量,而const修饰该变量;. `# K# o/ x. [+ V1 K7 o) L
  21.                         * const p表示const p是一个整体,const 修饰指针p,即指针p存放的地址不能变。
    ; C2 y7 h5 n. E, Z3 b
  22.         */
    , _1 Q! t5 h- i" X8 I
  23. printf("*p=%d\n",*p);
    * G2 T0 o3 S/ A; j* F
  24. printf("**pp=%d\n",**pp);
    ! Q  {0 u. R: I' `  p7 n) m2 m
  25. printf(" p=%d\n",p);1 u. c* Q1 u' ~& N7 K( s4 t
  26. printf("pp=%d\n",pp);
    0 r1 l$ F/ E6 H
  27. printf("pp=%d\n",&pp);2 L* X. s3 Y8 N2 N3 o$ |3 ^2 P
  28. }
复制代码
% a9 A3 u9 v' Y# V. s  o6 B2 g
很多时候还会遇到const关键字,很多人不知道该如何结合,到底const修饰谁?
. i- l, w8 M, R这里你可以将定义看成是从右到左的结合。

- i9 u& e2 L9 i3 d; r+ }* x
int const *kp;7 V) m+ }; m3 a; n0 @- b) _$ Z' }
int *const mp;
+ ]) B. ~, i: _# ]1 L
例如例子中的这两个,你看好了,从右到左
! L! M' O# L+ C: B, O, n
int const (*kp);
5 a* v, n/ h& \4 Z: h" J( {1 ~int *(const mp);
5 ~( d1 K5 W% U! J, \1 P
第一个括号里是表示kp指针指向的某个变量,该变量是个const常量,不可变。
  M& r' `; n: \) i# `* r第二个是const直接修饰了指针mp,意思是指针存放的内容是不可变的,就是地址不可变。
; x. x0 p0 |9 q; O9 o. w. P: Q* V% n" \7 G! A8 \5 a+ o
*与&是一对逆操作,*的出现用于定义指针,在使用的时候用于通过指针找到指向的变量。

4 b- J$ {& g! y, K/ L; ^
而&用于取出变量的地址。
8 r) u) y8 n" Q' ~: A
3 Z. V- b! Y" r在PC测试上,推荐一个C语言的IDE,是C语言入门圣经  C primer plus上推荐的一款:Pelles C IDE
4 i3 J6 N) X) n/ B% C/ E, R
微信图片_20210119120954.png % P6 _% u$ Y  [+ O0 y# w
如果想使用中文界面可以访问下面这个中文链接:https://www.pellesc.cn/
2 t) M' W3 t; q) |7 s% T
例如一个指向固定地址的指针,若想修改它指向的地址,那么会报错

2 w: m  C' i9 h* K& O
微信图片_20210119120958.png ; `5 D8 M! ?) c7 `3 P
上面的报错信息意思是赋值错误,'='的操作数有不兼容的类型'int *'和'int',分配到了固定的地址。该固定的地址是不可以被修改的。
) C  P9 \# {0 c6 `; q" c0 P( p
另外需要注意,如果一个变量定义为指向常量的指针,那么该指针还是可以指向一个可变的变量,但是无法通过该指针修改该变量。该变量的属性就是通过它操作指向的变量都当做不可修改常量看待。
7 m" E# r% o$ v% X, |9 |
报错内容如下:
: J- }2 X4 M2 p% c
微信图片_20210119121001.png
# J3 d, F% d, f1 X
微信图片_20210119121004.png ) A0 l. S- X/ \6 d2 r
( e: }7 C) V7 R3 H. y
最后奉上,注释掉不合法的语句后的完整学习代码
  1. 6 ?6 a9 n* W/ N& W  d
  2. #include "stdio.h"
      t5 C, E( k# U

  3. 0 b& ?( r% L2 I, w- j' m
  4. int main(void)) g$ a  B$ T0 B$ E) e
  5. {
      q4 q6 z! u2 @1 a: h% U
  6. //无符号整形变量x,指向无符号整形变量类型的指针p,指向指针类型p的指针pp.
    ) |, B. P6 n! {
  7.         unsigned int x,*p,**pp;' _! }3 N4 o& @  ]
  8.         x=12;
    , g  k" C5 y) h! X+ j, q
  9.         p=&x;
    1 t$ g2 W/ F5 D: A
  10.         pp=&p;6 G& B6 M& x5 L# p
  11.         printf("通过指针p,打印x的值12:*p=%d\n",*p);
      n  Y/ A9 D/ F) [! W
  12.         printf("通过指针pp,打印pp存放的指针p指向的变量x的值:**pp=%d\n",**pp);
    + g, N4 z1 [" G1 _
  13.         printf("打印变量x的地址:        &x=%p\n",&x);
    , P  ~% N* u- I: w6 {0 e' x
  14.         printf("打印指针p存放的变量x的地址:p=%p\n",p);  ]8 B! c. J6 r! l
  15.         printf("打印指针p的地址:        pp=%p\n",pp);
    0 m8 J# o; G( {' {/ v0 L
  16.         printf("打印指针变量pp的地址:        pp=%p\n",&pp);0 \5 ?; ^) U* K) S$ A7 |! i+ y3 @9 t
  17.         printf("--------------------------------------------\n");* i3 b4 x6 Z) T5 |  _/ U
  18. //const是修饰指针指向的对象属性,意思是指针kp只能指向一个const常量,而kp可以被修改指向不同的const常量,但是不能通过kp指针修改指向变量的值。1 k2 |4 d( O2 ^6 |) H3 |
  19.         int const *kp,k=20,kv=32;; {, r6 h6 w  W" ?: F8 G- P
  20.         kp=&k;
    ! c' X- L7 Y, P7 W) F% z
  21.         printf("通过指针kp访问固定的数k,*kp=%d\n",*kp);, r) f) W& T1 [% n% }- k4 g
  22.         kp=&kv;
    : X' l) [5 P9 b
  23.         printf("通过指针kp访问固定的数kv,*kp=%d\n",*kp);
    ' i2 E% W, Q5 J" x
  24. //        通过kp不可以修改指向地址存放变量的固定值。& I6 h* }+ G/ x7 A0 a
  25. //        *kp=21;
    8 e+ \7 Z; u4 B# G6 X' H
  26. * E) ~. K5 ^7 @2 l

  27. * B0 E! r3 d2 F$ o+ D6 _. w

  28. 7 i: I2 ~( a# G* r) c7 W1 Y
  29. //const是修饰指针mp,mp将指向固定的地址,因此在定义的时候就应该指定好该地址,之后无法修改该指针内的地址。3 b6 [$ O9 w. i0 ^# @' p4 U* c
  30.         int mv=14,mx=24;
    ( ^# p2 U# P7 I( F) b
  31.         int *const mp=&mv;; X9 M1 p* _# I$ D7 ^
  32.         printf("通过存放固定地址的指针访问指向的变量mv=14:*mp=%d\n",*mp);
    ; |$ ?! Z/ l! O) j
  33.         *mp=15;
    / ^5 T1 O4 n  W, f7 I- m% W: e2 G
  34.         printf("通过存放固定地址的指针修改指向的变量mv=15:*mp=%d\n",*mp);' U6 w; R# x7 D9 X
  35. //可以让kp指向mv的地址,但是不能通过kp,修改mv的值;        
    8 J" w6 @! v& ~; ]! v" \+ u; X
  36.         kp=&mx;
    ! W0 x" }6 N; I, w3 l: b) I
  37.         printf("将指向固定数据的指针kp指向一个可以修改的变量mx=24,*kp=%d\n",*kp);+ F9 i! V. z8 d7 g# B
  38. //        试图通过指向固定常量的指针kp修改指向的可修改变量mx时候,失败了。
    ' `6 g. Z% n+ Z. l7 ]
  39. //        *kp=25;/ z7 e2 H- i# _; I( A" @) C4 t0 f9 V
  40. + f% |3 |1 a7 i
  41. //因为mp指针指向的地址是const类型,所以下面的操作是非法的,会报错。        8 A, [7 R* z- b5 }- R3 K
  42. //        mp=&24;* A1 L1 ~3 ~% M: t% u! {, d

  43. 8 r9 X/ w2 h( P5 v. ]
  44. /*  }4 o& R2 \- ~* ]
  45.         总结:        const *p 表示*p是一个整体,即指针p指向的某个变量,而const修饰该变量;
    ! B* C4 t: P& w
  46.                         * const p表示const p是一个整体,const 修饰指针p,即指针p存放的地址不能变。! F8 X8 ]* _7 S# C
  47.         */) P! C+ G' z) b7 V
  48. }
复制代码

. p& \/ O+ P% Z. A3 D3 H3 O) @2 z1 |/ P% x* n5 J
赞 收藏 评论0 发布时间:2021-1-19 12:10

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版