zoukankan      html  css  js  c++  java
  • C语言基础11

    函数指针的定义:

    函数类型 (标识符 指针变量名)(形参列表)

    void  printHello( );

    void printHello( ){

      printf("hello world!!! " );

    }

    main函数中:

    //创建函数指针,同时赋值空.

    int (*p)() = NULL;

    p = printHello  // 将函数名称 赋值给函数指针,相当于函数的入口赋值给一个内存地址.

    p( );      // 此时函数指针p就可以像函数名一样调用. 就可以理解为p 于 函数名是"相等".

    实用1:

    int sumValue(int a , int b){

      return a + b;

    }

    int subValue(int a , int b ){

      return a - b;

    }

    main函数:

    //创建一个函数指针变量

    int (*p2)(int , int);

    // char str[] ={0};

    // 在堆空间开辟一个 1* 20 字节的空间,同时str指向控制台输入的字符数组.

    char *str = malloc( sizeof(char) * 20);

    printf("Please enter some thing :");

    scanf("%s" , str);         // 注意这里str本身就是指针,一个地址,不需要在用&或者地址,直接赋值.

    if(strcmp(str, "sub") == 0){

      p = subValue;    // p 为函数指针,所以赋值给它的是函数的入口地址,就是函数名称 ,需要后面的( )

    }else if( strcmp(str , "sum") == 0){

      p = sumValue;

    }else {

      printf("you are wrong !! ");

    }

    int x = 20, y = 45;

    int result = p( x, y );  直接使用p来代替subValue或者sumValue函数名称,并调用函数.

    printf("%d", result );

    free( str );

    str = NULL;

     实用2:写一函数查找成绩90分以上的学员,使⽤用回调函数在姓名后加”高富帅".

    typedef struct {

      int num;

      char name[30];

      char gender;

      float score;

    } Student;

    void printStudent(Student *stu, int count );

    void printStudent(Student *stu, int count ){

      for (int i = 0 ; i< count ; i++){

        printf("%d %s %c %f ", (stu+i)->num, (stu+i)->name, (stu+i)->gender, (stu+i)->score);

      }

    }

    void getStudent(Student *stu , int count , void (*p)(Student *));

    void getStudent(Student *stu , int count , void (*p)(Student *)){

        for(int i = 0 ; i< count ; i++){

            if((stu+i)->score >= 90){

                p(stu+i);  //传入一个指针     

            }

        }

    }

    void getName(Student *s1);

    void getName(Student *s1){

      strcat(s1->name, "白富美");

    }

    main函数:

    Student stu[] ={

              {21, "luoshuai", 'm', 76.8},

              {12, "luoteng", 'f', 98.6},

              {68, "liruoxuan", 'm', 29.6},

              {43, "lihuahua", 'f', 99.7},

               {87, "guagua", 'm', 23.5}

        };

    Student *st = stu;

    int count = sizeof(stu) / sizeof(Student);

    getStudent(st , count , getStudent);

    printStudent(st, count);

     //动态排序

    为函数指针重新命名: 比如说 int (*p)(int ,int ) 在很多地方都可以用到,我觉得很长很丑,简化一下:

    typedef int(*PFUNC)(int ,int ) 以后在程序中任何使用到该函数指针的地方都可以用PFUNC xxx 来创建函数指针变量.

    仍然使用上述的结构体和结构体数组,我们根据age或者score或者name来进行排序

    void sortStudent( Student *stu, int count);

    void sortStudent( Student *stu, int count){

      for(int i = 0 ; i< count -1; i++){

        int minKey = i ;

        for(int j = i+1; j< count; j++){

           // 如果有一天我修改条件,根据姓名 或者我又修改,根据学号来排序,我们每次都需要过来修改一次很麻烦.

          //  所以我们引入了动态排序的概率,不在需要,查询该函数的数据,只需要在外部进行不同条件的判断.     

          // if((stu+j)->score  < (stu+minKey)->score ){  

            minKey = j;

           }    

        }

      if(minKey != i ){

        Student temp = *(stu + i);

        *(stu+i ) =*(stu +minKey);

        *(stu+minKey) = temp;

      }

    }

    }

    main函数中:

    Student *s1 = stu;

    int count = sizeof(stu) /sizeof(Student);

    // sortStudent(s1, count);

    //  printStudent(s1, count );

     修改sortStudent()函数如下:

    void sortStudent( Student *stu, int count, BOOL (*p2)(Student *, Student *));

    void sortStudent( Student *stu, int count, BOOL (*p2)(Student *, Student *)){

      for(int i = 0 ; i< count -1; i++){

        int minKey = i ;

        for(int j = i+1; j< count; j++){

           // 如果有一天我修改条件,根据姓名 或者我又修改,根据学号来排序,我们每次都需要过来修改一次很麻烦.

          //  所以我们引入了动态排序的概率,不在需要,查询该函数的数据,只需要在外部进行不同条件的判断.     

          if( p2(stu+j, stu+minKey) ){  

            minKey = j;

           }    

        }

      if(minKey != i ){

        Student temp = *(stu + i);

        *(stu+i ) =*(stu +minKey);

        *(stu+minKey) = temp;

      }

    }

    }

    //根据名字来排序

    BOOL changeStudentByName(Student *stu1, Student *stu2);

    BOOL changeStudentByName(Student *stu1, Student *stu2){

      return strcmp(stu1->name, stu2->name) > 0;  // 注意这里需要大于0才能成立.

    }

    // 根据分数来排序

    BOOL changeStudentByScore(Student *stu1, Student *stu2);

    BOOL changeStudentByScore(Student *stu1, Student *stu2){

      return stu1->score > stu2->score ;    // 这里需要两两的分数大于或者小于才成立.

    }

    最后我们在main函数中调用:

    Student *s1 = stu;

    int count = sizeof(stu) /sizeof(Student);

    sortStudent( stu, count, changeStudentByName );

    printStudent(stu, count);

    最后一个问题,返回值为函数指针:

    typedef BOOL (*PFUNC)(Student *,Student *) ;

    typedef struct {

      char name[40];

      PFUNC p;

    } nameFunction;

    PFUNC getFunctionName(char *str){

      if(strcmp(str, "name") == 0 ){

        return changeStudentByName;

      }else if(strcmp(str, "num") == 0){

        return changeStudentByNum;   // 返回函数主入口的地址.表示为函数名称.

      }else if(strcmp(str, "score") == 0){

        return changeStudentByScore;

      }

      return NULL;

    }

            int str1[] ={0};

            printf(" Please enter some thing s :");

            scanf("%s", str1);

            PFUNC p3 = getFunctionByName(str1);

            if( p3 == NULL){

                 return 0;

            }

            sortStudent(st, count, p3);

            printStudent(st, count);  

  • 相关阅读:
    Protocol Buffer详解
    RPC进阶篇
    RPC基础篇
    测试控制器
    更加简洁的tableview
    storyboard中Unwind segue使用
    IOS开发Apache服务器搭建
    IOS多线程操作
    IOS使用Svn的trunk、branches、tag分别的侧重
    在设计IOSapp时为了代码的扩展性可可维护性需要遵守的原则
  • 原文地址:https://www.cnblogs.com/liruoxuan/p/4089938.html
Copyright © 2011-2022 走看看