C语言函数指针的用法
函数指针是一种在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语言函数指针的用法的更多相关文章
- C#委托与C语言函数指针及函数指针数组
C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...
- C语言函数指针基础
本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...
- c/c++ 函数指针的用法
[目录] 基本定义 c 函数指针使用举例 c++ 函数指针使用举例 函数指针作为函数参数 函数指针作为函数返回值 函数指针数组 typedef 简化函数指针操作 c语言函数指针的定义形式:返回类型 ( ...
- IOS typedef 函数指针的用法
代码简化, 促进跨平台开发的目的. typedef 行为有点像 #define 宏,用其实际类型替代同义字. 不同点:typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换. 用 ...
- C语言函数sscanf()的用法
从文件读取数据是一件很麻烦的事,所幸有sscanf()函数. C语言函数sscanf()的用法 sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型: int sscanf( st ...
- “对外部(局部)变量的访问”是C语言函数指针的最大弱点
1.“对外部(局部)变量的访问”是C语言函数指针的最大弱点 . #include <stdio.h> #include <stdlib.h> /* 结构体定义 */ struc ...
- (转)typedef 函数指针的用法
typedef 函数指针的用法 在网上搜索函数指针,看到一个例子.开始没看懂,想放弃,可是转念一想,这个用法迟早要弄懂的,现在多花点时间看懂它,好过以后碰到了要再花一倍时间来弄懂它.其实很多时候都 ...
- C语言函数指针 和 OC-Block
C语言函数指针 和 OC-Block 一. C语言函数指针 关于函数指针的知识详细可参考:http://www.cnblogs.com/mjios/archive/2013/03/19/2967037 ...
- C语言函数sscanf()的用法(转)
转自:http://www.cnblogs.com/lyq105/archive/2009/11/28/1612677.html C语言函数sscanf()的用法 sscanf() - 从一个字符串中 ...
随机推荐
- 用H5+Boostrap做简单的音乐播放器
前言:这个是综合一下我最近在学的东西做的小Demo,到实际使用还有距离,但是用来练手巩固知识点还是不错的,最近在二刷JS书和Boostrap.css的源码,做完这个Demo也算是暂告一段落,接下来是j ...
- mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理
1.mvc5+ef6+Bootstrap 项目心得--创立之初 2.mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理 3.mvc5+ef6+Bootstrap 项目心得--WebG ...
- 我的 GitHub 100 连击
终于达成 gayhub 的第一个100连击了,感觉自己整个人颜色都不一样了,完全蜕变了. PS: GitHub 汉化插件 52cik/github-hans 感兴趣的赶紧 get 起来吧. 遇到瓶颈 ...
- 系统升级日记(1)- 升级到SQL Server 2012
最近一段时间在公司忙于将各类系统进行升级,其最主要的目标有两个,一个是将TFS2010升级到TFS2013,另外一个是将SharePoint 2010升级到SharePoint 2013.本记录旨在记 ...
- [BZOJ1564][NOI2009]二叉查找树(区间DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1564 分析: 首先因为每个点的数据值不变,所以无论树的形态如何变,树的中序遍历肯定不变 ...
- Exif
Exif是一种图像文件格式,它的数据存储与JPEG格式是完全相同的.实际上Exif格式就是在JPEG格式头部插入了数码照片的信息,包括拍摄时的光圈.快门.白平衡.ISO.焦距.日期时间等各种和拍摄条件 ...
- MATLAB中plot()画图的颜色线型和希腊字母参数设置
y 黄色 · 点线 m 粉红 ○ 圈线 c ...
- 【JavaEE企业应用实战学习记录】logFilter
package sanglp.servlet; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import ja ...
- yii2权限控制rbac之详细操作步骤
本篇的主题是 rbac权限控制的详细操作步骤,注意是操作步骤哦,关于配置与rbac的搭建,我们在博文 yii2搭建完美后台并实现rbac权限控制实例教程说的再清楚不过了. 但是,在很多人的反馈下,说是 ...
- 模拟发送http请求
1.httpie 2.postman:Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件. 3.fiddler