函数指针:存放函数首地址的变量
函数与数组类似,函数名代表函数首地址,且存放函数地址的指针为函数指针。
如下:
void prin() { printf(“hello ”); } int main() { void (*fp)() = prin;//fp为变量名,其余为数据类型 fp();//调用自定义函数prin,输出一次hello } 上述代码中,fp为指针名,void ( * )() 为数据类型。除此之外,函数指针还可以作为参数写入函数的参数列表,如: void prin() { printf(“hello ”); } void func( void (*fp)() ) { fp();//调用自定义函数prin,输出hello } int main() { func( prin );//调用func函数时,可将prin函数的地址作为参数写入 return 0; }
将函数指针作为参数写入参数列表的函数被称为“回调函数”。
例:
int add( int a, int b ) { return a + b; } int func( int num1, int num2, int (*fp)(int,int) )//回调函数func { return fp( num1, num2 ); } int main() { int num = add( 10, 20 ); printf( “%d ”, num );//30 int (*fp)(int,int) = add; //fp为函数指针,add为函数首地址 num = fp( 20, 20 ); printf( “%d ”, num );//40 //函数指针指向函数首地址后,可以像使用函数一样去使用指针 num = func( 20, 30, add ); printf( “%d ”, num );//50 //将函数指针作为参数后,调用时填入对应类型函数名即可 return 0; }
特殊指针:
即void *型的指针,也被称为万能指针。
万能指针可以存放任何数据类型的地址。理论上来讲,只要是一个合法的地址,都可以用万能指针存放。
如:
struct person { int age; char name[20]; char *data; }; int add( int a, int b ) { return a + b; } int main() { int num = 10; int (*f)[2][3]; char *a = “djskl”; struct person tom; void *p = # void *p1 = &a; void *p2 = &f; void *p3 = add; void *p4 = &tom; return 0; }
但是万能指针无法进行解指针的操作,且只有void *才被称为万能指针。
int main() { int num = 10; void *p = #//万能指针 void **p1 = &p;//void型二级指针,用于存放void *型变量的地址 printf( “%d ”, *p );//无法运行,无法对万能指针解指针 printf( “%d ”, *(int *)p );//对万能指针解指针需要强转为原来的类型 return 0; }