源码阅读之函数指针

很久没有在CSDN上面更新博客了。主要是因为自己觉得博客的文章太水,不好意思发到CSDN上面,所以就全部发到了自己的个人博客上面。

当然如果大家有兴趣,可以去 miibotree.com光临我的个人技术博客。

最近想提高一下阅读源码的水平,主要是因为拿到一份源代码之后自己连编译都要编译半天。面对编译时候产生的各种各样错误,毫无头绪的感觉很糟糕。所以下定决心要多阅读别人的源代码,学习开源代码来增加自己写代码的能力。

函数指针在c语言中应用范围很广,可以理解成c++中的成员函数。

下面自己写了个简单的代码来说明下函数指针的用法。

#include 

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);


你可能感兴趣的:(c/c++)