博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言函数指针
阅读量:5742 次
发布时间:2019-06-18

本文共 1637 字,大约阅读时间需要 5 分钟。

   

一、函数的指针:

#include "stdafx.h"

 

#include <stdio.h>

#include "t.h"

 

void Function(int i)

{

    printf("Call Function: %d\n", i);

}

 

void f1()

{

    typedef void (*PFUNC)(int);

    PFUNC pfunc;

    pfunc = Function;

    pfunc(1);    

    

    pfunc = &Function;

    pfunc(2);

}

 

 

void f2()

{

    typedef void (FUNC)(int);

    

    FUNC* pfunc;

    pfunc = Function;

    pfunc(3);

 

    pfunc = &Function;

    pfunc(4);    

 

}

 

void t2()

{

    f1();

    f2();

}

/*

Call Function: 1

Call Function: 2

Call Function: 3

Call Function: 4

请按任意键继续. . .

*/

二、函数指针拆解:

#include<signal.h>

void (*signal(int signo,void(*func)(int)))(int);

 

1、使用typedef拆解

typedef void(*sighandler_t)(int);

sighandler_t signal(int signum,sighandler_t handler);

 

2、使用函数指针理解

int (*p)();

p指向的是一个不带任何参数,并且返回值为int的函数;

int (*fun())();

这个式子与上式区别在于用fun()代替p,即fun()返回值是一个函数指针,这个函数指针(可以看作p),指向一个不带任何参数,并且返回值为int的函数;因此,对于

void (*signal(int signo,void(*func)(int)))(int);

可以看成是signal()函数,此函数带两个参数:一个为整型,一个为函数指针。而这个signal()函数的返回值也为一个函数指针,这个函数指针指向一个带一个整型参数,并且返回值为void的函数。

 

这个函数过于复杂,本身没有任何意义,通常都是使用typedef之后的简单信号处理函数。

 

3、实例分析

1、实例源代码

 

2、执行程序

 

3、查看进程号

 

4、给进程发送信号

 

5、进程接收到信号

 

   

三、(*(void(*) ())0)()------这是什么?

  是不是感觉上面的例子太简单,不够刺激?好,那就来点刺激的,看下面这个例子:

1

(*(void(*) ())0)();

这是《C Traps and Pitfalls》这本经典的书中的一个例子。没有发狂吧?下面我们就来分析分析:

1

2

3

4

第一步:void(*) (),可以明白这是一个函数指针类型。这个函数没有参数,没有返回值。

第二步:(void(*) ())0,这是将0强制转换为函数指针类型,0是一个地址,也就是说一个函数存在首地址为0的一段区域内。

第三步:(*(void(*) ())0),这是取0地址开始的一段内存里面的内容,其内容就是保存在首地址为0的一段区域内的函数。

第四步:(*(void(*) ())0)(),这是函数调用。

好像还是很简单是吧,上面的例子再改写改写:

1

(*(char**(*) (char **,char **))0) ( char **,char **);

如果没有上面的分析,肯怕不容易把这个表达式看明白吧。不过现在应该是很简单的一件事了。读者以为呢?

 

 

参考:

1. 关于"void (*signal(int signo,void(*func)(int)))(int)"的剖析http://www.51hei.com/bbs/dpj-29464-1.html

2. 语言函数指针的理解与使用;

 

转载地址:http://yonzx.baihongyu.com/

你可能感兴趣的文章
eclipse中git的使用
查看>>
ajax请求
查看>>
django orm
查看>>
python中的 == 和 is
查看>>
检查密码复杂度的C#正则表达式
查看>>
C# 中 async/await 调用传统 Begin/End 异步方法
查看>>
C# 为什么使用了多线程界面假死?
查看>>
ConfigParser模块&hashlib模块&subprocess模块
查看>>
读取数据库信息构建视图字段的备注信息,方便程序代码生成
查看>>
uva 11027 Palindromic Permutation
查看>>
uva 10587 Mayor's posters
查看>>
bzoj2820(莫比乌斯反演)
查看>>
开启WordPress维护模式,站点临时关闭
查看>>
.NET平台4.0 发布网站流程及出错总结
查看>>
python 第三方库的加载与虚拟机的登录
查看>>
Vue系列:关于侵权前言
查看>>
DL学习笔记-CNN 相关知识
查看>>
关于<context:annotation-config/>配置
查看>>
jquery中的attr与prop
查看>>
Alpha阶段发布说明
查看>>