即使世界线收束,未来是可以改变的
愿你我都能通过努力,获取自己想要的人生
上一篇博客我们已经学习了指针数组,接下来我们继续来学习几个指针类型。
1.字符指针变量
经过上面几篇博客的学习,我们很容易就可以知道字符指针变量就是存字符地址的变量,字符指针变量的创建以及初始化就不详细说了,这里我通过一个例子介绍一下使用时的注意事项。
按如图方式使用指针我们会发现程序什么也没打印,并且异常退出了。
而当我们将第三行代码注释后会发现程序正常运行并且我们成功修改了字符数组中的一个元素。这个现象当然会引起我们去思考原因。
我们需要了解一下计算机是如何存储数据的。如上图,计算机在分配内存时有不同的区块,每个区块都有不同的作用(当然不仅仅以上几个分块,只是我们在C编写程序的过程中大部分时间只涉及以上几个),我们可以看到,p1指针指向的内存在常量区(常量区的数据具有常性,不可被修改),因此我们进行的*p1='d'是一个非法操作(尝试对常量区代码进行修改),在不同的编译器下运行会有不同的结果(比如有些编译器会直接报错),而数组arr却不同,它是在栈上找一块内存存储字符串,我们可以对它进行修改。
根据上面的解释,我们对于这个例子也可以有很清楚的解释了,读者自行体会。
2.数组指针(不是指针数组!!)
数组指针,即指向数组的指针,存放的时数组的地址(注意它是指针)
这里我们也仅仅简单的介绍一下它的初始化和使用,重要的是对它的理解。
我们可以知道p的作用范围是整个数组,因此我们对它进行运算操作时跳过了整个数组。
再结合以往我们学过的知识,我们进一步强化对于指针的理解和使用,对于复杂的指针使用情况,理解它们最好的方法就是画图。
如图所示,我们可以很容易就可以把它们之间的关系弄清楚,并且对于指针的计算的过程以及结果我们都很清晰,本质上p4是一个二级指针,它指向的对象是一个一级指针,对一个二级指针做加减运算就要跳过一个int*(不同类型不同),而对一个一级指针做加减运算跳过一个整形,那么指针指向的位置和对象就很明白了。
在前一篇博客中我讲述了一维数组传参的本质,接下来我们来看看二维数组传参的本质了。
我们对比这两个例子,发现他们的输出结果一模一样,上面的形参是一个完整的二位数组,而下面是一个指针数组,事实上这两种在本质上是一样的,因为arr数组名其实就是数组首元素的地址,我们通过调试可以验证
进入函数前
进入函数后
我们可以看到形参arr的值仍然和main函数中的arr的值相等,并且它的类型是一个指针数组,这些都可以验证arr数组名表示的是数组首元素地址,二维数组传参的本质就是传地址
3.函数指针变量
函数指针变量就是一个存放函数地址的变量
我们可以发现这些都有多种表现方式,这是在底层设计时的方案,我们只需知道有这些使用方法就可以。
4.typedef关键字
typedef是用来对类型重命名,使其简单化的关键字
如图使用方法,当然在我们日常学习中用的不多,但是如果你要继续往后学习(数据结构,c++等)或者是了解并实现(类似)底层将很有用。
结语:
我们现在将指针的类型学完了,刚开始学习指针时或许我们会混淆,但只要我们将指针类型弄清楚,再结合图形,对于大部分有关指针的程序分析都能弄清楚。