函数指针是一种在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. [leetcode]算法题目 - Sudoku Solver

    最近,新加坡总理李显龙也写了一份代码公布出来,大致瞧了一眼,竟然是解数独题的代码!前几天刚刚写过,数独主要算法当然是使用回溯法.回溯法当时初学的时候在思路上比较拧,不容易写对.写了几个回溯法的算法之后 ...

  2. linux 内存清理/释放命令

    1.清理前内存使用情况 free -m 2.开始清理  echo 1 > /proc/sys/vm/drop_caches 3.清理后内存使用情况 free -m 4.完成! 查看内存条数命令: ...

  3. Loom工具类:Unity3D巧妙处理多线程

    Loom代码不多,只有168行, 然而却具备了子线程运行Action, 子线程与主线程交互的能力! public static Thread RunAsync(Action a) public sta ...

  4. WEB API 中HTTP的get、post、put,delete 请求方式

    一.WEB API 中HTTP 请求方式的四个主要方法 (GET, PUT, POST, DELETE), 按照下列方式映射为 CURD 操作: 1.POST 用于新建资源,服务端在指定的URI 上创 ...

  5. matlab 画图数据导入

    http://www.yiibai.com/matlab/matlab_data_import.html Python 执行py 文件: 在要执行文件处按shift右击鼠标打开cmd 命令窗口,输入: ...

  6. tomcat设置端口号和默认webapp

    tomcat一下载,解压之后webapps目录下自带几个webapp: * docs文档:这是一个静态页面集,不用启动tomcat也可以阅读 * examples样例 * hostmanager主机管 ...

  7. java泛型中的对象

    import java.util.HashMap; class Key { String s; Key(String s) { this.s = new String(s); } @Override ...

  8. Java反射机制学习与研究

    Java反射机制:可以获取正在运行时的Java对象. 1.判断运行时对象对象所属的类. 2.判断运行时对象所具有的成员变量和方法. 3.还可以调用到private方法,改变private变量的值. S ...

  9. 在Ubuntu 14.04安装Nginx

    ###介绍 Nginx是世界上最流行的网络服务器中的一种,负责托管网络上一些流量最高的网站.在多数情况下,Nginx比Apache在资源上更加友好,可以作为网络服务器或反向代理服务器. 这篇教程中,我 ...

  10. 【BZOJ 2194】快速傅立叶之二

    随便代换一下把它变成多项式乘法,及$C[T]=\sum_{i=0}^{T}A[i]×B[T-i]$这种形式,然后FFT求一下就可以啦 #include<cmath> #include< ...