进阶指针
字符指针
概念
还有另外一种用法
还有第三种写法
但注意不是把字符串“abcdef”赋给p,而是把字符串首元素a的地址赋给p
我们知道p存的是a的地址,那么可不可以更改a呢,如下
注意:可能vs较老版本可以编译成功并输出Wbcdef,但这是完全错误的,这里先不做具体讲解。
实例
下面我们来看一个程序来更清楚的了解一下
为什么会输出haha呢,我们来分析一下
再看一下下面这个程序
那为什么这个打印hehe呢
指针数组
指针数组其实是数组,指针只是对这个数组的修饰
数组指针
概念
数组指针是指针,数组只是对他的修饰
下面举个例子
*p一定要用括号括起来,但在定义变量,并不是解引用
下面看一个程序更清晰的了解
实例
或第二种写法
但事实上,这里用数组指针完全自找麻烦,可以用简单的方法解决
所以说,数组指针可以这样用,但并不方便使用,事实上在二维数组以上才方便,下面举个例子
下面我们再用数组指针的方法(参数是指针的方式)来看一下
事实上,上面的*(
(p+i)+j)
可以写成*(
(p+i)[j])
解释:
这些输出都是一样的
总结
那下面我们看一下下面的代码各自代表什么意思
下面对parr3画图直观的观察一下
数组传参和指针传参
一维数组传参
二维数组传参
这里注意,二维数组的地址是首元素的地址,就是第一行的地址,也就是一个一维数组的地址
所以上面这两种传参方式是错误的
一维指针传参
下面看一个思考问题
二级指针传参
实际上数组也可以
函数指针
概念
函数指针是指针,这个指针指向函数,是存放函数地址的指针
首先我们先定义一个函数
注意这里有一个特殊的地方,就是&函数名和函数名都是函数的地址,函数没有首元素,所以这两个地址是相同的
调用函数
但事实上,对于函数指针来说,p前面的*
可有可无,因为我们把Add的地址赋给pa了,直接调用Add和pa效果是一样的,pa前的*
写几个也都对编译结果没影响
下面再看一个代码加深理解
那么函数的地址应该怎么保存
拓展
下面再看两段有趣的代码
有兴趣的可以自己研究一下,这里不做讨论
函数指针数组
概念
函数指针数组是一个可以存放多个函数的地址的数组
下面用代码来直观了解,首先我们先定义一个函数实现加减乘除
实例
1.初步了解使用
2.转移表(计算器)
首先打印一个菜单
然后定义几个函数
然后写程序引用函数,使用函数指针数组
指向函数指针数组的指针
回调函数
概念
举例
1.计算机例子
以上面计算机的例子来看,先定义一个函数
2.创建两个函数
打印后
3.冒号排序函数(qsort)
我们首先先回忆一下冒号排序,先定义一个函数
再调用函数
大家对这个冒泡排序可能比较熟悉,但是很显然这种方法有一定的缺陷,就是他只能排序整数型的,那么下面我们用一个新的方法,可以排序各种类型—qsort函数
下面我们先了解一下这个qsort函数
首先这个qsort函数需要一个头文件#include<stdlib.h>
其次它需要四个参数
那这四个参数分别是什么意思呢
这里注意,在自己定义的函数参数比较时,要相减返回值
再补充一个知识点
了解后我们用qsort函数对上面的冒泡排序代码进行优化
qsort的其中一大优势就是它可以比较各种类型,下面比较一下浮点型
那一个结构体也肯定可以比较,但是不能用大于小于号,而且首先我们要确定用结构体中的什么区别条件排序
比如我们先用年龄比较
再用名字比较
那如果不知道类型怎么比较
进阶指针的讲解就到这里,希望大家可以结合初级指针学习,掌握指针,指针是c的精华,学完后应多做面试题加深理解和应用,下面的博客中会介绍比较经典的面试题,希望大家可以互相学习指正错误互相进步。
坚持不懈脚踏实地才能成功,加油!
作者:吕文康
学校:山东第一医科大学
2020年11月9日