C语言之指针篇【超详细讲解,带你层层深入理解指针】

2024-03-23 1163阅读

温馨提示:这篇文章已超过373天没有更新,请注意相关的内容是否还可用!

目录

一、关于指针

二、指针类型

1、整型指针的访问权限说明:

2、字符指针的访问权限说明:

3、指针的类型决定向前或向后一步走了多大距离

三、野指针相关知识

1、野指针的成因

①指针未初始化

②指针的越界访问

③指针所指向的空间释放了

2、如何规避野指针

①指针要初始化

②要注意指针越界的问题

③指针所指向的空间及时置NULL

④避免返回局部变量的地址

⑤指针使用之前检查有效性

四、常量指针和指针常量

1、常量指针

2、指针常量

五、有关指针的运算 

1、指针+-整数

2、指针-指针

3、指针的关系运算

六、字符指针

常量字符串(相关知识)

七、指针数组

数组名的含义

八、数组指针

九、数组参数,指针参数

1、一维数组传参

2、二维数组传参

3、一级指针传参

4、二级指针传参

十、函数指针

函数指针重命名 

十一、函数指针数组


​​​​​​​

一、关于指针

首先内存会划分为小的内存单元,每个内存单元都有一个编号,这个编号就被称为地址,我们把地址也叫指针,如下图所示:

C语言之指针篇【超详细讲解,带你层层深入理解指针】


注意注意:指针指的是地址,但是我们口语中的指针通常指的是指针变量

指针变量就是用来存放地址的变量

我们是可以通过修改指针变量的值来修改原数值,如下:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

原本a的值是5,通过指针变量pa,解引用也可以改变a的值


关于指针的大小:在32位平台是4个字节大小,在64位平台是8个字节大小,并不会因为指针类型的改变而改变!下方是VS2019的32位平台环境下的演示:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

 观察可知,无论是整型指针还是字符指针在32位平台下内存大小都是4个字节

注意:32位平台即是32个bit组成的,所以32个bit=4个byte,因此在32位平台指针是4个字节的大小,64位也是相同的道理


二、指针类型

指针类型决定了,指针在被解引用的时候所访问的权限,例如:

整型指针解引用会访问4个字节

字符指针解引用会访问1个字节

下面来具体证明这两个类型的指针的访问权限:

1、整型指针的访问权限说明:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

a为16进制0x11223344,在监视页面观察a与*pa相同,都是数值;&a与pa相同,都是地址

C语言之指针篇【超详细讲解,带你层层深入理解指针】

 观察此时内存中a的存储

C语言之指针篇【超详细讲解,带你层层深入理解指针】

输入a的地址,发现内存中存储为44 33 22 11,这里涉及到了我们前面所讲到的大小端存储,不知道的小伙伴可以到“C语言之数据的存储”那篇博客中学习

我们VS中用的是小端存储,所以说为44 33 22 11,接着运行到*pa=0后,我们再观察内存可知:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

a的值被更改为了00 00 00 00,4个字节的值都被改了 

2、字符指针的访问权限说明:

同样按照刚才的顺序,如下图:

代码部分其他都不变,只变了指针的类型

C语言之指针篇【超详细讲解,带你层层深入理解指针】

 监视和内存部分一样

C语言之指针篇【超详细讲解,带你层层深入理解指针】

当代码运行*pa=0后

C语言之指针篇【超详细讲解,带你层层深入理解指针】

我们发现,字符指针类型,解引用只能改变2个16进制位,即8个bit位,即1个byte

上面两个例子证明了不同的指针访问权限是不同的

3、指针的类型决定向前或向后一步走了多大距离

具体意思就是说指针变量加或减一,它的地址变化的量,如下所示:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

分别定义了整型指针变量pa和字符指针变量pb, 分别用%p打印地址,观察运行结果可知:

pa和pb地址相同,因为pa和pb都是指向a的地址

而pa+1和pb+1则大大不同,pa+1相对于pa加了4,而pb+1相对于pb只加了1,从这个例子中可以看出指针的类型也决定了,指针向前或向后走一步能够走多大的距离。


三、野指针相关知识

野指针就是指针指向位置是不可知的!

1、野指针的成因

①指针未初始化

这种问题非常常见,具体看如下代码;

C语言之指针篇【超详细讲解,带你层层深入理解指针】

运行后报错也会显示这种错误

C语言之指针篇【超详细讲解,带你层层深入理解指针】

 代码int* p没有初始化,所以p变量中存的地址并没有指向我们当前程序的空间,而是指向内存中随机的空间,因此要*p要访问这块内存空间肯定是出错的!

这里的p就是野指针

②指针的越界访问

这个问题可以说是非常常见的了,我们平常在遍历数组中,一不注意就会遇到这样的问题:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

我们设定数组arr,让指针变量p等于数组首元素的地址,数组本身有5个元素,但是在for循环中却循环6次,i分别是0 1 2 3 4 5,本身i是0~4的,循环时多了个5,导致非法访问内存,因此第六个数打印出来是随机数,这里也是野指针的问题了 

③指针所指向的空间释放了

这个问题也是经常遇到的问题啦,具体看下方例子:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

test函数的返回值是x的地址,main函数中用指针变量p接收x的地址,但是x变量进入test函数创建,而出了test函数会销毁,这时再改变*p的值,即使用x的地址,则是非法访问内存了,也会造成野指针的问题

2、如何规避野指针

①指针要初始化

比如上方的例子中,不能直接int* p,必须要初始化,int a = 10;int* p = &a;从而规避野指针问题

②要注意指针越界的问题

在我们使用数组时,一定要注意数组的元素个数以及我们所循环的次数,避免粗心而导致越界访问

③指针所指向的空间及时置NULL

在我们不使用指针变量p时,int* p = NULL;置为空,在接下来想要使用p时,用if语句:

if(p != NULL)  ......

能够很好地避免野指针

④避免返回局部变量的地址

就像上方野指针成因的第三条所举的例子,避免返回局部变量的地址

⑤指针使用之前检查有效性

像if(p != NULL)  ......就是在检查指针的有效性


四、常量指针和指针常量

常量指针和指针常量在题目中遇到的可算是非常多啦,它们都与const这个关键字有关,下面举三个例子,看看大家能不能分清其中的区别:

const int *pa = &a;

int const *pa = &a;

int *const pa = &a;

1、常量指针

常量指针的概念是:指针所指空间的值不能发生改变,不能通过指针解引用修改指针所指向空间的值,但是指针的指向是可以改的

2、指针常量

指针常量的概念是:指针本身就是一个常量,即指针的指向不能发生改变,但是指针所指向空间的值是可以发生改变的,可以通过解引用改变指针所指向空间的值


具体怎么更好的理解呢?

大家先看常量指针这个名字,以指针结尾,所以是具有指针的性质的,因此可以改变指向,又因为是常量指针,所以指向的值是常量的,即是不能改变的

再看指针常量这个名字,以常量结尾,应该具有常量的一些性质,所以自然不能改变指针的指向,只能修改指针所指向的值啦

那么const究竟加到代码的哪个位置才叫常量指针,加到哪个位置才叫指针常量呢?

说一个小窍门可以很快的帮助大家记住:

const如果在*的左边,那就是常量指针

const如果在*的右边,那就是指针常量

至于为什么要这样记呢,可以思考一下,*在指针中有解引用的作用,那么const在*左边,可以理解为const修饰*,即不能修改指针所指向空间的值,但是指针的指向确是没有限制的

那么const在*右边,修饰的就是指针变量啦,即指针变量不能改变它的指向,但是指针所指向空间的值不受限制

那么上面的三个例子就很明显有答案了,只需要看const修饰的是*还是指针变量即可

常量指针:const int *pa = &a;、int const *pa = &a;

指针常量:int *const pa = &a;


五、有关指针的运算 

1、指针+-整数

举个例子简单说明指针加减整数的情况:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

 指针变量p是数组第一个元素的地址,用for循环打印数组各个元素,*的优先级高于++,所以每次执行*p打印完数组中元素后,p++再指向数组下一个元素,从而循环5次打印出数组中5个元素

2、指针-指针

 指针-指针的操作得到的是指针和指针之间元素的个数,当然前提是两个指针必须指向同一块空间,下面看例子;

C语言之指针篇【超详细讲解,带你层层深入理解指针】

具体画图进行如下讲解:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

如上图所示表示数组中5个元素在内存中的存储,其中p1指向第一个元素的地址,p2表示第五个元素的地址,代码中用p2-p1,就表示的是两个指针之间的元素个数,很清楚的看到是4个元素,所以打印出来结果为4

3、指针的关系运算

指针的关系运算就是指针之间进行大小的比较,从而实现某些功能,例如:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

 圈出来的即为指针的关系运算,下方所画的图可以清楚解释:

C语言之指针篇【超详细讲解,带你层层深入理解指针】

 p刚开始是数组首元素的地址,接着通过p

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]