C语言专题(二):函数指针及其应用
时间:2010-08-31 来源:kangwang1988
C语言专题(二):函数指针及其应用函数指针:函数的入口地址 C程序变量驻留在程序内存空间的某个地址,它所在的地方取决于变量类型(自动变量、静态变量或全局变量等)。我们可以很容易打印变量的地址,如下所示:#i nclude int main(void) { int i = 3; printf("i resides at %p\n", &i); //i resides at 0xbfef6c44 return 0; } 在程序中,操作符&作用于变量i,要求生成i的地址,而格式化标识符%p指定输出内存地址。上述程序的可能输出如下: i resides at 0xbfef6c44 同变量一样,我们也可以打印函数的地址。下面这段代码说明了这一点:#i nclude void func(void); int main(void) { int i = 3; printf("i resides at %p\n", &i); // i resides at 0xbfe2f6f4 printf("func() resides at %p\n", &func); // func() resides at 0x80483fa // printf("func() resides at %p\n", func); // func() resides at 0x80483fa printf("main() resides at %p\n", &main); // main() resides at 0x8048368 // printf("main() resides at %p\n", main); // main() resides at 0x8048368 return 0; } void func(void) { printf("Hello, world\n"); } 对应的输出如下: i resides at 0xbfe2f6f4 func() resides at 0x80483fa main() resides at 0x8048368 实际上,函数也驻留在程序的内存空间中。地址操作符&也可以作用于函数,从而生成函数所在的地址。如何声明函数指针在C语言中,所有变量都需要声明和定义,函数指针也不例外。变量和指针的声明及定义如下: int i; int *int_ptr = &i; 很自然会联想到: int f(int arg); int *func_ptr(int arg) = &f; 实际上,由于根据运算符优先级规则,括号的优先级要比指针高,因此这种形式定义了一个指针函数,也就是一个返回指向整型数的指针的函数。函数指针的正确定义为: int f(int arg); int (*func_ptr)(int arg) = &f; 需要强调的是,函数指针和它所指向的函数应该是兼容的。下例给出了一些对函数及函数指针的错误赋值: int func(int arg) { return 0; } int *func_ptr1(int arg); int (*func_ptr2)(int arg); int (*func_ptr3)(void); double (*func_ptr4)(int arg); int main(void) { // func_ptr1 = &func; //error: invalid lvalue in assignment func_ptr2 = &func; //pass // func_ptr3 = &func; //warning: assignment from incompatible pointer type // func_ptr4 = &func; //warning: assignment from incompatible pointer type } 其中,只有第二个赋值是正确的。在示例一中,func_ptr1并不是函数指针,而是一个指向指针的函数。在示例三中,func_ptr3只能指向没有参数的函数,而函数func带有一个整型参数。而示例四中,func_ptr4只能指向返回double类型的函数,而函数func返回的是int类型。如何获得函数的地址有两种方式获取函数的地址。假设funcptr是一个函数指针。如果我们将它指向一个兼容函数func()。第一种方法使用隐式指针转换(implicit conversion to pointer): funcptr = func; 第二种方法使用显式指针转换(explicit conversion to pointer): funcptr = &func; 这两种方法都是可行的。实际上,如果在程序中有第一种形式的语句,编译器会把它自动转换为第二种方式。使用函数指针调用函数象获取函数的地址一样,通过函数指针调用函数的方法也有两种:第一种是使用显式指针(explicit dereference of the pointer),如下: extern void func(int x, int y); void (*func_ptr)(int x, int y) = func; (*funcptr)(3, 2); 第二种称为隐式指针(implicit dereference of the pointer)。 extern void func(int x, int y): void (* func_ptr)(int x, int y) = func; funcptr(3, 2); 函数指针的应用在Linux内核实现中大量使用了函数指针。待补充…