如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针(指向函数的指针)。
函数指针说的就是一个指针,但这个指针指向的函数,不是普通的基本数据类型或者类对象。指向函数的指针包含了函数的地址,可以通过它来调用函数。
声明格式:类型说明符 (*函数名)(参数)
函数返回值类型 (* 指针变量名) (函数参数列表);
其实这里不能称为函数名,应该叫做指针的变量名。这个特殊的指针指向一个返回整型值的函数。指针的声明必须和它指向函数的声明保持一致。
函数指针的定义就是将“函数声明”中的“函数名”改成“(*指针变量名)”。但是这里需要注意的是:“(*指针变量名)”两端的括号不能省略,括号改变了运算符的优先级。如果省略了括号,就不是定义函数指针而是一个函数声明了,即声明了一个返回值类型为指针型的函数。
那么怎么判断一个指针变量是指向变量的指针变量还是指向函数的指针变量呢?
首先看变量名前面有没有“*”,如果有“*”说明是指针变量;其次看变量名的后面有没有带有形参类型的圆括号,如果有就是指向函数的指针变量,即函数指针,如果没有就是指向变量的指针变量。
最后需要注意的是,指向函数的指针变量没有 ++ 和 — 运算。
int (*f)(int a, int b); // 声明函数指针 - 当然,函数指针的返回值也可以是指针。
上面的函数指针定义为一个指向一个返回值为整型,有两个参数并且两个参数的类型都是整型的函数。下面是利用函数指针分别求两个整数的最大值和最小值的用法。
例1.通过函数指针计算出三个数最大的值
# include <stdio.h> int Max(int, int); //函数声明 int main(void) { int(*p)(int, int); //定义一个函数指针 int a, b, c; p = Max; //把函数Max赋给指针变量p, 使p指向Max函数 printf("please enter a and b:"); scanf("%d%d", &a, &b); c = (*p)(a, b); //通过函数指针调用Max函数 printf("a = %d\nb = %d\nmax = %d\n", a, b, c); return 0; } int Max(int x, int y) //定义Max函数 { int z; if (x > y) { z = x; } else { z = y; } return z; }
例2. 打印三次Hi
#include <stdio.h> void Hi_function (int times); /* function */ int main() { void (*function_ptr)(int); /* function pointer Declaration */ function_ptr = Hi_function; /* pointer assignment */ function_ptr (3); /* function call */ return 0; } void Hi_function (int times) { int k; for (k = 0; k < times; k++) printf("Hi\n"); }
A. 定义并声明一个标准函数Hi_function,该函数在调用函数时将k次打印Hi文本(由参数指示)
B.定义了一个函数指针(带有其特殊的声明),该函数带有一个整数参数并且不返回任何内容
C.使用Hi_function初始化函数指针,这意味着指针指向Hi_function()
D. 不是通过使用参数点击函数名称来调用标准函数,而是通过将数字3作为参数来仅调用函数,仅此而已!
wer