您的位置:首页 - 教程 - C语言 - 正文
c 高级函数的简单用法

c 中内置了很多高级的函数,我们先使用排序函数看一下

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 int compare_score(const void *n1 ,const void *n2) {
     
     int *a = (int *)n1;
     int *b = (int *)n2;
     return *a - *b;
 }
 
 int compare_name(const void *n1 , const void *n2) {
     
     char **a = (char **)n1;
     char **b = (char **)n2;
     return strcmp(*a, *b);
 }
 
 int main(int argc, const char * argv[]) {
     
     int array[] = {123,34,55,66,77,342,4,22};
     
     qsort(array, 8, sizeof(int), compare_score);
     
     for (int i = 0; i < 8; i++) {
         printf("%i \n",array[i]);
     }
     
     char *name[] = {"abc","efs","ss","gds","aaa","fee"};
     qsort(name, 6, sizeof(char *), compare_name);
     for (int i = 0; i < 6; i++) {
         printf("%s \n",name[i]);
     }
     
     return 0;
 }

输出结果为

为了能使这个qsort排序函数适应很多种排序情况,需要传入一个排序规则函数当做参数。

下边介绍一种函数指针数组的使用情况

假如我们要写一个群发邮件的程序,向不同的人发送不同类型的内容,很自然的想到,我们用struct 来实现

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 /**
  创建一个包含需要类型的枚举来保存类型数据
  */
 enum response_type {
     DUMP,            ///  舍弃
     SECOND_CHANCE,   ///  给次机会
     MARRIAGE         ///  合作
 };
 
 /**
  *  创建一个结构体,用来保存相应这的姓名和类型
  */
 typedef struct {
     char *name;
     enum response_type type;
 }reponse;
 
 /**
  *  给响应者p 发送dump邮件,单看这个函数,是没有限制条件的
  */
 void dump(reponse p) {
     printf("Dear: %s \n",p.name);
     puts("Unfortunately your last date contacted us to");
     puts("say that they will not be seeing you again");
 }
 
 /**
  *  给次机会的方法
  */
 void second_chance(reponse p) {
     printf("Dear: %s \n",p.name);
     puts("Good news: your last date had asked us to");
     puts("arrange another meeting. Please call AA");
 }
 
 /**
  *  合作的方法
  */
 void marriage(reponse p) {
     printf("Dear: %s \n",p.name);
     puts("Congratulatons: your last date has contacted");
     puts("us with a proposal of marriage");
 }
 
 int main(int argc, const char * argv[]) {
     
     reponse p[] = {
                         {"James",DUMP},
                         {"Juces",SECOND_CHANCE},
                         {"Bande",SECOND_CHANCE},
                         {"Hanmeimei",SECOND_CHANCE}
                     };
     
     for (int i = 0; i < 4; i++) {
         
         switch (p[i].type) {
             case DUMP:
                 dump(p[i]);
                 break;
             case SECOND_CHANCE:
                 second_chance(p[i]);
                 break;
             default:
                 marriage(p[i]);
                 break;
         }
     }
 
     return 0;
 }

我们使用结构来存放需要的数据打印的结果如下

但是代码中充斥着大量的函数调用,每次都需要根据type来判断调用哪个函数,日后如果需要添加新的类型,就要改动很多地方的代码,这并不是我们想看到的

其实接下来的思想跟上边的枚举差不多,我们可以把一类的东西放到一个数组中,根据需要在其中取值就可以了

void (*reponse_array[])(reponse) = {dump,second_chance,marriage};

经过函数指针数组的改造呢,我们就得出了下边的代码

 int main(int argc, const char * argv[]) {
     
     reponse p[] = {
                         {"James",DUMP},
                         {"Juces",SECOND_CHANCE},
                         {"Bande",SECOND_CHANCE},
                         {"Hanmeimei",SECOND_CHANCE}
                     };
     
     void (*reponse_array[])(reponse) = {dump,second_chance,marriage};
     
     for (int i = 0; i < 4; i++) {
         
         reponse_array[p[i].type](p[i]);
     }
 
     return 0;
 }

上边的单词写错了 reponse 应该改成 response ,这里就不做修改了

接下来 引入一个可以传多个参数的函数的使用方法,类似printf函数

加入某酒吧中有很多种不同的酒,现在需要写一个程序,当我们输入酒的名称的后可以获取该酒的价格,很简单,程序是这样的

 #include <stdio.h>
 
 enum drink {
     MUDSLIDE,FUZZY_NAVEL,MONKEY_GLAND,ZOMBIE
 };
 
 double price(enum drink d) {
     switch (d) {
         case MUDSLIDE:
             return 122.0;
             break;
         case FUZZY_NAVEL:
             return 222.0;
             break;
         case MONKEY_GLAND:
             return 322.0;
             break;
         default:
             return 422.0;
             break;
     }
 }
 
 int main(int argc, const char * argv[]) {
     
     
     printf("%f",price(MONKEY_GLAND));
     
     return 0;
 }

现在我们已经能够获取酒的价格了,但是现在如果我提出这样一个要求,需要知道几种单酒的总价的呢。因此我们就需要写一个函数类似于这样的

double total(3,MUDSLIDE,FUZZY_NAVEL,MONKEY_GLAND);

由于输入的酒品的个数是不固定的,因此顺理成章的引申出了可变参数这个概念

我们先看一下打印多个int 的函数

 void print_ints(int arg,...) {
     va_list ap;
     va_start(ap, arg);
     for (int i = 0; i < arg; i++) {
         printf("%i \n",va_arg(ap, int));
     }
     va_end(ap);
 }

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

 #include <stdio.h>
 #include <stdarg.h>
 
 enum drink {
     MUDSLIDE,FUZZY_NAVEL,MONKEY_GLAND,ZOMBIE
 };
 
 double price(enum drink d) {
     switch (d) {
         case MUDSLIDE:
             return 122.0;
             break;
         case FUZZY_NAVEL:
             return 222.0;
             break;
         case MONKEY_GLAND:
             return 322.0;
             break;
         default:
             return 422.0;
             break;
     }
 }
 
 double total(int args,...) {
     double total = 0.0;
     va_list ap;
     va_start(ap, args);
     for (int i = 0; i < args; i++) {
         double p = price(va_arg(ap, enum drink));
         total += p;
     }
     va_end(ap);
     return total;
 }
 
 
 
 
 int main(int argc, const char * argv[]) {
     
     
     printf("%f",total(3,MUDSLIDE,MONKEY_GLAND,FUZZY_NAVEL));
    
     return 0;
 }

打印结果是

666.000000Program ended with exit code: 0


评论: