C语言——指向函数的指针
C语言中的指针是非常灵活的,能够熟练运用和掌握指针必将给程序的开发带来方便和无穷的魅力。
讲一讲我对函数指针的一些浅显的认识。一个指向函数的指针,也就是函数的入口地址。刚开始我接触的时候也是非常疑惑,这个到底有什么用呢。通过几次使用和用心的体会,我发现了一些其中的巧妙。
在一个程序中,可能对于不同的用户要求会产生不同的算法代码。但是算法代码中间却又是有一些相似的。如果把函数的指针当做参数,我们到底触发那个算法代码,就可以通过传入的参数或函数指针来实现。感觉有点像工厂函数的韵味。通过一个函数指针数组,用户传入触发函数的下标值。一个工厂函数就可以产生多个不同函数的功效。这样的设计模式很巧妙。(可以参考一下设计模式的书,里面讲的很实用和美妙)
1 函数类型 (* 函数指针变量)() ; //指向函数的入口地址
一个函数是若干语句的集合 , 经编译后存储在函数代码存储区 , 并占有一片连续的存储空间 ,对函数指针只能用函数名赋值而无其他运算
1 #include<stdio.h>
2
3 int max(int x ,int y);
4
5 int main()
6 {
7 int (* p)(int,int) ;//定义p是指向函数的指针变量
8 int a , b , c ;
9
10 p= max ;//将函数max的入口地址赋给指针变量p
11 scanf("%d %d" ,&a ,&b) ;
12 c= (* p)(a , b) ;//用指向函数的指针变量p调用函数
13 printf("a = %d , b = %d , max = %d" , a , b , c);
14
15 return 0 ;
16 }
17
18 int max(int x ,int y)
19 {
20 int k ;
21 k= (x> y)? x : y ;
22
23 return k ;
24 }
函数名作为实际参数 :
1 #include <stdio.h> 2 3 int fun1(int a , int b) 4 { 5 return a+b ; 6 } 7 8 int fun2(int (*q)() , int x , int y) 9 { 10 return (*q)(x , y) ; 11 } 12 13 int main() 14 { 15 int (*p)() , k ; 16 p = fun1 ; 17 k = fun2( p , 8 , 5 ) ; 18 19 printf("k = %d \n" , k); //输出 13 20 21 return 0 ; 22 }
设置一个函数proc ,每次调用它会实现不同的功能 ,输入 a , b 两个数 ,第一次调用proc时,找出两者中最大者 , 第二次找出最小者 , 第三次调用求两数之差 :
1 #include <stdio.h> 2 3 int max(int *x , int *y); 4 int min(int *x , int *y); 5 int a_b(int *x , int *y); 6 int proc(int *x , int *y , int(*p)()); 7 8 int main() 9 { 10 int a , b ; 11 12 printf("Enter a and b :"); 13 scanf("%d %d" , &a , &b); 14 15 printf("a = %d \t b = %d \n" , a , b); 16 17 printf("max(%d,%d) = " , a , b); 18 proc(&a , &b , max); 19 20 printf("min(%d,%d) = " , a , b); 21 proc(&a , &b , min); 22 23 printf("%d - %d = " , a , b); 24 proc(&a , &b , a_b); 25 26 return 0 ; 27 } 28 29 int max(int *x , int *y) 30 { 31 int k ; 32 33 k = (*x > *y) ? *x : *y ; 34 35 return k ; 36 } 37 38 int min(int *x , int *y) 39 { 40 int k ; 41 42 k = (*x < *y) ? *x : *y ; 43 44 return k ; 45 } 46 47 int a_b(int *x , int *y) 48 { 49 int k ; 50 51 k = *x - *y ; 52 53 return k ; 54 } 55 56 int proc(int *x , int *y , int (*p)()) 57 { 58 int q ; 59 q = (*p)(x , y); 60 61 printf("%d\n" , q); 62 63 return 0 ; 64 }
一个简单的主控菜单程序 , 包括 增加 , 删除 , 显示 , 退出
1 #include <stdio.h> 2 #include <string.h> //字符操作 3 #include <stdlib.h> //包含system函数 4 5 void enter() ; 6 void delete() ; 7 void review() ; 8 void quit() ; 9 //void enter() , delete() , review() , quit() ; 10 int menu(); 11 void (*option[])() = {enter , delete , review ,quit} ; 12 13 14 int main() 15 { 16 int i ; 17 while(1) 18 { 19 i = menu(); 20 system("CLS"); //清屏函数 21 22 (*option[i])(); //调用函数,执行功能 23 24 system("PAUSE"); //等待输入 25 system("CLS"); 26 } 27 } 28 29 int menu() 30 { 31 char select[] = {"1234EDRQedrq"}; 32 char *p , ch ; //定义数组指针应与数组数据类型一致 33 34 printf("1:Enter\n"); 35 printf("2:Delete\n"); 36 printf("3:Review\n"); 37 printf("4:Quit\n"); 38 39 printf("Please select a number :"); 40 41 while(!(p = strchr(select , ch = getchar()))) //将找到的字符地址赋给指针变量p 42 // 若没找到则 p 返回 '\0' 即 NULL , 非P 为真 执行 下列语句 43 { 44 putchar('\a'); // 产生响铃声 45 printf("%c\b" , ch); //退格回显 46 } 47 48 return((p - select) % 4) ; // 返回值只可能为 0 ,1 ,2 ,3 49 } 50 51 void enter() 52 { 53 printf("In enter()"); 54 } 55 56 void delete() 57 { 58 printf("In delete()"); 59 } 60 61 void review() 62 { 63 printf("In review()"); 64 } 65 66 void quit() 67 { 68 printf("In quit()"); 69 exit(0) ; //函数exit()使程序立即正常终止 , 通常 ,状态值 status 为 0 表示正常终止 70 //status 为 非 0 时 为出现错误后终止程序 71 }