指针的进阶(C语言)(下)

目录

4、数组参数、指针参数传参

4.1一维数组传参

4.2二维数组传参

4.3 一级指针传参

4.4 二级指针传参

5、函数指针

6、函数指针数组

7、指向函数指针数组的指针

8、回调函数

总结


续上篇

4、数组参数、指针参数传参

        在写代码的时候难免把【数组】或者【指针】传给函数,那函数的参数如何设计呢?

4.1一维数组传参

        指针的进阶(C语言)(下)_第1张图片

        对于arr1和arr2来说,这五种形式的传参都是合理的。

4.2二维数组传参

指针的进阶(C语言)(下)_第2张图片

        上面的例子说明,二维数组传参,函数的形参只能省略第一个,因为对于一个二维数组,可以不知道有多少行,但是必须知道每一行有多少个元素,这样才能对数据进行分配。

        现在我们用指针进行传参:

指针的进阶(C语言)(下)_第3张图片

        只有第三种指针(数组指针)传参是可行的。

4.3 一级指针传参

        指针的进阶(C语言)(下)_第4张图片

        如此一个函数,实现对数组的打印,实参部分传递指向数组首元素地址的指针p,以及记录数组大小的sz。形参接收用一个一维指针和一个整型变量接收。

        (思考:如果函数的形参是一维指针,那实参可以传什么呢?答案:整型变量的地址&a;指针*p;数组名.....)

4.4 二级指针传参

指针的进阶(C语言)(下)_第5张图片

        对于二级指针传参,需要用二级指针接收,或者对于&指针传参,接收也是需要二级指针的。

        (思考:如果函数的形式参数是二级指针,调用该函数时,可以传什么类型的变量过去?答案是:二级指针;&数组名;&指针;指针数组.....)

5、函数指针

        数组指针:指向数组的指针就是数组指针

        函数指针:指向函数的指针就是函数指针        

函数也有地址码?先看一段代码:

指针的进阶(C语言)(下)_第6张图片

        的确,函数也是有地址的。所以我们可以用一个指针去指向函数,这样的指针就是函数指针。对于函数来说,取地址函数名和函数名都是函数的地址。

指针的进阶(C语言)(下)_第7张图片

        那么我们怎么去创建指针,去存放函数的地址呢?创建好之后又如何使用呢?指针的进阶(C语言)(下)_第8张图片

        看到这个代码,我们知道,函数指针的创建其实跟数组指针又异曲同工之妙,使用时只需要调用指针解引用并将要传的参数写入,就能得到函数运行后的返回值。在前期,这样的指针看上去没有很大用处,但是到了之后写一些较为复杂的代码时,函数指针的作用就会体现出来。

        简单讲一个用法:当我们想引用一个函数,传参为另外一个函数时,这时的形参就只能用函数指针接收。所以,函数指针的出现,让我们能够将函数作为参数传给另外一个函数,为代码提供了新的可能。

6、函数指针数组

        数组是一个存放同类型数据的存储空间,那么函数指针数组就好理解了,函数指针数组就是一个存放类型都为函数指针的数组。

指针的进阶(C语言)(下)_第9张图片

        上面这个例子,arr就是一个函数指针数组,它存放了四个函数指针,这四个函数指针分别指向函数:Add、Sub、Mul、Div。由于这四个函数的函数返回值,函数参数都是同类型的,所以可以放在一个数组中。

        如何通过函数指针数组调用函数指针:

指针的进阶(C语言)(下)_第10张图片

        arr[0]其实就是指向Add的函数指针,实现的是加法运算,发现结果如预期,所以调用成功。

        如此就可以调用函数指针数组中的函数指针,注意,这里我和前面调用函数指针不一样,我没有加*,也就是( (*arr[0])(1 , 2) ),加上这个*和不加都可以去调用函数指针所指向的函数,加上*是方便理解一点,不加其实也没问题,这是函数指针数组的独特特性,其他指针访问时一定要加上*。

        函数指针数组的运用,要配合函数指针,在以后实现复杂功能的程序编写时,运用函数指针数组,可以极大地简化程序地修改和优化成本。

7、指向函数指针数组的指针

        指向函数指针数组的指针,其实还是一个指针,只不过其内容是函数指针数组的首地址,指向函数指针数组。

        如何定义,如何运用:指针的进阶(C语言)(下)_第11张图片

        可以看到,只需要在定义函数指针数组的形式的基础上,再加一个*去声明指针pfarr即可,在运用时,用*进行解引用之后就跟函数指针数组的用法相同,可以看到,上面也例子也是成果调用了arr数组中第一个指针所指向的函数Add的功能。

        对于函数指针数组的指针,运用情况较少,但也是有运用的可能的,所以可以大概了解一下。

        接下来,我们要将一个很重要的知识了:回调函数。

8、回调函数

          回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方法直接调用,而是在特定事件或条件发生时由另外的一方调用,用于对该事件或条件进行影响。(就是我在说函数指针的作用时提到过的)

        指针的进阶(C语言)(下)_第12张图片

        如此,就是回调函数的简单流程。在函数B中,有一个参数是指向A的函数指针,在函数B中可以通过PA函数指针去调用函数A。

        举例:qsort函数

指针的进阶(C语言)(下)_第13张图片

        对于qsort函数,它可以比较任意数据的大小并排序,我们观察它的形参(上图),发现其中有一个函数指针类型:int(*cmp)(const void* e1,const void* e2)。

        这其实就是一种函数回调,qsort函数内调用了另一个函数cmp,根据数据的大小(单位字节)来对应地调用cmp这个函数。指针的进阶(C语言)(下)_第14张图片

        实现了排序。

总结

        本篇文章按顺序讲解了数组、指针传参;函数指针;函数指针数组;指向函数指针数组的指针;回调函数。是c语言进阶的指针篇。

你可能感兴趣的:(c语言学习,c语言,开发语言)