• c 高级函数的简单用法


    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

  • 相关阅读:
    基于Centos7.2搭建Cobbler自动化批量部署操作系统服务
    Centos 7 Linux系统修改网卡名称为ethx
    解决端口被占用而导致软件运行失败,程序无法启动,无法安装开发工具等问题
    applicationContext.xml文件放置位置不同而导致的jUnit测试的时候路径的不同
    myeclipse中的web项目导入到eclipse中注意事项,项目部署到tomcat后无法访问jsp文件
    SSH项目整合教学Eclipse搭建SSH(Struts2+Spring3+Hibernate3)
    ApplicationContext.xml文件详解
    SSH项目练习的时候报错:[applicationContext.xml]: Invocation of init method failed;
    [转载]快速搭建Spring MVC 4开发环境
    struts配置测试中遇到报错信息,记录下
  • 原文地址:https://www.cnblogs.com/xumaojun/p/8523058.html
Copyright © 2020-2023  润新知