终于有人写了一篇通俗易懂的C语言指针

C语言指针变量的定义和使用(精华)


 

"数据"在内存中的"地址"也成为"指针",如果一个变量存储了一份数据的"指针",我们就称它为"指针变量"。

在C语言中,允许用一个 变量 来存放 指针,这个变量我们称它为指针变量。

"指针变量的值"就是某份数据的"地址",这样一份的数据可以是"数组、字符串、函数,页可以是另外的一个普通变量或者指针变量"

现在我们假设有一个"char类型的变量c"它存储了一个字符'K'(ASCII码为 十进制的75),并占用了地址为OX11A的内存(地址通常用十六进制表示)

另外有一个"指针变量p"它的值为OX11A,正好等于"变量c的地址",这种情况下就称"p指向了c"或者说"p是指针变量c的指针"。

一、定义指针变量

它与普通变量的定义非常相似,不过要在"变量名"前面加个 星号 *

格式为:

    datatype *kangkang;

    或者:

    datatype *kangkang = value;

指针变量:   *

指针变量所指向的数据的类型:  datatype

//例如:

int *p1;

p1是一个指向int类型数据的"指针变量",至于p1究竟指向哪一份数据,应该由赋予它的值决定。

例如:

int a = 100;

int *p_a= &a;

在定义指针变量p_a的同时 对它进行初始化,并将变量a的地址赋予它,此时p_a就指向了a

需要注意的是,p_a需要的是一个地址!!!

所以a前面必须要加"取地址符&",不然就错了!!!

和普通变量一样,指针也可以被多次写入,只要你想,随时都可以改变指针变量的值。

具体如下

//定义普通变量

float a = 99.5,b = 10.6;

char c = 'q',d = '#'

//定义指针变量

float *p1 = &a;

char *p2 = &c;

//修改指针变量的值

p1 = &b;

p2 = &d;

//注意!!

1. *是一个特殊的符号,表明一个变量是指针,定义p1、p2时必须带上 * 。

2. 而给p1、p2 "赋值"时,因为编译器已经知道它是一个指针变量,所以就不用再多此一举了,就可以跟使用普通变量一样来使用指针变量。

3. 也就是说,定义指针变量时必须带*,给指针变量赋值时不能带*。


 

指针变量也可以连续定义噢!

例如:

int *a,*b,*c; //指针a b c的类型都为int*

注意每个变量前面都要带*。如果写称下面的形式,那么只有a是指针变量,bc都是int类型的普通变量。

int *a,b,c;   //只有a是 int*

二、通过指针变量取得数据

指针变量存储了"数据的地址",通过指针变量能够获取到"该地址上的数据"。

格式为:

    *kangkang;

* 称为"指针运算符",用来取得某个地址上的数据

//举个程序例子吧

#include<stdio.h>

int main()

{

    int a = 15;

    int *p = &a;

    printf("%d,%d\n",a,*p);

    return 0;

}

结果:

15,15

假设 a 的地址是 0X1000,p 指向 a 后,p 本身的值也会变为 0X1000,*p 表示获取地址 0X1000 上的数据,也即变量 a 的值。从运行结果看,*p 和 a 是等价的。


 

//指针除了可以获取内存上的数据,也可以修改内存上的数据,

例如:

#include<stdio.h>

int main()

{

    int a = 15,b = 99,c = 222;

    int *p = &a; //定义指针变量

    *p = b; //通过指针变量修改内存上的数据

    c = *p; //通过指针变量获取内存上的数据

    printf("%d,%d,%d,%d\n",a,b,c,*p);

    return 0;

}

结果为:

99,99,99,99

*p 代表的是 a 中的数据,它等价于 a,可以将另外的一份数据赋值给它,也可以将它赋值给另外的一个变量。

 * 在不同的场景下有不同的作用:

1. *可以在指针变量的定义中,表明这是一个指针变量(让大家可以将它与普通变量区别开)

2. 是用"指针变量"时在 前面加* 表示"获取指针指向的数据",或者说 表示的是"指针指向的数据本身"。

也就是说,"定义指针变量时的*"与 "使用指针变量时的*" 意义完全不同。

具体如下:

int *p = &a;

*p = 100;

第一个 代码中 * 用来指明p是一个指针变量

第二个带啊吗中 * 是用来获取指针指向的数据

"需要注意的是":给指针变量本身"赋值"时 不能加  * 

如下:

int *p;

p = &a; //给指针变量本身 赋值!!!

*p = 100;

指针变量也可以出现在普通变量能出现的任何表达式中,例如:

int x, y, *px = &x, *py = &y;

y = *px + 5;  //表示把x的内容加5并赋给y,*px+5相当于(*px)+5

y = ++*px;  //px的内容加上1之后赋给y,++*px相当于++(*px)

y = *px++;  //相当于y=*(px++)

py = px;  //把一个指针的值赋给另一个指针

为了让大家更易理解,下面再举个程序例子吧!

//eg通过指针交换两个变量的值。

#include<stdio.h>

int main()

{

    int a = 100,b = 999,temp;

    int *pa = &a;

    int *Pb = &b;

    printf("a=%d,b=%d",a,b);

    //进入交换!!!

    temp = *pa; //将a的值先保存到temp上

    *pa = *pb; //将b的值交给a;

    *pb = temp;//最后将保存起来的a值交给b



    //结束交换,输出最终结果

    printf("a=%d,b=%d\n",a,b);

    return 0;

}

结果:

a=100, b=999

a=999, b=100

从运行结果可以看出,a、b 的值已经发生了交换。需要注意的是临时变量 temp,它的作用特别重要,因为执行*pa = *pb;语句后 a 的值会被 b 的值覆盖,如果不先将 a 的值保存起来以后就找不到了。


 

三、关于 * 和 & 的谜题

假设有一个int类型的a, pa是指向他们的指针, 那么 *&a 和*&pa 分别是什么意思呢?

    *&a可以理解为 *(&a),   &a表示"取变量a的地址",等价于(pa),所以*(&a)表示取这个地址上的数据(等价于*pa),绕来绕去,又回到原点,*&a仍然等于a。

  

    &*pa可以理解为 &(*pa),   *pa表示"取得pa指向得数据(等价于a)", &(*pa)表示数据的地址(等价于&a),所以&*pa等价于 pa。


 

四、对 星号* 的总结

在我们目前所学到的语法中,星号*主要有三种用途:

表示乘法,例如int a = 3, b = 5, c;  c = a * b;,这是最容易理解的。

表示定义一个指针变量,以和普通变量区分开,例如int a = 100;  int *p = &a;。

表示获取指针指向的数据,是一种间接操作,例如int a, b, *p = &a;  *p = 100;  b = *p;。

猜你喜欢

转载自blog.csdn.net/weixin_51563198/article/details/122783836
今日推荐