通过线程来谈指针函数和函数指针

来源:互联网 发布:免费期货行情软件下载 编辑:程序博客网 时间:2024/06/05 18:00

线程中遇到pthread_create函数第三个参数 void *(*start_routine)(void *)
这个参数代表一个指针,这个指针指向的函数必须满足以下条件:
1、函数参数只有一个为void指针,可以为任意数据类型的指针。
2、函数的返回值必须是void指针,可以为返回任意数据类型的指针

指针函数:函数返回值为指针的函数。
函数指针:指向函数名的指针为函数指针。

eg:这里有个函数是 void *func( void *)
我们用一个指向函数名的指针来做pthread_create的第三个参数

函数名指针有个特殊的地方:函数名可以直接做为指向函数的指针来使用。
定义指向函数的指针是根据函数的参数来定义的。
比如有个函数

int max( int x, int y );
我们要定义一个指向max函数的指针,我们可以这么定义 int (*p)(int,int); p=max;
这样我们就定义了一个指针p指向函数样式为 int xx(int, int)类型的函数。
这里的*p必须用括号括起来,如果不括起来编译器会认为定义了一个函数,函数的返回值类型是一个指针。
根据pthread_create的定义,我们需要给他传送一个指向 void *XXX( void * )的指针。
所以我们通常会定义一个处理函数:
void *thr_fn( void *arg )
{
printids(arg);
return NULL;
}
然后有些书上在调用pthread_create第三个参数时候喜欢写成 (void *)*thr_fn
这里做一下说明。其实我们可以直接用 (void *)thr_fn来代替他,因为thr_fn本来就是一个指针。指向自己这个函数的地址。所以我们不需要再另外定义个 void *(*p)( void *

)来保存这个函数的地址了。
所以下面几条语句是等同的
1、pthread_create( &tid, NULL, (void *)thr_fn, “hello” );
2、void *(*p)( void * ); //首先定义个指向该函数的指针
p = thr_fn;
pthread_create( &tid, NULL, p, “hello” );
3、pthread_create( &tid, NULL, thr_fn, “hello” ); //建议写法
4、pthread_create( &tid, NULL, (void *)*thr_fn, “hello” ); //书上标准写法
5、pthread_create( &tid, NULL, (void *)**thr_fn, “hello” );
6、pthread_create( &tid, NULL, (void *)***thr_fn, “hello” );

这里要说明的是 函数名作为的地址比较特殊。如果我们试着对函数名取值*thr_fn,发现取值后的地址还是个地址,也就是本身thr_fn的地址。所以不管多少次*取值都会得到同样

的结果,函数名指针就有这样一个特殊之处。换作其他变量的指针,多次用*取值后系统会找不到值,会报错。
这里有几个实例

#include <stdio.h>int main(){int a=3;int *p = &a;printf( "%x\n", (int)p );printf( "%x\n", (int)&p ); /* printf( "%x\n", (int)&&p );  对地址的位置进行取地址,编译器报错 */printf( "%x\n", (int)main );printf( "%x\n", (int)*main );printf( "%x\n", (int)**main );printf( "%x\n", (int)***main ); /* 多次*取值不会报错,函数名指针特殊性 */printf( "%x\n", (int)&main );return 0;}RedHat freelh~/pthread >gcc -Wall -o test2 test2.cRedHat freelh~/pthread >./test2bfffeb64bfffeb6080483288048328804832880483288048328