C语言 - 函数指针 | 指针函数
函数指针
1 - 函数指针是指向函数的指针变量,本质是一个指针。声明格式如 int (*maxValue) (int x)
2 - 函数指针只能指向具有特定特征的函数,要求所有被同一指针所指向的函数必须具有相同的参数和返回值类型
比如 void (*func) ( ) 首先执行的是 (*func),func 是一个指针;紧接着执行 ( ),表明 func 指向的是一个函数;void 则标明这个函数不返回任何值
3 - 代码示例
① 使用函数指针
1 #include <stdio.h> 2 #include <string.h> 3 4 // 加 5 int sumValue(int x,int y){ 6 int sum =0; 7 sum = x+y; 8 return sum; 9 } 10 11 // 较大值 12 int maxValue(int a,int b){ 13 return a > b ? a : b; 14 } 15 16 // 遍历求和 17 int number (int x){ 18 19 int sum=0; 20 for (int i=0; i<x; i++) { 21 sum += i; 22 } 23 return sum ; 24 } 25 26 // 平方 27 int squareValue (int y){ 28 int square =0; 29 square = y*y; 30 return square; 31 } 32 int main(int argc, const char * argv[]) { 33 34 // 加 35 int (*p) (int,int)= sumValue;// 函数指针 p 36 printf("%d \n",sumValue(10, 20));// 方式 1 37 printf("%d \n",p(10,20)); // 方式 2 38 printf("%d \n",(*p)(10,20));// 方式 3 39 40 printf("%p \n",sumValue); 41 printf("%p \n",p); 42 43 44 // 取较大值 45 p = maxValue;// 函数指针重指向,等价于 p = &maxValue;(取址运算符可以忽略) 46 printf("%d \n",maxValue(10, 20)); 47 printf("%d \n",p(10,20)); 48 printf("%p \n",maxValue); 49 printf("%p \n",p); 50 51 52 // 遍历求和 53 int (*q) (int ) = number; 54 printf("%d \n",number(101)); 55 printf("%d \n",q(101)); 56 57 // 相加或平方 58 int (*point)(int) = NULL; 59 printf("请输入sum或者squ:\n"); 60 char string [20] =" "; 61 scanf("%s",string); 62 if (strcmp(string, "sum")==0) { 63 point = number; 64 }else if(strcmp(string, "squ")==0){ 65 66 point = squareValue; 67 } 68 69 printf("%s的结果为:%d\n",string,point(10)); 70 71 return 0; 72 }
注:C 语言规定函数名既不是左值也不是右值,但是 CPP 语言规定函数名属于左值。另外函数指针没有自增 ++ 和 自减 – 操作。函数名除了可以作为 sizeof 和取地址 & 的操作数,函数名在表达式中可以自动转换为函数指针类型的右值。就是说通过一个函数指针调用所指向的函数不需要在函数指针面前添加操作符号 *
指针函数
1 - 简单来说就是一个返回指针的函数。其本质是一个函数,而该函数的返回值是一个指针。声明格式如 int *fun(int x,int y)
2 - 代码示例:输入学生信息(姓名、年龄、分数),以指定分数为标准将学生信息按照年龄进行排序
1 #include <stdio.h> 2 #include <stdbool.h> 3 #include <stdlib.h> 4 5 // 学生信息 6 typedef struct student{ 7 8 char name[20];// 姓名 9 float score; // 分数 10 int age; // 年龄 11 12 }Student; 13 14 // 遍历学生信息 15 void printStudentInfo(Student *stus,int count){ 16 printf("\n----------------------------------\n"); 17 for (int i=0; i<count ; i++) { 18 printf("姓名:%s, 成绩:%.2f,年龄:%d \n",stus[i].name,(stus+i)->score,stus[i].age); 19 } 20 printf("----------------------------------\n"); 21 } 22 23 //---------------------------------------------------------未优化前使用函数指针作参 24 // 在名字后面拼接标记 25 void modifyName(char *name){ 26 strcat(name, "---学霸"); 27 } 28 void Name(char *name){ 29 strcat(name, "---学渣"); 30 } 31 32 // 查找分数:高于指定分数标记为学霸,低于指定分数标记为学渣 33 // @stus 学生 34 // @count 学生总数 35 // @destScore 分数分界线 36 // @void(*p)(char*)、void(*q)(char*) 函数指针 37 // 定义格式同 void modifyName(char *name)、 void Name(char *name) 38 // 注:未使用 typedef 优化,函数指针作参显得晦涩难懂,代码不清晰、不简洁 39 void searchStudentInfo(Student *stus,int count,float destScore,void(*p)(char*),void(*q)(char*)){ 40 41 for (int i = 0;i< count ;i++) { 42 43 if ((stus+i)->score > destScore) { 44 45 // 函数指针 46 p((stus+i)->name);// 学霸 47 }else{ 48 q((stus+i)->name);// 学渣 49 } 50 } 51 } 52 53 54 //-------------------------------------------------使用 typedef 优化 55 // 升序 56 bool isAscending(int age1,int age2){ 57 return age1 > age2 ? 1 : 0; 58 } 59 60 // 降序 61 bool isDecending(int age1,int age2){ 62 return age1 < age2 ? 1 : 0; 63 } 64 65 bool(*p) (int,int); 66 // 使用 typedef 优化函数指针 67 typedef bool(*Compare) (int,int); 68 // 排序 69 // @point typedef 优化后的函数指针 70 void sortStudentInfo(Student *stus,int count,Compare point){ 71 72 // 冒泡排序 73 for(int i=0; i<count-1; i++) { 74 for(int j=0; j<count-1-i; j++) { 75 76 if(point ((stus+j)->age,(stus+j+1)->age)){ 77 Student temp = *(stus+j); 78 *(stus+j) = stus[j+1]; 79 *(stus+j+1) = temp; 80 } 81 } 82 } 83 } 84 85 86 87 // ----- 注意这里是指针函数 ------ 88 Student *genterStudentsInfo(int count){ 89 90 // 开辟内存用来存储学生信息 91 Student *stus = malloc(sizeof(Student)*count ); 92 93 for (int i = 0; i < count; i++) { 94 printf("请输入第%d个学生的信息:\n",i+1); 95 printf("姓名 成绩 年纪:\n"); 96 scanf("%s %f %d",(stus+i)->name,&(stus+i)->score,&(stus+i)->age); 97 } 98 return stus; 99 }; 100 101 102 103 int main(int argc, const char * argv[]) { 104 105 // 开辟 3 个内存空间 106 Student *students = genterStudentsInfo(3); 107 108 // 区分学霸和学渣 109 searchStudentInfo(students, 3, 90, modifyName,Name); 110 111 // 按照年龄排序 112 sortStudentInfo(students, 3, isAscending);// 升序 113 114 // 打印学生信息 115 printStudentInfo(students, 3); 116 117 return 0; 118 }
日志信息
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2018-04-08 UI基础 - UIPickerView
2018-04-08 UI基础 - UISearchBar
2018-04-08 UI基础 - UITextView
2018-04-08 UI基础 - UIWebView | 已弃用 |
2018-04-08 UI基础 - UISegmentedControl