c难于理解的是指针,其魅力之处也是指针,函数方法结构,化繁为简可以理解为:返回值 函数名(形参表),具体来说:

返回值:1.可以为空void

    2.基本数据类型char short int long float double

    3.指针

形参表跟返回值一样,这里面最复杂最难理解的是指针,因为指针本身是一个变量,里面保存的是地址,而地址的类型是由指针定义的时候申明的,而指针又可以指向函数,这样一搭配就非常复杂了。我们从一个复杂的程序开始:

          void(*signal(int sig_num,void(*handler)(int)))(int)

第一看到都会头晕,不过抽丝剥茧之后发现也就那么回事。从最外层分析: void(*fb)(int),这是一个函数指针,fb=signal(int sig_num,void(*handler(int)))。这是一个函数,只不过这个函数一个参数是int,一个参数是函数指针。

两个这么一结合,发现fb是函数,这个函数返回值是一个函数指针,而这个函数指针指向的函数返回值是void 参数是int。只不过这些写难以理解,但是利用typedef将这个函数指针“封装”起来就很好理解了。

  typedef void(*func_p)(int);

上面是将func_p声明为 void ()(int)这样函数结构的函数指针。创造了一种新的指针类型,那么signal函数就可以简化成:

  func_p signal(int sig_num,func_p p);

这么一写,就跟我们平常使用的函数结构一样了,好理解多了。

注意定义函数指针的写法: void (*funcP)(void)。指向void ()(int)函数的,这与基本数据类型指针不同:int* ip;

至于函数返回值又是函数指针的情况,那样的写法了解一下就行,一般用typedef简化。至于调用函数指针指向函数的方式就调用函数的写法一样。

//自定义func_p为新的指针类型
typedef void (*func_p)(int); void callback(int x)
{
printf("callback:%d\r\n",x);
}
//普通函数返回值是指针
int* function(int* p)
{
int* q;
q = (int*)malloc(sizeof(int)*);
*q = *p;
return q;
}
//函数返回值是函数指针,函数体的参数是普通指针
void (*function1(int* p))(int)
{
printf("p:%d\r\n",*p);
return callback;
}
//函数返回值是函数指针,而函数形参也有函数指针,注意函数指针作为函数形参的写法
void (*function3(int*p,void(*handler)(int)))(int)
{
void (*func_temp)(int);//函数指针的写法,与形参handler写法是一样的。
func_temp = handler;
printf("p:%d\r\n",*p);
return handler;//函数的返回值是函数指针,这里形参的函数指针类型与返回值函数指针的类型是一样的都是void ()(int)
}
//利用typedef定义的新指针类型重写的函数,更好理解。
func_p function2(int* p)
{
printf("p:%d\r\n",*p);
return callback;
}

验证:

int main(int argc, char *argv[]) {
int a = ;
int* iq;
void (*funcp)(int);
void (*funcp2)(int) = callback2;//定义函数指针并赋值,直接赋函数名
funcp2();
iq = function(&a);//函数值是指针,注意这里返回的指针是函数中在堆空间申请的空间,如果不free是不会被收回的。
//而函数体中定义的零时指针是函数栈空间。当函数体结束会被收回。因此返回的是无效地址。 funcp = function3(&a,callback2);//调用函数返回值跟参数都是函数指针的函数。function3有一个普通指针参数。
//将函数callback2传入,这个函数会被返回给funcp。这个时候函数指针指向的函数体是callback2
funcp(); //执行指向的函数体
printf("ret:%d\r\n",*iq);
system("pause");
return ;
}

执行结果:

函数指针与指针函数以及typedef的更多相关文章

  1. (60) 结构体指针、结构体变量嵌套、结构体指针嵌套、函数指针、数组指针、指针数组、typedef 综合运用

    #include<stdio.h> #include<iostream> #include<malloc.h> /* author : 吴永聪 program: 结 ...

  2. [Reprint]C++普通函数指针与成员函数指针实例解析

    这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下   C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般 ...

  3. C:函数指针、回调函数

    函数指针 是一个指针,指向函数的指针,指针存放的都是地址,所以函数指针存放的是函数的地址.数组名就是数组的首地址,函数名就是函数的首地址.与数组类似. 代码demo int (*p) (int ,in ...

  4. Callback函数详解(我感觉,回掉函数的本质是函数指针,在业务做循环处理的时候,调用一下通知外部)

    2010年的最后一天了,转载一篇自己认为还不错的文章与大家分享.希望对大家有所帮助. 一,回调函数 我们经常在C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理.用回调函数记录某操作进度 ...

  5. 【转】 C++易混知识点2. 函数指针和指针函数的区别

    我们时常在C++开发中用到指针,指针的好处是开销很小,可以很方便的用来实现想要的功能,当然,这里也要涉及到指针的一些基本概念.指针不是基本数据类型,我们可以理解他为一种特殊类型的对象,他占据一定空间, ...

  6. c++指针函数的使用——回调函数

    /* 函数指针 函数也是有地址的 所谓函数指针,就是指向函数的指针,函数指针也是一个变量,可以指向不同的函数.同时通过函数指针可以调用其指向函数,从而使函数的调用更加灵活. 函数指针的用途 */ #i ...

  7. C++ —— 返回数组指针的函数 和 返回指向函数的指针的函数

    返回数组指针的函数 基础知识:数组不能被拷贝,函数不能返回数组,只能返回数组的指针或者引用. 定义一个 返回数组指针的函数 的方法,以 一个接收参数为 含有10个整型元素的数组的引用  和 返回一个含 ...

  8. C语言 函数指针一(函数指针的定义)

    //函数指针 #include<stdio.h> #include<stdlib.h> #include<string.h> //函数指针类型跟数组类型非常相似 / ...

  9. C++(二十二) — 指针变量、函数指针、void指针

    1.指针变量 (1)指针变量必须在初始化后才可以正常使用,初始化就是给他分配一个有效的数据地址. 先初始化,后使用. (2)指针可以进行加减运算,++ 或者 --:将指针的位置向前或者向后移动一个数据 ...

随机推荐

  1. Wordpress基础:文章和页面的区别

    页面: 页面是你可以单独建立一个固定页面,可以作为留言板,或者通知的单页面,发布之后是固定的网址. 页面并不能被分类.亦不能拥有标签,但是它们可以有层级关系.您可将页面附属在另一个页面之下. 对应模板 ...

  2. iOS下Html页面中input获取焦点弹出键盘时挡住input解决方案—scrollIntoView()

    问题描述 iOS系统下,移动web页面,inpu获取焦点弹出系统虚拟键盘时,偶尔会出现挡住input的情况,尽管概率不大,但是十分影响用户体验. 问题重现 原始页面:页面中有header.main.f ...

  3. 协程并发框架gevent及其用法

    gevent是python的一个并发框架,采用协程实现并发目的,用起来也非常简单 gevent的docs:http://www.gevent.org/contents.html 一个最简单的例子: i ...

  4. css使input中的值自动变大写

    <style type="text/css"> input { text-transform:uppercase; } </style>

  5. JSP中的指令(Directive)

  6. mac 启动 docker daemon

    我是用virtualbox安装的. 有一个小问题就是启动docker服务时会检查boot2docker是不是最新的. 由于github被封了,所以只能手动下 https://github.com/bo ...

  7. Android 5.1 open data flow 数据开启流程

    首先我们来看看下面的关系图: 底层Settings.apk 在Settings -> Data Usage Summary中的某个SIM tab下开启数据开关 android/packages/ ...

  8. 夺命雷公狗-----React---3--标签的规则

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. LoadRunner脚本设计、场景设计和结果分析

    本次笔记主要记录LoadRunner脚本设计.场景设计和结果分析   1. 脚本设计       录制模式            手工模式:插入步骤.手动编写       1.1  脚本增强:     ...

  10. 较全的IT方面帮助文档

    http://www.shouce.ren/post/d/id/108632 XSLT参考手册-新.CHMhttp://www.shouce.ren/post/d/id/108633 XSL-FO参考 ...