函数指针与指针函数:从pthread | 您所在的位置:网站首页 › 类函数指针转换为函数指针 › 函数指针与指针函数:从pthread |
Linux线程创建函数的定义是这样的: int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);其中的第三个参数void *(*start_routine)(void *)该如何理解? 一、函数指针与指针函数:函数指针: 本质是指针,指向一个函数的指针。 用法: int (*p)(int, int); //定义一个函数指针 int func(int a, int b) { } p = &func;指针函数: 本质是一个函数,函数的返回值是一个指针。 用法: int *p(void) { int *addr = (int*)malloc(sizeof(int)); return addr; } int main() { int *mem = p(void); return 0; }几点注意事项: 下面这种写法是绝对错误的: void (*p)(void) { }因为这是在定义一个函数指针,它只是一个指针,后面就不能有函数体。 &func 与 func 的区别: 函数名与对函数名取址有什么区别: 它们的值是相同的,但是表达的意思不同:func是函数的首地址,它的类型是void(),&func表示一个指向函数func这个对象的地址,它的类型是void(*)(),因此它们所代表的地址是一样的,但类型不一样。 按照&运算符本来的意义,它要求其操作数是一个对象,但函数名不是对象(函数才是对象),本来&func是非法的,但很久以前许多编译器就允许这么做。 总结: 在平时使用时,当需要传入一个函数指针做参数,直接传入函数名即可,不需要&func这样的写法。 二、pthread_create:再来看pthread_create()这个函数的第三个参数就比较好理解了: void *(*start_routine)(void *)要传入的参数是一个函数指针:(*start_routine), 这个函数的返回值类型是 (void *),入参类型是 (void *) 所以,pthread_create的使用方法是这样的: void *thread_callback(void *arg) { //do something } int main() { pthread_create(&tid, NULL, thread_callback, &arg); } 三、回调函数:1. 回调函数作用是什么? 回调函数最大的作用,就是 解耦。 如果只是为了在一个函数中调用另一个函数,普通函数也是完全可以实现的(直接在函数参数中调用另一个函数名即可),库函数只需要提供一个接口给使用者调用: void Library(void *(*Callback)(void *)) { }这样一来,只要使用者改变传进库函数的参数不同,就可以实现不同的功能,非常的灵活,并且没有丝毫改变库函数的实现,这就是解耦。 回过头来想一想,pthread_create就是这样的一种使用回调函数的方式: pthread线程库提供一个接口pthread_create供应用程序调用,应用程序将不同的线程回调函数(入口函数)传入进去,即可实现不同的线程功能: void *pthread_A(void *arg) { } void *pthread_B(void *arg) { } int main() { pthread_create(&tid_a, NULL, pthread_A, NULL); pthread_create(&tid_b, NULL, pthread_B, NULL); }参考内容: C语言回调函数详解 |
CopyRight 2018-2019 实验室设备网 版权所有 |