1. 指向函数的指针
在上一节中,我们讨论了声明器。 声明器可以允许程序员声明各种不同的数据类型。例如:基础变量,数组,指针等等。 这一节中,我们结合声明器讨论一类特殊的指针类型。 这种指针类型不是简单地指向基础变量或是数组,而是指向函数,即函数指针。 既然函数指针指向函数,那么我们写一个函数作为讨论的对象。
int print(char *pc)
{
int count = 0;
while(*pc != '\0')
{
putchar(*pc);
pc++;
count++;
}
putchar('\n');
return count;
}
这个函数的参数为一个char *
类型的指针,指向一个字符串的首元素。
函数内部逐个打印字符串的元素,每输出一次,计数器加1,直到遇到'\0'
为止。
现在我们想要一个函数指针指向名为print
的函数。
在写这个函数指针的声明之前,我们再次回忆一下声明器中的操作符优先级:
优先级从高到低依次如下:
- 括号
()
。 - 函数声明的
()
与数组声明的[]
优先级相同。 - 指针声明的
*
。
好的,现在我们根据操作符优先级写出这个函数指针。
- 首先,它是一个指针。
(*p)
- 这个指针指向一个函数
(*p)(char *)
- 函数的返回值为int,
int (*p)(char *)
int (*p)(char *)
即为这个函数指针的声明。
当然,写一个函数指针还有一个更方便的方法。
- 首先写出这个函数的声明
int print(char *)
- 将函数名替换成指针名
int p(char *)
- 在指针名前加星号
*
并用括号包括,int (*p)(char *)
我们通过声明器写出了这个函数指针的声明。现在这个函数指针p,没有有效的指向。我们让它指向print
函数。
int (*p)(char *) = print;
类似于数组在表达式中转换为指向首元素的指针。函数出现在表达式中,将转换为指向该函数的指针。因此函数print
可以用于初始化函数指针p
。
在32位程序中指针的空间大小始终为4字节。很显然函数指针p
的空间大小为4字节。若64位程序,则p
的空间大小为8字节。
但是,你现在肯定会想到是否能对函数本身使用sizoef
关键词测量大小呢?
由于函数类型的大小没有太大的实际意义,在各种编译器里面有可能有各种不同的表现。 在visual studio 2019中,对函数本身使用sizeof无法通过编译。
所以,这里不再讨论对函数类型本身使用sizeof
。