#include "stdio.h"
int mode = 0,a = 0;
void func1(void);
void func2(void);
void func3(void);
void func1(void) {
printf("这是第一个函数\n");
}
void func2(void) {
printf("这是第二个函数\n");
}
void func3(void) {
printf("这是第三个函数\n");
}
int main() {
void (*pfunc[3])(void) = {func1,func2,func3};
scanf_s("%d", &mode);
switch (mode) {
case 1:
pfunc[0]();
(*(*pfunc))();
printf("%p\n", &*pfunc);
printf("%p\n", &pfunc[0]);
printf("%p\n", *pfunc);
printf("%p\n", pfunc[0]);
printf("%p\n", *pfunc[0]);
printf("%p\n", &*pfunc[0]);
printf("%p\n", **pfunc);
printf("%p\n", &**pfunc);
printf("%p\n", func1);
printf("%p\n", &func1);
break;
case 2:
pfunc[1]();
break;
case 3:
pfunc[2]();
break;
default:
//printf("default");
break;
}
return 0;
}
这里给出的示例是一个在嵌入式中应用较多的例子,输入n后跳转到func[n],输出相对应的内容。
pfunc是一个有三个函数元素的指针数组,那么pfunc[0]()就是第一个元素即func1(),这里pfunc[0]后面不要缺少括号,因为pfunc的类型是void(*)()[3],pfunc[0]的类型是void(*)()。
*pfunc是这个指针数组的数组名,也是这个指针数组的首地址,*pfunc = &*pfunc[0],这里一个关键的结论是数组名指数组首元素的地址。
那么**pfunc就是数组第一个元素的内容,也就是pfunc[0],要想调用它指向的函数func1记得加括号,即(*(*pfunc))()。
接下来打印十个地址,由前面的分析已经清楚*pfunc[0]的地址就是func1的地址也是**pfunc的地址,但为什么&*pfunc和&pfunc[0]却和其他加&不一样呢,这是因为*pfunc的地址(pfunc[0]的地址)是第一个指针的地址,而不是第一个指针指向的内容的地址。而*pfunc[0]、**pfunc、func1都是函数数组名,不是指针数组名,由紫色的字段可知,加&也一样。