分类: C/C++
2009-08-18 14:29:54
我们知道一个函数在编译时会被分配给一个入口地址, 而我们也知道指针变量中只能存放地址(指针),哪么当然我们可以用指针来指向函数并调用该函数。下面是一个简单的例子:
int max(int a, int b)
{
if(a>b) return a;
else return b;
}
main()
{
int max(int a,int b);
int(*pmax)();
int x,y,z;
pmax=max;
printf("input two numbers:\n");
scanf("%d%d", &x, &y);
z = (*pmax)(x, y);
printf("maxmum=%d", z);
}
在上面的例子中我们定义了一个 int 型函数指针 int(*pmax)(); 之后把返回值为int型的函数地址赋给了 pmax 下面来调用该函数 ,如程序第 14 行 z=(*pmax)(x,y); 调用函数的一般形式为: (* 指针变量名 ) ( 实参表 ) 使用函数指针变量还应注意以下两点:
a. 函数指针变量不能进行算术运算,这是与数组指针变量不同的。数组指针变量加减一个整数可使指针移动指向后面或前面的数组元素,而函数指针的移动是毫无意义的。
b. 函数调用中 "(* 指针变量名 )" 的两边的括号不可少,其中的 * 不应该理解为求值运算,在此处它只是一种表示符号。
下面再看一个比较复杂一点的例子:指针型函数(即函数返回值为指针的函数)
我们首先来定义一个指针型函数
定义形式如下:
类型名 *函数名 (参数列表);
例如: int *a(int x ,int y);
a 为函数名 调用该函数后得到的是一个指向整型数据的地址(指针)。这里注意: *a两侧没有() 在a的两侧分别为* 和() 。在C语言中()优先级高于*,因此a先于()结合。而a(int x,int y)显然是函数形式,这个函数前面只有一个* 说明此函数十一个指针型函数 最前面的int 表示返回的指针指向整形变量。
注意:
函数指针变量和指针型函数这两者在写法和意义上的区别。如 int(*p)() 和 int *p() 是两个完全不同的量。 int(*p)() 是一个变量说明,说明 p 是一个指向函数入口的指针变量,该函数的返回值是整型量, (*p) 的两边的括号不能少。 int *p() 则不是变量说明而是函数说明,说明 p 是一个指针型函数,其返回值是一个指向整型量的指针, *p 两边没有括号。作为函数说明, 在括号内最好写入形式参数,这样便于与变量说明区别。
再让我们看看一个实际应用吧
main()
{
int i;
char *day_name(int n);
printf("input Day No:\n");
scanf("%d",&i);
if(i<0) exit(1);
printf("Day No:%2d-->%s\n",i,day_name(i));
}
char *day_name(int n)
{
static char *name[]={ "Illegal day", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "Sunday"
};
return((n<1 || n>7) ? name[0]:name[n]);
}
本程序是通过指针函数,输入一个 1 ~ 7 之间的整数, 输出对应的星期名。
下面再复杂一点 我们知道一个函数的入口地址0,现在要调用该函数 该怎么办呢(*(void (*)( ) )0)( )。
我们已知0为函数地址(指针),其调用形式为 (*0)();然而函数指针变量不能为常数,哪么把0用指针来代替。形式为(*(void (*)( ) )0)( ) 。
(void (*)( )) ,是一个返回值为void,参数为空的函数指针原型。
(void (*)( ))0,把0转变成一个返回值为void,参数为空的函数指针,指针指向的地址为0.
*(void (*)( ))0,前面加上*表示整个是一个返回值为void的函数的名字
(*(void (*)( ))0)( ),这当然就是一个函数了。