int (*p)[num]( char*,int,int ); int (*p[num])( char*,int,int ); int (*(*p)[num])(int a);
上一篇博客最后的三个例子的答案分别是:(第一个先放着,周末问下老师),函数指针数组,函数指针数组的指针。
函数指针数组指针和前面的数组指针其实没有太大区别。然后今天主要理一下函数指针数组和二级指针。
函数指针数组
函数指针数组中,存放的一定要是相同返回值类型,以及相同参数列表的函数指针,这样数组可以通过下标来调用不同的函数,省去了使用大量的判断语句。下面举个例子:
假设你要看电影,下面有4种类型的,动作,浪漫,卡通,搞笑,然后再输入电影名观看。按照以前我可能就会是一堆if else或者switch case来判断 ,但现在可以这样:
#include<stdio.h> void watch_action(char* name) { printf("Action movie <%s> starts\n",name); } void watch_funny(char* name) { printf("Funny movie <%s> starts\n",name); } void watch_romantic(char* name) { printf("Romantic movie <%s> starts\n",name); } void watch_cartoon(char* name) { printf("cartoon <%s> starts\n",name); } int main(int argc, char const *argv[]) { void (*watch[4])(char* name)={watch_action,watch_funny,watch_romantic,watch_cartoon}; printf("what kinds of movie would you want\n"); int num; scanf("%d",&num); printf("please input the movie name of this kinds\n"); char movie_name[128]; scanf("%s",movie_name); watch[num](movie_name); return 0; }
通过num来调用不同的函数,省去了一堆判断语句,感觉还是方便蛮多的。
二级指针:
在指针的定义时就说过,指针变量虽然保存的是别人的地址,但其本身也是有地址的。而指向指针地址的指针,就叫做二级指针。
那啥时候会用到二级指针?不急,先看下面代码:
#include <stdio.h> int change_1(int b) { b = 10; return b; } int change_2(int *p) { *p = 15; } int main(int argc, char const *argv[]) { int a = 5; change_1(a); printf("%d\n",a); change_2(&a); printf("%d\n",a); return 0; }
你觉得输出是多少 ? 编译后结果是 5和15 也就是说change_1()这个函数没有把a修改了。C语言中函数的传参是值传递,change_1()只不过是把实参a的值5传给了局部变量b,然后b在被赋值10并返回,函数结束,b的生命周期也结束了。而主函数中的a根本就没有发生变化。要修改a的值,就要用第二种方法,前面我们说了,指针指向的是地址,change_2()中p得到的是a所在的地址,而*p就代表这个地址中的内容,我们对*p进行修改,就代表我们对这个地址上的变量即a进行了修改。
所以,想要修改一个数据的值,就要找到他的地址,用一级指针来修改。以此类推,想要修改指针的值,我们就要找到指针的地址,用二级指针来对他进行修改。
下面可以看下这个代码的结果,可能会更清晰一点:
#include <stdio.h> int main(int argc, char const *argv[]) { int a =5; int* p; p = &a; int** pp; pp = &p; printf("&a:%p\n",&a); printf("&p:%p\n",&p); printf("p:%p\n",p); printf("&pp:%p\n",&pp); printf("pp:%p\n",pp); printf("*pp:%p\n",*pp); printf("&(*pp):%p\n",&(*pp)); return 0; }
取这些变量的地址,地址运算符“&”,运算操作是取地址。编译结果:
画个图:
可以很清楚的看到 a的地址被放入了一级指针p当中 p的地址被放入了二级指针pp当中
p == &a 说明 *p == a pp == &p 说明*pp == *p *pp == &a 说明 **pp == a
也就是 **pp == *p == a
最后举个具体用例吧。
#include <stdio.h> int main(int argc, char const *argv[]) { char* num[9]={"one","two","three","four","five","six","seven","eight","nine"}; char** p; p = &num[0]; int number; scanf("%d",&number); printf("English Number is %s\n",*(p+number-1)); return 0; }
定义一个指针数组num,输入阿拉伯数字转换成英文数字。这里如果单单只有一级指针是不够的,一级指针只能找到字符串所在的位置,但是找不到其首地址,导致无法输出。所以需要二级指针二级寻址来输出。