ios--c DAY_11

//函数指针

//回调函数

//利用函数指针以及回调函数,实现动态函数

main.m中程序:

//
//  main.m
//  Lesson_15-8-11
//
//  Created by lanou3g on 15/8/11.
//  Copyright (c) 2015年 lanou.3g.com. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Student.h"
#import "Sort.h"

//两个数中的最大值
int maxValue(int a,int b);
int (*p)(int a,int b);//函数指针
int maxValue(int a,int b){
    return a>b?a:b;
}
//求和
int sumTwoNumber(int a,int b);
int sumTwoNumber(int a,int b){
    return a+b;
}
//给一个指针指向其他函数
int getValueOfOperation(int a,int b,int (*p)(int ,int ));
int getValueOfOperation(int a,int b,int (*p)(int ,int )){
    int result=p(a,b);
    return result;
}
//数组升序排列
void sortAscending(int array[],int n);
void (*point_arrayInt)(int array[],int n);
void sortAscending(int array[],int n){
    //---第一种 数组一般排序
    int temp=0;
    for (int i=0; i<n ; i++) {
        for (int j=0; j<n-i-1; j++) {
            if (array[j]>array[j+1]) {
                temp=array[j];
                array[j]=array[j+1];
                array[j+1]=temp;
            }
        }
    }
    printf("使用一维数组的一般形式实现升序排序:\n");
    for (int i=0; i<n ; i++) {
        printf("%d\t",array[i]);
    }
    printf("\n");
    //---第二种 指针排序
    int temp_point=0;
    int *point=NULL;
    point=array;
    for (int i=0; i<n ; i++) {
        for (int j=0; j<n-i-1; j++) {
            if (point[j]>point[j+1]) {
                temp_point=point[j];
                point[j]=point[j+1];
                point[j+1]=temp_point;
            }
        }
    }
    printf("使用指针来实现一维数组的升序排序:\n");
    for (int i=0; i<n ; i++) {
        printf("%d\t",point[i]);
    }
    printf("\n");
}
//打印hello
void printHello();
void (*point_Print)();
void printHello(){
    printf("hello beijing!\n");
}

int main(int argc, const char * argv[]) {

    //函数:实现某特定功能的一段代码。
#pragma mark 函数指针
    //函数指针---》是一个函数类型的指针
    //===>函数指针:指向函数首地址的指针。可以通过函数指针调用指向的函数。
    //定义===》返回值类型 (*函数指针名) (参数1,参数2);
    //函数指针名=函数名;
    //函数名也是地址。函数名指向存代码的那段内存的首地址。
    //===>练习1:
    int a=4;
    int b=9;
    p=maxValue;
    int max=p(a,b);
    printf("最大值:%d",max);
    printf("\n=================================================\n");
    //练习2:
    int array_Int[10]={0};
    for (int i=0; i<10; i++) {
        array_Int[i]=arc4random()%(100-80+1)+80;
        printf("%d\t",array_Int[i]);
    }
    printf("\n");
    point_arrayInt=sortAscending;
    point_arrayInt(array_Int,10);
    //函数指针类型:返回值类型(*)(参数类型)
    //练习3:
    //定义一个函数:void PrintHello();
    printf("\n===============================================\n");
    point_Print=printHello;
    point_Print();
    //练习4、
    //定义两个函数,求最大值、求和,输入maxValue或sum分别对两个数3,5求值。定义一个函数指针,根据输入的内容指向不同的函数,一次调用。
    int num1=3,num2=5;
    char operator[10]={0};
    printf("要进行的操作:\n");
    scanf("%s",operator);
    getchar();
    if (strcmp(operator, "maxValue")==0) {
        p=maxValue;
        //分开写
        //p!=NULL 为了程序的健壮性
        if (p!=NULL){
        int maxValue=p(num1,num2);
        printf("%d和%d中的最大值:%d\n",num1,num2,maxValue);
        }
    }else if (strcmp(operator, "sum")==0){
        p=sumTwoNumber;
        if (p!=NULL) {
            int sumValue=p(num1,num2);
            printf("%d+%d=%d\n",num1,num2,sumValue);
        }
    }else{
        printf("输入有误\n");
    }
    //总体写
    if (p!=NULL) {
        int returnValue=p(2,4);
        printf("2,4进行%s运算后返回的值:%d\n",operator,returnValue);
    }
    
    //定义一个含有函数指针的形参的函数,实现加减乘除
    char operator1[10]={0};
    printf("要进行运算的函数名:\n");
    scanf("%s",operator1);
    getchar();
    if (strcpy(operator1, "sumTwoNUmber")==0) {
        p=sumTwoNumber;
    }else if (strcpy(operator1, "maxValue")==0){
        p=maxValue;
    }
    if (p!=NULL) {
        int result=getValueOfOperation(num1, num2, p);
        printf("%d和%d进行%s运算后的结果:%d\n",num1,num2,operator1,result);
    }
#pragma mark 回调函数
    //回调过程:在getValueOfOperator执行过程中,通过传入的参数(函数指针),调用执行某个函数。
    //回调函数:在函数执行过程中,被函数指针调用的函数。(名词)
    //函数回调:调用回调函数的 操作。---操作(动词)
 
    //练习5、
    //写一个函数查找成绩90分以上的学员,使用回调函数在姓名后面加上“高富帅”。
     //1、新建一个文件夹
     //2、声明结构体类型(姓名,性别,年龄,分数);定义结构体数组;声明,定义函数实现查找成绩90分以上的学员。
     //3、提示:1)回调函数:在姓名后加高富帅。2)输出所有的学生信息,写成函数。
    Student stu[3]={
        {"yibella",'m',22,98.5},
        {"jack",'f',23,95},
        {"captain",'f',34,89}
    };
    void (*point)(Student stu[],int n)=printMessages;
    pp p1=addPostfix;
    findScoreOver90(stu, 3, point,p1);
    
    //最原始的排序方式
    void (*pointSort)(Student stu[],int n)=printAllInformation;
    sortAscendByAge(stu, 3, pointSort);
    sortAscendByName(stu, 3, pointSort);
    sortAscendByScore(stu, 3, pointSort);
#pragma mark 动态函数
    printf("\n==================================================\n");
    printf("动态函数指针分配:\n");
    //进化第一次----程序员可以在应用程序中动态的选择要执行的函数
    BOOL (*pointSortByBOOL)(Student stu1,Student stu2);
    pointSortByBOOL=compareStudentByAge;
    sortStudent(stu, 3, pointSortByBOOL);
    
    //进化第二次----用户可以自己控制功能,实现动态匹配执行的函数
    //定义结构体数组
    FunctionList list[3]={
        {"name",compareStudentByName},
        {"age",compareStudentByAge},
        {"score",compareStudentByScore}
    };
    //输入执行的函数名
    char _names[10]={0};
    printf("输入你要执行的函数名(age,name,score):\n");
    int aa=0;
    scanf("%d",&aa);
    scanf("%s",_names);
    getchar();
    //定义一个函数指针变量
    POINT point_names=NULL;
    //调用一个返回函数指针的函数
    point_names=judgeFunction(_names, list, 3);
    if(point_names!=NULL){
    //此时的point_names已经前面返回的函数名,调用排序函数
    sortStudent(stu, 3, point_names);
    }
   
    return 0;
}

自定义文件Student=====》

Student.h

//
//  Student.h
//  Lesson_15-8-11
//
//  Created by lanou3g on 15/8/11.
//  Copyright (c) 2015年 lanou.3g.com. All rights reserved.
//

#import <Foundation/Foundation.h>

typedef struct Student{
    char _names[20];
    char _sex;
    int _age;
    float _score;
}Student;
//为void (*point)(Student stu[],int n)取一个别名 point
typedef void (*point)(Student stu[],int n);
//取别名
typedef void (*pp)(char *point);
//取别名
typedef void (*point_postfix)(char *point);
//=====================================================
//声明查找成绩在90分以上的函数
void findScoreOver90(Student stu[],int n,point point,pp p);
//声明打印学员信息的函数
void printMessages(Student stu[],int n);
//声明为满足条件的学员名字添加后缀的函数
void addPostfix(char *point);

Student.m

//
//  Student.m
//  Lesson_15-8-11
//
//  Created by lanou3g on 15/8/11.
//  Copyright (c) 2015年 lanou.3g.com. All rights reserved.
//

#import "Student.h"

//实现查找成绩在90分以上的学员
void findScoreOver90(Student stu[],int n,point point,pp p){
    int ScoreLimit=90;
    //用来存储成绩90分以上的学员结构体数组。
    Student stuTemp[10]={0};
    //记录90分以上的学员的人数。
    int count=0;
    for (int i=0,j=0; i<n ; i++) {
        //遍历,找到成绩90分以上的学员,并把名字后加 高富帅。
        if (stu[i]._score>ScoreLimit) {
            stuTemp[j]=stu[i];
            //下面是两种加后缀的方法
            //方法一 ====》是利用回调函数实现功能
            p(stu[i]._names);
            //方法二 ====》是直接加后缀
//            strcat(stu[i]._names, "高富帅");
            
            p(stuTemp[j]._names);
//            strcat(stuTemp[j]._names, "高富帅");
            j++;
            count++;
        }
    }
    //回调函数的应用
    //传过去的结构体数组是成绩是90分以上的。
//    point(stuTemp,count);
    //注释掉的是用来输出成绩90分以上的学员的信息。
    point(stu,n);
}

void printMessages(Student stu[],int n){
    //输出全部的学员的信息
    for (int i=0; i<n ; i++) {
        printf("%s\t\t%c\t%d\t%.2f\n",stu[i]._names,stu[i]._sex,stu[i]._age,stu[i]._score);
    }
    printf("\n============================================\n");
    //可以只输出成绩在90分以上的学员的信息
//    for (int i=0; i<n ; i++) {
//        printf("%s\t\t%c\t%d\t%.2f\n",stu[i]._names,stu[i]._sex,stu[i]._age,stu[i]._score);
//    }
}
//给满足条件的名字加后缀
void addPostfix(char *point){
    strcat(point, "高富帅");
}

自定义的Sort文件======》

Sort.h

//
//  Sort.h
//  Lesson_15-8-11
//
//  Created by lanou3g on 15/8/11.
//  Copyright (c) 2015年 lanou.3g.com. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Student.h"
//第一种:===》最原始的分个排序
//按年龄排序
void sortAscendByAge(Student stu[],int n,point point);
//按姓名排序
void sortAscendByName(Student stu[],int n,point point);
//按成绩排序
void sortAscendByScore(Student stu[],int n,point point);
//打印所有信息
void printAllInformation(Student stu[],int n);
//第二种:===》把重复代码最简化
//给一个函数指针取别名  *后面的就是别名
typedef BOOL (*POINT)(Student stu1,Student stu2);
typedef void (*point)(Student stu[],int n) ;

//声明判断姓名的先后次序的函数
BOOL compareStudentByName(Student stu1,Student stu2);
//声明判断年龄的大小的函数
BOOL compareStudentByAge(Student stu1,Student stu2);
//声明判断成绩的大小的函数
BOOL compareStudentByScore(Student stu1,Student stu2);
//声明一个根据传入的函数指针,选择特定的排序方式的函数
void sortStudent(Student *stu,int n,POINT point);

//第三种:===》函数指针做返回值:在第二种的基础上再简化
//一个函数列表,把字符串和函数名一一对应起来
typedef struct FunctionList{
    char name[10];//函数名对应的字符串
    POINT p_compare;//函数指针--函数名
}FunctionList;
//声明一个返回函数指针的函数
POINT judgeFunction(char *name,FunctionList *list,int n);


Sort.m


//
//  Sort.m
//  Lesson_15-8-11
//
//  Created by lanou3g on 15/8/11.
//  Copyright (c) 2015年 lanou.3g.com. All rights reserved.
//

#import "Sort.h"
//第一种=====》
//实现按年龄排序--point为函数指针
void sortAscendByAge(Student stu[],int n,point point){
    //中间结构体变量
    Student stu_temp={0};
    //利用冒泡排序
    for (int i=0; i<n ; i++) {
        for (int j=0; j<n-i-1; j++) {
            if (stu[j]._age>stu[j+1]._age) {
                stu_temp=stu[j];
                stu[j]=stu[j+1];
                stu[j+1]=stu_temp;
            }
        }
    }
    printf("按年龄排序:\n");
    //函数回调--操作
    point(stu,n);
}
//实现按姓名排序--point函数指针
void sortAscendByName(Student stu[],int n,point point){
    //中间结构体变量
    Student stu_temp={0};
    for (int i=0; i<n ; i++) {
        for (int j=0; j<n-i-1; j++) {
            if (strcmp(stu[j]._names, stu[j+1]._names)>0) {
                stu_temp=stu[j];
                stu[j]=stu[j+1];
                stu[j+1]=stu_temp;
            }
        }
    }
    printf("按姓名排序:\n");
    //函数回调
    point(stu,n );
}
//实现按成绩排序--point函数指针
void sortAscendByScore(Student stu[],int n,point point){
    //中间结构体变量
    Student stu_temp={0};
    for (int i=0; i<n ; i++) {
        for (int j=0; j<n-i-1; j++) {
            if (stu[j]._score-stu[j+1]._score>0.000001) {
                stu_temp=stu[j];
                stu[j]=stu[j+1];
                stu[j+1]=stu_temp;
            }
        }
    }
    printf("按成绩排序:\n");
    point(stu,n );
}
//打印所有的信息
void printAllInformation(Student stu[],int n){
    for (int i=0; i<n ; i++) {
        printf("%s\t\t%c\t\t%d\t%.2f\n",stu[i]._names,stu[i]._sex,stu[i]._age,stu[i]._score);
    }
    printf("\n");
}
//第二种:===》把上面函数块中的if条件判断用函数指针调用相应的功能--动态调用
//第二种明显比第一种好太多
//实现判断姓名的大小功能
BOOL compareStudentByName(Student stu1,Student stu2){
    //实现升序的条件
    return strcmp(stu1._names, stu2._names)>0;
}
//实现判断年龄大小的功能
BOOL compareStudentByAge(Student stu1,Student stu2){
    return stu1._age-stu2._age>0;
}
//实现判断成绩的大小功能
BOOL compareStudentByScore(Student stu1,Student stu2){
    return stu1._score-stu2._score>0.000001;
}
//POINT为函数指针的别名,point为定义的函数指针。
void sortStudent(Student *stu,int n,POINT point){
    Student stu_temp={0};
    for (int i=0; i<n ; i++) {
        for (int j=0; j<n-i-1; j++) {
            //函数调用,这里的函数调用,根据maim.m传过来的参数,动态的选择执行某个功能。
            if (point(stu[j],stu[j+1])) {
                stu_temp=stu[j];
                stu[j]=stu[j+1];
                stu[j+1]=stu_temp;
            }
        }
    }
    //调用打印信息的函数
    printAllInformation(stu, n);
}

//第三种:===》函数指针做返回值
//根据用户输入的字符串返回相应的函数名(函数指针)
//并且,返回的函数名是之前定义好的结构体成员变量--也就是函数名
POINT judgeFunction(char *name,FunctionList *list,int n){
    POINT point_name=NULL;
    for (int i=0; i<n ; i++) {
        if (strcmp(name, list[i].name)==0) {
            point_name=list[i].p_compare;
        }
    }
    //返回函数指针--也就是结构体数组中对应的函数名
    return point_name;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值