c 中内置了很多高级的函数,我们先使用排序函数看一下
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 int compare_score(const void *n1 ,const void *n2) {
6
7 int *a = (int *)n1;
8 int *b = (int *)n2;
9 return *a - *b;
10 }
11
12 int compare_name(const void *n1 , const void *n2) {
13
14 char **a = (char **)n1;
15 char **b = (char **)n2;
16 return strcmp(*a, *b);
17 }
18
19 int main(int argc, const char * argv[]) {
20
21 int array[] = {123,34,55,66,77,342,4,22};
22
23 qsort(array, 8, sizeof(int), compare_score);
24
25 for (int i = 0; i < 8; i++) {
26 printf("%i \n",array[i]);
27 }
28
29 char *name[] = {"abc","efs","ss","gds","aaa","fee"};
30 qsort(name, 6, sizeof(char *), compare_name);
31 for (int i = 0; i < 6; i++) {
32 printf("%s \n",name[i]);
33 }
34
35 return 0;
36 }

输出结果为
为了能使这个qsort排序函数适应很多种排序情况,需要传入一个排序规则函数当做参数。
下边介绍一种函数指针数组的使用情况
假如我们要写一个群发邮件的程序,向不同的人发送不同类型的内容,很自然的想到,我们用struct 来实现

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 /**
6 创建一个包含需要类型的枚举来保存类型数据
7 */
8 enum response_type {
9 DUMP, /// 舍弃
10 SECOND_CHANCE, /// 给次机会
11 MARRIAGE /// 合作
12 };
13
14 /**
15 * 创建一个结构体,用来保存相应这的姓名和类型
16 */
17 typedef struct {
18 char *name;
19 enum response_type type;
20 }reponse;
21
22 /**
23 * 给响应者p 发送dump邮件,单看这个函数,是没有限制条件的
24 */
25 void dump(reponse p) {
26 printf("Dear: %s \n",p.name);
27 puts("Unfortunately your last date contacted us to");
28 puts("say that they will not be seeing you again");
29 }
30
31 /**
32 * 给次机会的方法
33 */
34 void second_chance(reponse p) {
35 printf("Dear: %s \n",p.name);
36 puts("Good news: your last date had asked us to");
37 puts("arrange another meeting. Please call AA");
38 }
39
40 /**
41 * 合作的方法
42 */
43 void marriage(reponse p) {
44 printf("Dear: %s \n",p.name);
45 puts("Congratulatons: your last date has contacted");
46 puts("us with a proposal of marriage");
47 }
48
49 int main(int argc, const char * argv[]) {
50
51 reponse p[] = {
52 {"James",DUMP},
53 {"Juces",SECOND_CHANCE},
54 {"Bande",SECOND_CHANCE},
55 {"Hanmeimei",SECOND_CHANCE}
56 };
57
58 for (int i = 0; i < 4; i++) {
59
60 switch (p[i].type) {
61 case DUMP:
62 dump(p[i]);
63 break;
64 case SECOND_CHANCE:
65 second_chance(p[i]);
66 break;
67 default:
68 marriage(p[i]);
69 break;
70 }
71 }
72
73 return 0;
74 }

我们使用结构来存放需要的数据打印的结果如下
但是代码中充斥着大量的函数调用,每次都需要根据type来判断调用哪个函数,日后如果需要添加新的类型,就要改动很多地方的代码,这并不是我们想看到的
其实接下来的思想跟上边的枚举差不多,我们可以把一类的东西放到一个数组中,根据需要在其中取值就可以了
void (*reponse_array[])(reponse) = {dump,second_chance,marriage};
经过函数指针数组的改造呢,我们就得出了下边的代码

1 int main(int argc, const char * argv[]) {
2
3 reponse p[] = {
4 {"James",DUMP},
5 {"Juces",SECOND_CHANCE},
6 {"Bande",SECOND_CHANCE},
7 {"Hanmeimei",SECOND_CHANCE}
8 };
9
10 void (*reponse_array[])(reponse) = {dump,second_chance,marriage};
11
12 for (int i = 0; i < 4; i++) {
13
14 reponse_array[p[i].type](p[i]);
15 }
16
17 return 0;
18 }

上边的单词写错了 reponse 应该改成 response ,这里就不做修改了
接下来 引入一个可以传多个参数的函数的使用方法,类似printf函数
加入某酒吧中有很多种不同的酒,现在需要写一个程序,当我们输入酒的名称的后可以获取该酒的价格,很简单,程序是这样的

1 #include <stdio.h>
2
3 enum drink {
4 MUDSLIDE,FUZZY_NAVEL,MONKEY_GLAND,ZOMBIE
5 };
6
7 double price(enum drink d) {
8 switch (d) {
9 case MUDSLIDE:
10 return 122.0;
11 break;
12 case FUZZY_NAVEL:
13 return 222.0;
14 break;
15 case MONKEY_GLAND:
16 return 322.0;
17 break;
18 default:
19 return 422.0;
20 break;
21 }
22 }
23
24 int main(int argc, const char * argv[]) {
25
26
27 printf("%f",price(MONKEY_GLAND));
28
29 return 0;
30 }

现在我们已经能够获取酒的价格了,但是现在如果我提出这样一个要求,需要知道几种单酒的总价的呢。因此我们就需要写一个函数类似于这样的
double total(3,MUDSLIDE,FUZZY_NAVEL,MONKEY_GLAND);
由于输入的酒品的个数是不固定的,因此顺理成章的引申出了可变参数这个概念
我们先看一下打印多个int 的函数

1 void print_ints(int arg,...) {
2 va_list ap;
3 va_start(ap, arg);
4 for (int i = 0; i < arg; i++) {
5 printf("%i \n",va_arg(ap, int));
6 }
7 va_end(ap);
8 }

经过我们修改后的代码是这样的

1 #include <stdio.h>
2 #include <stdarg.h>
3
4 enum drink {
5 MUDSLIDE,FUZZY_NAVEL,MONKEY_GLAND,ZOMBIE
6 };
7
8 double price(enum drink d) {
9 switch (d) {
10 case MUDSLIDE:
11 return 122.0;
12 break;
13 case FUZZY_NAVEL:
14 return 222.0;
15 break;
16 case MONKEY_GLAND:
17 return 322.0;
18 break;
19 default:
20 return 422.0;
21 break;
22 }
23 }
24
25 double total(int args,...) {
26 double total = 0.0;
27 va_list ap;
28 va_start(ap, args);
29 for (int i = 0; i < args; i++) {
30 double p = price(va_arg(ap, enum drink));
31 total += p;
32 }
33 va_end(ap);
34 return total;
35 }
36
37
38
39
40 int main(int argc, const char * argv[]) {
41
42
43 printf("%f",total(3,MUDSLIDE,MONKEY_GLAND,FUZZY_NAVEL));
44
45 return 0;
46 }

打印结果是
666.000000Program ended with exit code: 0