本次主要学习和理解函数指针
1.函数指针
1 void printValue(int number) { 2 printf("number = %d\n", number); 3 } 4 int main(int argc, const char * argv[]) { 5 void (*p1)(int) = NULL; 6 p1 = printValue; 7 p1(5); 8 }
1> 定义
代码第5行
函数类型:int (int, int)
函数指针的类型:int (*p)(int, int)
p是函数指针变量名
2> 给函数指针赋值(使用函数首地址)
代码第6行
函数存放在代码区,函数名是函数存储空间的首地址
3> 通过函数指针调用函数
代码第7行
与通过函数名调用函数是一样的
练习:定义两个函数,一个求两个数的 最大值,一个求两个数的 和,从控制台输入maxValue或sum分别求3和5的最大值或和(提示:定义一个函数指针,根据输入内容指向不同函数,最后一次 调用完成)。
Func.h
1 #import <Foundation/Foundation.h> 2 3 int maxValue(int a, int b); 4 int sum(int a, int b);
Func.m
1 #import "Func.h" 2 3 int maxValue(int a, int b) { 4 return a > b ? a : b; 5 } 6 7 int sum(int a, int b) { 8 return a + b; 9 }
main.m
1 #import <Foundation/Foundation.h> 2 3 #import "Func.h" 4 5 int main(int argc, const char * argv[]) { 6 char str[20] = {0}; 7 int (*p)(int, int) = NULL; 8 9 printf("输入maxValue或sum:\n"); 10 scanf("%s", str); 11 if (strcmp("maxValue", str) == 0) { 12 p = maxValue; 13 printf("最大值:"); 14 } else if (strcmp("sum", str) == 0) { 15 p = sum; 16 printf("和:"); 17 } else { 18 printf("输入有误,函数名不存在!\n"); 19 } 20 // 安全判断 21 if (p != NULL) { 22 printf("%d\n", p(3, 5)); 23 } 24 return 0; 25 }
第20行代码是一个安全判断,是程序更加健壮。
2、调用回调函数
回调函数就是 函数指针作为函数参数(一般是函数的最后一个参数)
练习:写一函数查找成绩90分以上的学员,使用回调函数在姓名后加”高富帅”。
提示:定义两个函数
1、void addStr(char *name);
2、void findStudentByScore(Student *stus, int count, void(*p)(char *))
Func.h
1 #import <Foundation/Foundation.h> 2 3 struct student { 4 char name[20]; 5 int age; 6 int score; 7 }; 8 typedef struct student Student; 9 10 void addStr(char *name); 11 void findStudentByScore(Student *stus, int count, void(*p)(char *)); 12 void printArray(Student *stus, int count);
func.m
1 void addStr(char *name) { 2 strcat(name, "高富帅"); 3 } 4 void findStudentByScore(Student *stus, int count, void(*p)(char *)) { 5 for (int i = 0; i < count; i++) { 6 if (stus[i].score >= 90) { 7 p(stus[i].name); 8 9 } 10 } 11 } 12 13 void printArray(Student *stus, int count) { 14 for (int i = 0; i < count; i++) { 15 printf("name = %s,age = %d,score = %d\n", stus[i].name, stus[i].age, stus[i].score); 16 } 17 }
main.m
1 #import <Foundation/Foundation.h> 2 3 #import "Func.h" 4 5 int main(int argc, const char * argv[]) { 6 7 Student stu1 = {"张三", 18, 80}; 8 Student stu2 = {"张四", 19, 90}; 9 Student stu3 = {"张五", 17, 99}; 10 Student stus[3] = {stu1, stu2, stu3}; 11 findStudentByScore(stus, 3, addStr); 12 printArray(stus, 3); 13 14 return 0; 15 }
3、动态排序
主要的思想是:使用回调函数,提高代码的复用性,提高代码的可修改性(当需求有变化时,可以快速简单的修改)
Function.h
1 #import <Foundation/Foundation.h> 2 3 struct student { 4 char name[20]; // 姓名 5 int age; // 年龄 6 double score; // 成绩 7 int num; // 学号 8 }; 9 typedef struct student Student; 10 11 // 函数指针重定义,重定义的名字为 * 后面的名字 12 typedef BOOL (*Function)(Student, Student); 13 14 // 打印数组元素 15 void printArray(Student *stu, int count); 16 17 // 比较两个学生的年龄 18 BOOL compareStuAgeAsc(Student stu1, Student stu2); 19 20 // 比较两个学生的姓名 21 BOOL compareStuNameAsc(Student stu1, Student stu2); 22 23 // 比较两个学生的成绩 24 BOOL compareStuScore(Student stu1, Student stu2); 25 26 // 比较两个学生的学号 27 BOOL compareStuNumAsc(Student stu1, Student stu2); 28 29 // 排序函数 30 void sortStudents(Student stu[], int count, Function p);
Function.m
1 #import "Function.h" 2 3 // 输出数组 4 void printArray(Student *stu, int count) { 5 for (int i = 0; i < count; i++) { 6 printf("name = %s, age = %d, score = %.2f, num = %d\n", stu[i].name, stu[i].age, stu[i].score, stu[i].num); 7 } 8 } 9 10 // 比较两个学生的年龄 11 BOOL compareStuAgeAsc(Student stu1, Student stu2) { 12 return stu1.age > stu2.age; 13 } 14 15 // 比较两个学生的姓名 16 BOOL compareStuNameAsc(Student stu1, Student stu2) { 17 return strcmp(stu1.name, stu2.name) > 0; 18 } 19 20 // 比较两个学生的成绩 21 BOOL compareStuScore(Student stu1, Student stu2) { 22 return stu1.score < stu2.score; 23 } 24 25 // 比较两个学生的学号 26 BOOL compareStuNumAsc(Student stu1, Student stu2) { 27 return stu1.num > stu2.num; 28 } 29 30 // 排序函数 31 void sortStudents(Student stu[], int count, BOOL (*p)(Student, Student)) { 32 for(int i = 0; i < count - 1; i++) { 33 for(int j = 0; j < count - 1 - i; j++) { 34 if(p(stu[j], stu[j + 1])) { 35 Student temp = stu[j]; 36 stu[j] = stu[j + 1]; 37 stu[j + 1] = temp; 38 } 39 } 40 } 41 }
main.m
1 #import <Foundation/Foundation.h> 2 3 #import "Function.h" 4 5 int main(int argc, const char * argv[]) { 6 Student stu1 = {"zh", 45, 9.9, 315}; 7 Student stu2 = {"s", 3, 100, 666}; 8 Student stu3 = {"f-1", 18, -100, 38}; 9 Student stu4 = {"Zboomsky", 19, 99, 17}; 10 Student stu5 = {"Boos", 16, 150, 6}; 11 12 Student stuArray[] = {stu1, stu2, stu3, stu4, stu5}; 13 int count = sizeof(stuArray) / sizeof(Student); 14 15 // 比较两个学生的年龄 16 sortStudents(stuArray, count, compareStuAgeAsc); 17 printArray(stuArray, count); 18 19 // 比较两个学生的姓名 20 sortStudents(stuArray, count, compareStuNameAsc); 21 printArray(stuArray, count); 22 23 // 比较两个学生的成绩 24 sortStudents(stuArray, count, compareStuScore); 25 printArray(stuArray, count); 26 27 // 比较两个学生的学号 28 sortStudents(stuArray, count, compareStuNumAsc); 29 printArray(stuArray, count); 30 31 return 0; 32 }