iOSDay09C语言函数指针

Posted 墨隐于非

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOSDay09C语言函数指针相关的知识,希望对你有一定的参考价值。

本次主要学习和理解函数指针

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(10, 20));
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 }

以上是关于iOSDay09C语言函数指针的主要内容,如果未能解决你的问题,请参考以下文章

iOSDay11之继承

iOSDay06C语言结构体

iOSDay15之集合

iOSDay13之NSString

更新:C++ 指针片段

如何在汇编函数中将元素数组作为参数传递时转发ARM寄存器的地址指针