1、函数指针的引出

假设我们需要写个函数

sort( start, end, compare );

对start 和end 之间的数组元素进行排序compare 定义了比较数组中两个字符串的比较操作。如果我们需要比较的数组是string类型,那么排序方式,也许是按照字典序列,也许是串长度,也许是出现频率,那么怎么方便的进行比较呢?

众所周知,C语言的一大精髓就是指针,那么对此,我们同样可以引入指针来解决。这里的解决方案就是函数指针:讲第三个参数compare 设为函数指针并由它指定要使用的比较函数。从而方便的进行各种比较。

2、函数指针的使用

1)声明

怎么声明一个函数指针呢?

int (*pf)( const string &, const string & ); // ok: 正确

如上,声明了一个函数指针,注意的是,解引用操作符* 应与返回类型关联所以在这种情况下是与类型名int 关联而不是pf 要想让解引用操作符与pf 关联,所以括号是必需的,而不能声明为:

int *pf( const string &, const string & );

2)初始化、赋值和调用

a. 函数指针可以用0 来初始化或赋值以表示该指针不指向任何函数。

b.直接去想要调用的函数名,如add,注意,这里没有括号。为什么呢?我们知道不带下标操作符的数组名会被解释成指向首元素的指针当一个函数名没有被调用操作符修饰时会被解释成指向该类型函数的指针,例如表达式

lexicoCompare;

被解释成类型

int (*)( const string &, const string & );

的指针,这里,lexicoCompare定义如下:

#include

int lexicoCompare( const string &s1, const string &s2 ) {

return s1.compare(s2);

}

c.将取地址操作符作用在函数名上也能产生指向该函数类型的指针因此lexicoCompare和&lexioCompare 类型相同

对于初始化和赋值的示例如下:

int (*pfi)( const string &, const string & ) = lexicoCompare;//初始化

pfi = lexicoCompare;//赋值

看到这个赋值,楼主想到2个地方,一个是在严蔚敏版数据结构的源代码中,BFS和DFS中的visit函数,都是定义为的函数指针,当时的定义为:

void(*VisitFunc)(char* v); /* 函数变量(全局量) */

传参时如本例提出,将参数作为函数指针传入

void DFSTraverse(ALGraph G,void(*Visit)(char*))

另外一个,是在flex的ActionScrip中的addEnentListen(),如

addEventListener(Event.CLOSE, closeHandler);

closeHandler则是作为函数指针传入,虽然在as入门书上讲是引用,不过引用,不就是弱化版指针呢么?(其实对于引用,C++Primer有一句简要的概括:

引用是没有指针语法的指针。比如调用时指针用->,引用用点操作符)。

3、问题的解决

下面用函数指针解决开始提出的sort问题,funcP.h代码如下:

#include

#include

using namespace std;

typedef int ( *PFI2S )( const string &, const string & );

int lexicoCompare( const string &s1, const string &s2 )

{

return s1.compare(s2);

}

void sort( string *s1, string *s2,PFI2S compare = lexicoCompare )

{

// 递归的停止条件

if ( s1 < s2 )

{

string elem = *s1;

string *low = s1;

string *high = s2 + 1;

for (;;)

{

while ( compare( *++low, elem ) < 0 && low < s2) ;

while ( compare( elem, *--high ) < 0 && high > s1) ;

if ( low < high )

low->swap(*high);

else break;

} // end, for(;;)

s1->swap(*high);

sort( s1, high - 1, compare );

sort( high + 1, s2, compare );

} // end, if ( s1 < s2 )

}

main.cpp如下:

#include "funcP.h"

string as[10] = { "a", "light", "drizzle", "was", "falling",

"when", "they", "left", "the", "museum" };

int main()

{

// 调用 sort(), 使用缺省实参作比较操作

sort( as, as + sizeof(as)/sizeof(as[0]) - 1 );

// 显示排序之后的数组的结果

for ( int i = 0; i < sizeof(as)/sizeof(as[0]); ++i )

cout << as[ i ].c_str() << endl;

return 0;

}

程序使用了typedef使程序可读性更强,并提供了默认参数(关于默认参数这种偷懒的东东,理解为初始化对话框内容这样,以后可改,只是提供初值。只是这样的初始化,很符合常规思维,理念上更可取)

4、一些注意的问题

在指向函数类型的指针之间不存在隐式类型转。也就是,只有当赋值操作符左边指针的参数表和返回类型与右边函数或指针的参数表和返回类型完全匹配时初始化和赋值才是正确的如果不匹配则将产生编译错误消息。在灵活性上,更注重了安全性,高级货啊!

关于函数指针,还可以参考https://www.coonote.com/cplusplus-note/c-fun-pointer.html这个简单明了,很清晰易懂。

c语言visit函数指针,C++中的函数指针总结相关推荐

  1. C语言printf重入,单片机中printf函数的重映射

    单片机中printf函数的重映射 一.源自于:大侠有话说 1.如果你在学习单片机之前学过C语言,那么一定知道printf这个函数.它最最好用的功能 除了打印你想要的字符到屏幕上外,还能把数字进行格式化 ...

  2. findmid函数c语言,excel find函数用法_excel中mid函数的用法教程详解

    [www.gpsvo.com--管理学] Excel中经常需要使用到mid函数进行截取数据,mid函数具体该如何使用操作呢?下面是由小编分享的excel中mid函数的用法,以供大家阅读和学习. exc ...

  3. matlab stem函数坐标轴_MATLAB中stem函数用法

    stem(Y) 将数据序列Y从x轴到数据值按照茎状形式画出,以圆圈终止.如果Y是一个矩阵,则将其每一列按照分隔方式画出. stem(X,Y)在X的指定点处画出数据序列Y.  stem(...,'fil ...

  4. 递归重入c语言延时函数多任务程序设计中的函数重入问题按照Keil的规范对函数添加关键字“reentrant”,将函数定义为可重入的 void Delay_MS(x) reentrant

    c语言延时函数_子牙篇(2)多任务程序设计中的函数重入问题 weixin_39559333 2020-11-29 09:07:44  39  收藏 文章标签: c语言延时函数 c语言延时函数delay ...

  5. java assert函数_assert函数-论java中assert函数和Python、PHP、C语言assert函数

    assert函数广泛在java.Python.PHP.C语言中存在,都有统一的意义,用业界语言称之为"断言".最初的出发点都是为了方便调试而设计的,但是最近越来越多的开发者不分测试 ...

  6. c 打印 callback 函数名_Go 中的函数

    1. 函数参数和返回值的写法 如果有多个参数是同一个类型,可以简略写: func testReturnFunc(v1,v2 int)(int,int) {x1 := 2 * v1x2 := 3 * v ...

  7. python在工厂中的应用_什么是工厂函数?Python 中工厂函数怎么理解?

    其实谈工厂函数前必须首先把嵌套作用域和闭包讲清楚 python有一个很有意思的地方,就是def函数可以嵌套在另一个def函数之中.调用外层函数时,运行到的内层def语句仅仅是完成对内层函数的定义,而不 ...

  8. linux下mkdir头文件_Linux中mkdir函数与Windows中_mkdir函数的区别

    下面先来给大家介绍windows下_mkdir函数 #include int _mkdir( const char *dirname ); 参数: dirname是目录的路径名指针 返回值: 如果新目 ...

  9. python count函数代码_python中count函数简单用法

    python中count函数简单用法 python中count函数的用法 Python count()方法 描述 Python count() 方法用于统计字符串里某个字符出现的次数.可选参数为在字符 ...

最新文章

  1. Asp.net 不使用SQLDMO实现数据库备份和还原
  2. CTFshow php特性 web91
  3. CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学)
  4. 小白都能看懂的干货!大数据这朵“后浪”,能卷起多大的风浪?
  5. 客制化键盘键位修改_IQUNIX Slim87 RGB机械键盘评测
  6. JavaScript 字符串截取方法汇总
  7. Windows API一日一练(17-18)DialogBox DialogBoxParam EndDialog函数
  8. java18.取球游戏,12种球类游戏,想怎么玩就怎么玩!
  9. TYUT太原理工大学2022需求工程考试选择题背诵版
  10. 欧姆龙服务器数码管不显示问题,数显仪表常见故障的原理分析以及解决方案
  11. linux中IGV的运行,科学网—使用UCSC和IGV查看reads在基因组上分布情况 - 熊朝亮的博文...
  12. 求和符号的定义和性质
  13. python中mapping_python-学习-ORM中遇到的 mapping 详解并再总结字典dict
  14. 每个人都至少需要4个邮箱账户(附国内外数十个免费邮箱)
  15. 矩阵“特征值”要表示什么“特征”
  16. 2013移动开发工具盘点:最火原型设计工具
  17. Email和电子邮箱一样吗?
  18. 自己动手配置AMD 5600g 主机
  19. weakauras教程_魔兽世界:WeakAuras 教程3利用WA基础完成标准监控套件
  20. xc7z030有多少个quad_XC7Z030-1FFG676I全新原装【科美奇科技】XILINX一级渠道商

热门文章

  1. 15个Spring的核心注释示例
  2. 研究优雅停机时的一点思考
  3. C语言32位数加一精简,一个简单的32位多任务操作系统的实现(1)
  4. 16进制ff转化为二进制_3秒钟快速转换十六进制为二进制
  5. PP-YOLOv2开源,你的目标检测器又该升级了!性能超越YOLOv5且推理耗时保持不变
  6. torch nll_loss
  7. python url请求
  8. struct.error: 'h' format requires -32768 number 32767
  9. access violation reading 0x0000000000000020
  10. python 内存二进制读取图片