一、指针函数的定义

指针函数,顾名思义,返回指针的函数。其一般定义形式如下:

类型名 *函数名(函数参数列表);

其中,后缀运算符括号()表示这是一个函数,其前缀运算符星号*表示此函数为指针型函数,其函数返回值为指针,当调用这个函数后,将得到一个“指向返回值为…的指针(地址),类型名表示函数返回的指针指向的类型”。

“(函数参数表列)”中的括号为函数调用运算符,在调用语句中,即使函数不带参数,其参数表的一对括号也不能省略。其示例如下:

int *pfun(int, int);

*的优先级低于()的优先级,因而pfun首先与后面的()结合,也就意味着pfun是一个函数。即:

int* (pfun(int, int));

接着和前面的*结合,说明该函数的返回值是一个指针。再前面是一个int,也即 pfun 的返回值是一个返回值为整型类型的函数。

二、函数指针

指向函数的指针;

int (*pfun)(int, int);

返回值为int,是不可再被*取值的;

int* (*pfun)(int, int);
==
int *pfun(int, int);

函数指针通过括号强制性的将pfun首先与*结合,也就意味着,pfun是一个指针,接着与后面的()结合,说明该指针指向的是一个函数,最后与前面的int结合,也就意味着,该函数的返回值是int

虽然仅有一个括号的差别,但表示的意义却截然不同。

  • 函数指针(如同整型指针int*)的本质是一个指针,只不过指向的类型不是一般的基本数据类型,而是函数,对该函数的返回值没有要求,也可以为指针;

  • 指针函数的本质是一个函数,其函数的返回值是一个指针;

三、以函数指针作为函数的返回值

分析如下的函数声明:

int (*ff(int))(int, int);

*的优先级小于()ff首先与()结合,意味着ff(int)的返回值为指针(这称为指针函数),再与后面的()结合,也即该指针指向的是一个函数。

这种写法易让人产生误解,更非常难懂。一般来说,用typedef关键字会使该声明简单易懂;

typedef int (*PF)(int, int);

typedef是类型定义关键字,也即int (*pf)(int, int); 此时pf是一个函数指针变量,当使用typedef声明后,PF就成为了一个函数指针关键字。这样,我们便可使用PF作为返回值来声明函数;

PF ff(int);

四、以函数指针为返回值的应有实例

求序列最值和平均值:

#include <stdio.h>
#include <assert.h>typedef double(*PF)(double *, int );double GetMin(double* seq, int sz)
{double minVal = seq[0];assert(sz > 0);for (int i = 1; i < sz; ++i)if (minVal > seq[i])minVal = seq[i];return minVal;
}double GetMax(double* seq, int sz)
{double maxVal = seq[0];assert(sz > 0);for (int i = 1; i < sz; ++i)if (maxVal < seq[i])maxVal = seq[i];return maxVal;
}
double GetAverage(double* seq, int sz)
{double sum = 0.;    assert(sz > 0);for (int i = 0; i < sz; ++i)sum += seq[i];return sum / sz;
}double Unknown(double* seq, int sz)
{return 0;
}PF GetOp(char c)
{switch (c){case 'd':return GetMin;case 'x':return GetMax;case 'p':return GetAverage;default:return Unknown;}
}int main(int, char**)
{double dbData[] = { 3.1415926, 1.4142, -0.5, 999, -313, 365 };int sz = sizeof(dbData) / sizeof(dbData[0]);char c;fputs("please input the operation: ", stdout);c = getchar(); printf("%f\n", GetOp(c)(dbData, sz));return 0;
}

我们看到,由typedef定义的函数指针类型实际上是给出一种接口规范

References

[1] 深入理解指针函数

C 基础——指针函数与函数指针相关推荐

  1. go语言基础(二)函数,数组,指针,结构体

    目录 函数 匿名函数 函数闭包的简单使用以及获取键盘输入 闭包加上函数多返回值 为什么闭包不会被垃圾回收 defer 内置函数panic.recover 语言变量作用域 数组 数组定义 数组+函数+宏 ...

  2. C语言基础知识之define宏定义表达式,undef,内存对齐,a和a的区别,数组知识点,int (*)[10] p,二维数组参数与二维指针参数,函数指针数组,常见的内存错误及对策

    一.用define宏定义表达式 1.定义一年有多少秒: #define SEC_A_YEAR 60*60*24*365 //上述描述不可靠,没有考虑到在16位系统下把这样一个数赋给整型变量的时候可能会 ...

  3. C语言基础10——指针进阶。字符指针、指针数组、数组指针、函数指针、函数指针数组、回调函数、数组名详解、杨氏矩阵、字符串旋转

    目录 字符指针 指针数组 数组指针 数组传参.指针参数 函数指针 函数指针数组 指向函数指针数组的指针 回调函数 练习 数组名的意义 指针笔试题 字符指针 字符指针的另一种使用方式 #include ...

  4. 【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

  5. 指向成员函数的指针有什么用_指针函数,函数指针,有点懵圈了?你能分清楚吗...

    指针函数和函数指针到底怎么区分? 1.前言 数组.指针,这两个词结合的顺序不同,其意义也不同. 同样的,函数.指针这两个词结合的顺序不同其意义也不同,即指针函数与函数指针的意义不同. 2.指针函数 指 ...

  6. 数组指针和指针数组,函数指针和指针函数,常量指针和指针常量,常量引用

    一.数组指针和指针数组 1.数组指针(行指针) 首先要知道数组指针是指向数组的指针.所以数组指针本质是个指针,只不过指向一个数组而已.格式为:T (*ptr)[]. 注意:"[]" ...

  7. 【C/C 】浅谈C/C 中函数指针与回调函数

    01.函数指针 1.1.函数指针定义 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似.我们可以把函数的这个首地址(或称入口地址)赋予 ...

  8. 指针结构体函数-事实上能够这样具体理解

    今天一大早登了下QQ空间,看到本科的一个学弟发表一篇日志.写关于西电微软俱乐部面试题的解答,写的非常不 错. 我也一下子起兴了,由于我以前也是被指针困惑非常久.搞不清头绪,本科到研究生.我也笔试面试不 ...

  9. 函数指针与回调函数、句柄

    函数指针 定义: 函数指针是指向函数的指针变量. 因而"函数指针"本身首先应是指针变量,只不过该指针变量指向函数.这正如用指针变量可指向整型变量.字符型.数组一样,这里是指向函数. ...

最新文章

  1. java定时关机源码_java实现电脑定时关机的方法
  2. 用人工智能打击人工智能
  3. 【控制】《多智能体系统的协同群集运动控制》陈杰老师-第7章-Brunovsky 型高阶非线性多智能体系统一致性控制
  4. 怎么求星期几的后几天C语言,计算任何一天是星期几的C语言源代码.
  5. Excel 文件读取
  6. POJ - 3683 Priest John's Busiest Day(2-SAT+路径打印)
  7. 编程语言API性能大比拼
  8. 简历要求中“ 扎实的JAVA基础”的学习方法
  9. 洛谷——P1706 全排列问题
  10. 外键查询_详解MySQL数据库删除所有表的外键约束、禁用外键约束相关脚本
  11. 计算机专业方面的期刊介绍
  12. tp5 查询求和_TP5 Or查询的几种方法
  13. 2019-CS224n-Assignment1
  14. dagger2 使用无法自动生成dagger + component 等问题集錦
  15. USACO 2016 JANUARY CONTEST, BRONZE PROBLEM 3. MOWING THE FIELD(收割庄稼)
  16. 1995-2013年RSA大会历届主题回顾
  17. Java后端春秋招之旅
  18. How I Hacked Facebook with a Word Document
  19. Excel#整体增加相同行高的宏命令#
  20. 考试管理系统-刷题系统案题目选项编写

热门文章

  1. Phoenix命令及语法
  2. Spark SQL介绍和特点
  3. PAT甲级 1017 Queueing at Bank
  4. 荣耀play3 鸿蒙,荣耀play系列跳过2直接上3代,999元的配置还能愉快play吗?
  5. python实现点击按钮_python实现点击按钮修改数据的方法
  6. Pandas——如何更改DataFrame中的值
  7. LeetCode 39. 组合总和(回溯+剪枝)
  8. OpenGL+VS2012环境搭建
  9. php redis zset 延迟队列_用PHP+Redis实现延迟任务,实现自动取消订单
  10. Windows下Redis的使用