`
duoerbasilu
  • 浏览: 1541883 次
文章分类
社区版块
存档分类
最新评论

void (*f(int, void (*)(int)))(int) 函数解析

 
阅读更多

函数指针

今天与几个同学看到了一个函数指针定义:

void (*f(int, void (*)(int)))(int)

以前在C trap pit fails里面见过,但是文章里面介绍的很详细,但是往往使初学者抓不到重点, 结果弄的一头污水。这里就简单介绍一下这中函数指针的定义方法。

什么是函数指针?

这个问题从定义的角度来看很好理解,指向函数的指针就是函数指针,但是我们如何声明一个函数指针呢?又如何将一个地址强制转换为某一个类型的函数指针呢?这里看下面一个例子源码:

void function(int a)

{

a = 5;

}

void (*pfunc)(int);

很简单,上面这段代码声明了一个函数fucntion和一个函数指针pfunc, 它指向的函数就是一个具有void返回值,int参数的函数。如果将function函数的地址给pfunc指针,可以简单的通过下面两种赋值:

pfunc = function;

或者

pfunc = &function

通过指针调用该函数,也有两种方法:

pfunc(5); (*pfunc)(5);

我们看一下赋值语句,pfunc = function; 但有时候可能是一个常数0x8999940, 它恰好也表示一个安全的与function相同的函数,如何将这个数值赋给pfunc呢?显然我们需要强制类型转换,应该将该常数转换成什么类型呢?这就是问题的关键!

在void (*pfunc)(int)语句里面,只有pfunc是变量名称,那么剩余的部分,void(*)(int),就是我们需要的转换类型。因此,新的赋值语句是:

pfunc = (void (*)(int)) 0x8999940;

赋值完成后,就可以通过pfunc(5); 或 (*pfunc)(5);调用相应的函数了。

如果理解了上面的内容,我们就可以解释void (*signal(int, void (*)(int)))(int)这个相对复杂的问题了

返回函数指针的函数声名

现在我们先抛开上面那个复杂的定义,先看一下下面的需求1) 定义一个函数;2) 该函数具有以下特点,两个参数,返回值是函数指针,并且一个参数也是函数指针。假如返回值和参数函数指针同为void (*)(int); 另一个函数参数是int型。该函数定义名称为my_func。

根据需求我们可以很容易定义出这种函数:

typedef void (*HANDLER)(int); //参数函数和返回函数定义

HANDLER my_func(int, HANDLER);

突然需求中又不让使用typedef,这就是早期C语言不支持typedef的情况,那么如何定义这种函数呢?

我们假如说my_func的返回值是int,是不是它的定义可以这么写:

int my_func(int, void (*)(int));

也就是说,my_func(int, void (*)(int))就是一个int型数据。现在将int换成一个函数,也就是

void (*)(int) my_func)(int, void (*)(int);

这样一种定义,显然这种语法不支持,那么,实际是如何表示呢?回过头来,我们先看看函数指针的声明格式

void (*pfunc)(int)

其中pfunc 等价于 void (*)(int)。现在在看看上面的格式,是不是很相识,对了,pfunc就是my_func(int, void (*)(int))现在如果将两者代替一下是不是就成了这种格式:

void (*my_func(int, void(*)(int)))(int)

如果将my_func换成signal,是不是就是我们文章开始提到的那个复杂声名?现在是不是明白了,原来如此啊,它是一个返回函数指针的的函数声名!

分享到:
评论

相关推荐

    斗转星移代码

    编写形如void fun(int *a1, int *b1, int *a2, int *b2)的函数,该函数帮助姑苏慕容将四个形参指向的整数互换(a1指向的整数与a2指向的整数互换,b1指向的整数与b2指向的整数互换)。 在主函数main()中输入四个...

    操作系统(基本操作、轮换调度)完整代码

    操作系统实验课轮换调度算法的代码~ ... /*优先级输入函数*/ void Create2(); /*时间片输入函数*/ void Priority(); /*按照优先级调度*/ void RoundRun(); /*时间片轮转调度*/ void InitialInterface(); /*初始界面*/

    C语言程序设计-请编一个函数void fun(int tt[M][N],int pp[N]),tt指向一个M

    C语言程序设计-请编一个函数void fun(int tt[M][N],int pp[N]),tt指向一个M行N列的二维数组,求出二维数组每列中最大元素,并依次放入pp所指一维数组中;二维数组中的数已在主函数中赋予;.c

    void及void指针含义的深刻解析

    - **内存管理函数**:`malloc`, `calloc`, `realloc` 和 `free` 等内存管理函数经常返回 `void *` 类型的指针,以便它们能够适应任何类型的数据。 ```c++ void *ptr = malloc(sizeof(int)); int *p = (int *)ptr...

    void指针小结

    - **用于函数参数**:当一个函数不需要接收任何参数时,可以在函数声明中使用`void`表示这一点。例如`void func(void)`表示该函数没有参数。 - **void指针**:`void*`是一种特殊类型的指针,它可以指向任何类型的...

    tong_xun_lu.rar_int enter_读文件 list

    /*** 以下是函数原型*******/ int enter(ADDRESS t[]) /*输入记录*/ ...int find(ADDRESS t[],int n,char *s) /*查找函数*/ int menuSelect() /*主菜单函数*/ void clrscr(void) void gotoxy(int,int)

    ios socket demo

    简单Demo , 对socket 各个函数运用 核心代码 socket即网络, 这就是咱所用网络(NSURLSession/Connection/AFN...等)最底层代码了 // 创建 int socket(int domain, int type, int protocol); // 连接 int connect(int,...

    int main和int main(void)区别

    ### int main 和 int main(void) 的区别 在 C 和 C++ 编程语言中,`main` 函数作为程序的入口点,其定义方式对于理解程序的行为至关重要。尤其是在 C 和 C++ 中,`main` 函数的定义存在一定的差异,这涉及到函数的...

    关于C++中void*的小作用浅析

    在函数`o`中,我们看到了`void*`的使用,它接受一个`int*`和一个`void*`作为参数。这里的`void*`参数`y`可以接收任何类型的指针,只要在调用时进行适当的类型转换。例如,`&b`是一个`int`类型的指针,可以安全地赋值...

    Project组织应用

    void aMAX_MIN_AVE(int *a, int n, int &max, int &min, int &aver) { max = min = a[0]; // 初始化 int sum = 0; for (int i = 0; i ; i++) { sum += a[i]; if (a[i] > max) max = a[i]; if (a[i] ) min = a...

    深入学习C语言中memset()函数的用法

    void * memset( void * ptr, int value, size_t num ); 参数说明: ptr 为要操作的内存的指针。 value 为要设置的值。你既可以向 value 传递 int 类型的值,也可以传递 char 类型的值,int 和 char 可以根据 ASCII...

    五子棋源代码

    /*显示欢迎信息函数*/ void DrawBox(void); /*画棋盘函数*/ void Corrd(void); /*坐标对应数组board[a][b]*/ void DrawCircle(int x,int y,int color); /*画圆函数*/ void Alternation(void); /*交换行棋方函数*/ ...

    void的含义.docx

    2. **void 函数**: 当函数不返回任何值时,我们会使用`void`作为返回类型,如`void function();`。这表明调用该函数不会得到任何结果。 3. **void 指针**: `void*`是一个通用指针类型,它可以指向任何数据类型。...

    C语言函数库-第四章(字符串函数)

    - **函数原型**:int memcmp(const void *s1, const void *s2, size_t n); - **功能**:比较前 `n` 字节的两个内存区域 `s1` 和 `s2`。 #### memcpy - **函数原型**:void *memcpy(void *dest, const void *src, ...

    语言函数库-第七章(其它函数)

    - **是否是标准函数**:是 - **函数功能**:异常终止一个进程,并向 `stderr` 打印一条终止信息:“Abnormal program termination”。 - **返回值**:无返回值。 #### 例程 ```c #include #include int main...

    void指针的深刻理解.pdf

    在C/C++编程中,`void`关键字和`void`指针扮演着至关重要的角色,尤其是在处理不同类型数据和函数参数时。本文将深入探讨`void`的含义以及`void`指针的使用方法。 首先,`void`表示“无类型”,意味着它不关联任何...

    void_指针 使用

    ### void指针深入解析 #### 一、引言 在C/C++编程语言中,`void`关键字及其关联的`void`指针类型是经常被提及但又常常被忽视的概念。初学者往往容易忽略`void`及其指针类型的重要性和用途,导致在实践中遇到不少...

    void详解.docx

    - **无参数函数**:当函数不需要接收任何参数时,使用`void`作为参数列表,如`int func(void)`。 - **通用指针参数**:`void *`可以作为函数参数,使得函数能够接受任何类型的指针。例如,`memcpy`和`memset`函数...

    DES算法c语言

    11. **`F(int* rData, int* key)`**: Feistel函数,是DES的核心部分。 12. **`Expand(int* rData, int* rDataP)`**: 扩展函数,将32位数据扩展为48位。 13. **`ExchangeS(int* rDataP, int* rData)`**: S盒变换函数...

Global site tag (gtag.js) - Google Analytics