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 ",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 ",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 ",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 ",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 ",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 ",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