源码翻阅之函数指针
源码阅读之函数指针
很久没有在****上面更新博客了。主要是因为自己觉得博客的文章太水,不好意思发到****上面,所以就全部发到了自己的个人博客上面。
当然如果大家有兴趣,可以去 miibotree.com光临我的个人技术博客。
最近想提高一下阅读源码的水平,主要是因为拿到一份源代码之后自己连编译都要编译半天。面对编译时候产生的各种各样错误,毫无头绪的感觉很糟糕。所以下定决心要多阅读别人的源代码,学习开源代码来增加自己写代码的能力。
函数指针在c语言中应用范围很广,可以理解成c++中的成员函数。
下面自己写了个简单的代码来说明下函数指针的用法。
#include <stdio.h> int Fun (int x); //定义了一个函数 int CallFun(int, int(*Fun)(int)); //定义了一个函数指针作为参数的函数 int main() { int (*p)(int); //定义了一个函数指针 p = Fun; //函数指针的赋值 p(1); //通过函数指针调用Fun函数 CallFun(2, Fun); //通过把函数指针作为参数调用Fun函数 CallFun(3, p); //通过把函数指针作为参数调用Fun函数 return 0; } int Fun (int x) { printf("Fun is called\n"); return 0; } int CallFun(int param1, int(*Fun)(int x)) { Fun(4); return 0; }现在有这样一个函数:
int Fun (int x);
我们通过下面的方法定义了一个函数指针:
int (*p) (int);
这条语句说明了我们定义了一个函数指针p,返回值是int类型,有一个int类型的参数。因为这个函数指针的返回值类型和形参类型跟fun函数完全一样,所以我们可以进行下面的赋值操作:
p = Fun;
将Fun函数的地址赋值给p
接下来我们调用p其实就是调用了Fun函数。其实也就相当于给Fun函数起了个别名。
将函数指针作为参数的用法其实也是很常见的,下面这个函数定义了一个函数指针作为参数的函数:
int CallFun(int, int(*Fun)(int));
调用的时候直接把函数名作为形参传进去:
CallFun(2, Fun);
在CallFun函数里面可以直接调用Fun函数了
Fun(4);
下面来看个例子好了:
该例子选自《代码阅读方法与实践》提供源码中的 netbsdsrc/sbin/restore/tape.c
有下面两个函数:
static void xtrmap __P((char *, long)); static void xtrmapskip __P((char *, long));
两个函数的具体实现如下:
/* * Collect the next block of a bit map. */ static void xtrmap(buf, size) char *buf; long size; { memmove(map, buf, size); map += size; } /* * Skip over a hole in a bit map (should never happen). */ /* ARGSUSED */ static void xtrmapskip(buf, size) char *buf; long size; { panic("hole in map\n"); map += size; }
getfile的两个参数就是这两个函数的函数指针
void getfile(fill, skip) void (*fill) __P((char *, long)); void (*skip) __P((char *, long)); { ... }在程序里面就这样调用:
getfile(xtrmap, xtrmapskip);