目录
1>>前言
今天我会继续分享一些我做的笔记,以及我对指针的理解, 后续会持续分享指针几天,毕竟指针的内容太多了,一天我也学不完,也分享不完,感谢大家理解,希望我的文章对大家有所帮助,谢谢!
2>>野指针
先来聊聊指针,我们知道指针是地址,也就是某个变量的地址,那么前面加上了一个“野”字,生活中“野”有点“无家可归”的意思,那么在计算机中也是差不多,野指针就是“无家可归”的指针,它们没有明确的指向某个变量的地址,可能是随机的地址,这就是野指针。
2.1>>野指针是如何形成的?
那么它是如何形成的呢?其实不难知道,如我们的指针未进行初始化,那么编译器就会随便赋给它一个地址。还有数组越界,当超出数组范围的时候,p就是野指针。
2.2>>那么我们如何规避野指针呢?
首先,指针的初始化是必不可少的。其二,需要小心数组越界,其三,指针变量不再使用时,及时回收。如两个函数指针在其中一个函数结束时已经销毁,然后函数2继续使用,那么这个指针就会形成野指针最后。避免返回局部变量的地址,如:
这个n在函数结束已经销毁,那么返回的必然是一个没用的地址,那么此时p就会形成野指针。
3>>assert断言
有时候代码太长我们无法确定该指针是不是野指针时,就可以使用assert断言。
其格式为:assert(真)——执行,assert(假)——报错。
大家知道野指针会返回一个空值,在之前文章讲到过NULL是一个空指针,那么我们就可以用assert判断(注意:assert的使用需要一个头文件——#include<assert.h>):
我们p是一个空指针,空不等于空结果为假,那么就会报错。
assert还有一个点:如果我们程序检查完了没问题,不需要做断言,那么可以在上方上面加入#define NDEBUG
这样编译器就不会执行assert代码。
4>>指针的传地址调用
通过题目我们更好理解:使用函数实现两个变量的交换。以下是错误示范:
观察可以发现以上代码并没有交换成功,这是为什么?因为函数传参数的时候,传递的是它们的值,并没有把地址传过去,ab,xy是四个不同地址,那么对xy的修改也只能交换xy的值,并没有对ab进行操作,那么要实现对ab的操作,就得把ab的地址传过去,并且函数需要用指针变量进行接收,请看:
那么此时就可以完成题目,这便是指针的传址调用。
5>> 数组名的理解
给定一个数组arr,内有十个元素为1到10,如果使用&arr是取谁的地址呢?在这之前我们学到过sizeof,并用sizeof求出过数组元素个数:
那么我们取地址arr得到的是什么呢?arr既然等于&arr[0]第一个元素地址,那么sizeof为什么还等于40呢?带着这些疑问我们来看:
可以看到它们取出来的地址都一样,那究竟有什么不同呢?继续看:
这能看到只有&arr取出来的地址加了40,而40刚好是这个数组所有元素大小相加,由此我们可以得知,&arr取出来的是整个数组的地址。那为什么sizeof(arr)=40呢?注意:这里有两个例外,遇到sizeof和&数组名的时候是整个数组,其他时候都是取首元素地址。
6>>数组and指针的等价打印
这是我们常用的打印,我们还可以使用arr+i然后解引用,arr表示首元素地址,若i=1那么arr+i就表示第一个元素地址。
arr又等于p,所以还可以这样:
和这样
arr[i]在编译器底层也会转换为*(arr+i)的方式执行。
7>>结语
今天学习了很多内容,以学习笔记+经验的方式呈现给大家,希望能得到大家喜欢。谢谢大家!
另外希望得到大佬解答:有没有大佬说说指针是不是C语言最多的内容呀,学完指针还有没有更难更多的内容。