博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
指针之——一级二级多级指针
阅读量:5080 次
发布时间:2019-06-12

本文共 2828 字,大约阅读时间需要 9 分钟。

指针,C语言永恒的话题。关于指针,在《c和指针》上是这样形容的,指针就是地址的另外一个叫法。所以我们要明白,指针和指针变量的区别,指针就是地址,指针变量是存放指针的变量,即指针变量存放的是地址,我们通过间接访问符可以得到该地址的内容。但是,在一般情况下,我们都把指针变量说成指针这样的简称。例如:void (*fuc)(int a);我们会说fuc是一个指针,指向一个参数为int返回值为void的函数。这个时候我们并不它称作指针变量,而笼统地称为指针,因为我们使用指针的情况下,大多是在操作指针变量,但是,在某些情况下,需要精确表述时,应该明白,指针变量是存放地址(指针)的,指针就是一个地址。后面所说的指针,不特殊说明,都指指针变量,因为指针和指针变量大部分时候我们不是去区分它的文字定义,而是怎么去使用它,最主要是因为这已经三人成虎了。比如,char *p=NULL;我们都说p是一个指针,其实严格来说这个p是指针变量。因为定义一个指针类型的变量,必然在内存中开辟了空间,就是指针变量了,但已经被大家都这样叫指针了,所以,虽然我们这样叫着,但具体含义还是要清楚的。我们使用赋值方式给一个“指针”的时候,这个指针一定已经是指针变量了,因为地址不能做左值,地址对应的内存空间才可以。不过始终得有个约定吧,所以就先统称指针了。

指针就是为间接赋值或者说间接改变某些东西存在的。

eg:

1 #define _CRT_SECURE_NO_WARNINGS 2 #include
3 4 int main() 5 { 6 int a = 10; 7 int *p1= NULL; 8 int **p2 = NULL; 9 10 //直接修改方式11 a = 20;12 printf("a:%d\n", a);13 //一级间接修改14 p1 = &a;15 *p1 = 30;16 printf("a:%d\n", a);17 //二级间接修改18 p2 = &p1;19 //*p2 = 0x11;//可能会出错,因为内存中这片区域不一定可以使用20 **p2 = 40;//这样二级间接修改a就不会出错21 printf("a:%d\n", a);22 return 0;23 }

可能在这里你会觉得,既然一级指针就已经能够更改一个地址的变量了,为什么还要二级指针或者多级指针呢?

一级指针用普通变量的地址去接,二级指针用一级指针的地址去接,N级指针用N-1级指针的地址去接。

我们在一个程序中已经使用了一级指针了,如果我们想修改这个一级指针或者这个一级指针指向的内容,就会使用到二级指针了,但是,为了代码的可读性,最好用二级以下的指针解决。

指针变量需要指向一个内存空间,内存空间相当于门牌号,而对一个指针解引用(*),相当于间接访问这个指针变量中存储的地址里面对应的内容,(*)相当于一把钥匙打开了房门。

eg:

1 #define _CRT_SECURE_NO_WARNINGS 2 #include
3 4 int main() 5 { 6 int *p1; 7 int **p2; 8 9 p1 = 0x325;//随便给的一个地址,不要轻易访问这个内存,多半出错10 printf("0x%x\n", p1);11 p2 = &p1;//二级指针需要一级指针的地址初始化12 //当然,其实任意地址都可以,只是会有警告,比如下面:13 /*14 int a = 10;15 p2 = &a;//编译器提示:int **”与“int *”的间接级别不同16 //这样还是可以修改,因为本质上来说,不管你几级指针,都只是需要地址去初始化它17 //但是,我们应该遵循类型完全兼容的原则18 */19 20 *p2 = 123;21 printf("%d\n", p1);//这个时候,通过二级指针修改了一级指针的值22 return 0;23 }

再来一个体现二级指针用法的例子:

1 #define _CRT_SECURE_NO_WARNINGS 2 #include
3 //还是可以更改a的值,因为mp和p都指向a的地址,但要是我现在设计需求要改变p的值呢? 4 void two_pointer(int *mp) 5 { 6 *mp = 30; 7 } 8 //要改变p的值,当然和普通变量a一样,可以直接修改,也可以间接修改 9 //和普通变量a有需要间接修改的需求一样,指针变量p也有这样的需求10 //此时,二级指针就来了11 void two_pointer2(int **mmp)12 {13 //mmp是二级指针,不管它是多少级,始终记住,加一个(*)就像多一扇门14 //一级指针p修改普通变量a,我们通过*p=想要修改的数 这样的方式,同理15 //二级指针修改一级指针,也应该是通过*mmp=想要修改的一级指针 这样的方式     //二级指针修改一级指针指向地址的内容时,需要两个(*),因为你需要开两次门啊! 16 *mmp = (int *)0x100;//把一级指针p的值修改为100 17 //加强制类型转换是因为100是个立即数,而*mmp希望接受的是一个18 //int *的地址,当然,不强转成这样只是警告,而且还是可以达到效果19 //这个在后面写链表的程序中非常有用20 }21 int main()22 {23 int a=10;24 printf("a=%d &a=%p\n", a,&a);25 26 int *p=&a;27 *p = 20;28 printf("a=%d &p=%p\n", a, &p);29 30 two_pointer(p);31 printf("a=%d p=%p\n", a,p);32 33 two_pointer2(&p);34 printf("p=%p\n", p);//此时,p已经被修改35 return 0;36 }

请君多思量,指针不过如此。

转载于:https://www.cnblogs.com/yangguang-it/p/6618211.html

你可能感兴趣的文章
bzoj1878
查看>>
【Vegas原创】Mysql绿色版安装方法
查看>>
Thrift Expected protocol id ffffff82 but got 0
查看>>
分享《去哪儿网》前端笔试题
查看>>
2013-07-04学习笔记二
查看>>
CP15 协处理器寄存器解读
查看>>
【codeforces 787B】Not Afraid
查看>>
【9111】高精度除法(高精度除高精度)
查看>>
【hihocoder 1312】搜索三·启发式搜索(普通广搜做法)
查看>>
JavaFX中ObservableValue类型
查看>>
杭电 1097 A hard puzzle
查看>>
[转载]INFORMIX锁机制及如何剖析其锁申辩(第二部门)
查看>>
Andriod-项目stymqjlb-学习笔记2-原型
查看>>
Web AppDomain
查看>>
JQuery创建规范插件
查看>>
AD 域服务简介(三)- Java 对 AD 域用户的增删改查操作
查看>>
Unity中Text渐变色,和Text间距
查看>>
Android利用方向传感器获得手机的相对角度实例说明
查看>>
Linux基础学习系列(一)
查看>>
LINUX 蓝牙耳机的配置方法
查看>>