函数指针是一种在C、C++、D语言、其他类 C 语言和Fortran 2003中的指针。函数指针可以像一般函数一样,用于调用函数、传递参数。在如 C 这样的语言中,通过提供一个简单的选取、执行函数的方法,函数指针可以简化代码。

函数指针只能指向具有特定特征的函数。因而所有被同一指针运用的函数必须具有相同的参数和返回类型。

本文地址:http://www.cnblogs.com/archimedes/p/3669872.html,转载请注明源地址。

下面的代码说明了一种初始化函数指针的方法:

int f(int);
int (*fp)(int) = &f; //使用三种方式调用函数
int ans;
ans = f();
ans = (*pf)();
ans = pf();

以下为函数指针在C中的简单运用:

#include <stdio.h>

int max(int x, int y)
{
return x > y ? x : y;
} int main(void)
{
/* p 是函数指针 */
int (* p)(int, int) = & max; // &可以省略
int a, b, c, d; printf("please input 3 numbers:");
scanf("%d %d %d", & a, & b, & c); /* 与直接调用函数等价,d = max(max(a, b), c) */
d = (* p)(( *p)(a, b), c); printf("the maxumum number is: %d\n", d);
return ;
}

下面介绍函数指针最常见的两个用途:作为参数传递给另一个函数(回调函数)、转换表

1、回调函数:

下面有一个简单的函数,用来在单链表中查找一个给定的值

Node* search_list(Node* node, int const value)
{
while(node != NULL) {
if(node->value == value)
break;
node = node->next;
}
return node;
}

一种更加通用的方法就是使该函数能用任何类型值的链表,必须修改函数,使它与类型无关。解决的方案就是使用函数指针。

#include <stdio.h>
#include "node.h" Node *search_list( Node *node, void const *value,
int (*compare)( void const *, void const * ) )
{
while( node != NULL ){
if( compare( &node->value, value ) == )
break;
node = node->next;
}
return node;
}

在特定的链表中进行比较的时候,用户需要编写适当的比较函数,并把指向该函数的指针和指向需要查找的值的指针传递给查找函数,下面是一个整型链表中查找的比较函数:

int compare_ints(void const *a, void const *b)
{
if( *(int *)a == *(int *)b)
return ;
else
return ;
} //这个函数将像下面这样调用
desired_node = search_list(root, &desired_value, compare_ints);

如果你希望在一个字符串链表中进行查找,下面的代码可以完成任务:

#include<string.h>
...
desired_node = search_list(root, "desired_value", strcmp);

再看一个完整的例子:

#include<stdio.h>
struct object
{
int data;
}; int object_compare(struct object * a,struct object * z)
{
return a->data < z->data ? : ;
} struct object *maximum(struct object * begin,struct object * end,int (* compare)(struct object *, struct object *))
{
struct object * result = begin;
while(begin != end)
{
if(compare(result, begin))
{
result = begin;
}
++ begin;
}
return result;
} int main(void)
{
struct object data[] = {{}, {}, {}, {}, {}, {}, {}, {}};
struct object * max;
max = maximum(data + , data + , & object_compare);
printf("max: %d\n", (*max).data);
return ;
}

2、转移表

下面的程序是一个简化的根据运算符转到相应运算的例子:

#include<stdio.h>

double _add(double, double);
double _sub(double, double);
double _mul(double, double);
double _div(double, double); double _add(double a, double b)
{
return a + b;
} double _sub(double a, double b)
{
return a - b;
} double _mul(double a, double b)
{
return a * b;
} double _div(double a, double b)
{
return a / b;
} int main(void)
{
int n;
enum Operation{ADD, SUB, MUL, DIV}op;
double a, b, ans;
a = 0.232332;
b = 0.234398;
printf("请输入一个整数(0-3): ");
scanf("%d", &n);
op = (enum Operation)n;
switch(op) {
case ADD:
ans = _add(a, b);
break;
case SUB:
ans = _sub(a, b);
break;
case MUL:
ans = _mul(a, b);
break;
case DIV:
ans = _div(a, b);
break;
default:
break;
}
printf("%lf\n", ans);
return ;
}

使用可以使用转换表来实现相同的任务,转换表就是一个函数指针数组,代码如下:

#include<stdio.h>

double _add(double, double);
double _sub(double, double);
double _mul(double, double);
double _div(double, double); double _add(double a, double b)
{
return a + b;
} double _sub(double a, double b)
{
return a - b;
} double _mul(double a, double b)
{
return a * b;
} double _div(double a, double b)
{
return a / b;
} int main(void)
{
int n;
double a, b, ans;
a = 0.232332;
b = 0.234398;
printf("请输入一个整数(0-3): ");
scanf("%d", &n); double (*oper_func[])(double, double) = {
_add, _sub, _mul, _div
}; ans = oper_func[n](a, b);
printf("%lf\n", ans);
return ;
}

C语言函数指针的用法的更多相关文章

  1. C#委托与C语言函数指针及函数指针数组

    C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...

  2. C语言函数指针基础

    本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...

  3. c/c++ 函数指针的用法

    [目录] 基本定义 c 函数指针使用举例 c++ 函数指针使用举例 函数指针作为函数参数 函数指针作为函数返回值 函数指针数组 typedef 简化函数指针操作 c语言函数指针的定义形式:返回类型 ( ...

  4. IOS typedef 函数指针的用法

    代码简化, 促进跨平台开发的目的. typedef 行为有点像 #define 宏,用其实际类型替代同义字. 不同点:typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换. 用 ...

  5. C语言函数sscanf()的用法

    从文件读取数据是一件很麻烦的事,所幸有sscanf()函数. C语言函数sscanf()的用法 sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型: int sscanf( st ...

  6. “对外部(局部)变量的访问”是C语言函数指针的最大弱点

    1.“对外部(局部)变量的访问”是C语言函数指针的最大弱点 . #include <stdio.h> #include <stdlib.h> /* 结构体定义 */ struc ...

  7. (转)typedef 函数指针的用法

    typedef 函数指针的用法   在网上搜索函数指针,看到一个例子.开始没看懂,想放弃,可是转念一想,这个用法迟早要弄懂的,现在多花点时间看懂它,好过以后碰到了要再花一倍时间来弄懂它.其实很多时候都 ...

  8. C语言函数指针 和 OC-Block

    C语言函数指针 和 OC-Block 一. C语言函数指针 关于函数指针的知识详细可参考:http://www.cnblogs.com/mjios/archive/2013/03/19/2967037 ...

  9. C语言函数sscanf()的用法(转)

    转自:http://www.cnblogs.com/lyq105/archive/2009/11/28/1612677.html C语言函数sscanf()的用法 sscanf() - 从一个字符串中 ...

随机推荐

  1. <实训|第五天>通过搭建NFS,FTP实现共享文件附Vim脚本游戏

    先说个事情:我周末是不更新这个系列教程的,不过其他内容的会更新,我周末就整理这一周的各种内容到我的微信公众号中,提供给大家! 期待已久的linux运维.oracle"培训班"终于开 ...

  2. JavaScript中call,apply,bind方法的总结。

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...

  3. RabbitHub开源情况及计划

    之前写过一篇".NET 平台下的插件化开发内核(Rabbit Kernel)",已经过去三个月了,期间RabbitHub并不是没有了发展更不是放弃了发展,在RabbitHub中的群 ...

  4. 【对noip结束后一个月内的总结】

    最近在刷一些树结构,但发现没有一个提纲,觉得有点不知所措,经常学完一个就发现还有比它更好的,而且比较耗时间.于是沙茶准备按顺序刷bzoj的省选题,看看效果怎么样……求大神指教

  5. Vware Workstation pro 12|虚拟机

    Vmware是比较不错的PC虚拟化软件,vmware11+不在支持32的系统安装!体积比之前小了很多 VMware 12 官方中文页面 http://vmware.com/cn/products/wo ...

  6. Beta版冲刺Day1

    会议讨论: 628:        已经成功实现了文件的上传功能,但是按钮的布局有点不好看.未完成的功能有:修改老师信息时候弹出小窗口进行修改. 601:        目前还在解决剩下的问题,比如将 ...

  7. Error: [ng:areq]

    错误描述:Error: [ng:areq] http://errors.angularjs.org/1.4.8/ng/areq?p0=HelloCtrl&p1=not%20a%20functi ...

  8. 显示当前用户所拥有的表&当前用户可以访问的所有表&数据库中的所有表&当前用户信息&当前用户所能管理的用户&数据库中所拥有的用户

    1)显示当前用户名称:show user或者show user; 2)显示当前用户信息(包括用户名之外还有其他信息):select * from user_users; 3)显示数据库中所含有的所有用 ...

  9. 高手详解SQL性能优化十条经验

    1.查询的模糊匹配 尽量避免在一个复杂查询里面使用 LIKE '%parm1%'—— 红色标识位置的百分号会导致相关列的索引无法使用,最好不要用. 解决办法: 其实只需要对该脚本略做改进,查询速度便会 ...

  10. 树分治 poj 1741

    n k n个节点的一棵树 k是距离 求树上有几对点距离<=k; #include<stdio.h> #include<string.h> #include<algo ...