//
// main.m
// C10_函数指针
//
// Created by YIem on 15/11/23.
// Copyright (c) 2015年 www.yiem.net YIem博客. All rights reserved.
//

import <Foundation/Foundation.h>

import "MyFunc.h"

import <MyFunc2.h>

// 函数声明
int sum (int a, int b);
// 函数定义
int sum(int a, int b){

return a + b;

}
int sub(int a , int b);
int sub(int a, int b) {

return a - b;

}

// 最大值
int maxValue(int a, int b);
int maxValue(int a, int b) {

return a > b ? a : b;

}
// 最小值
int maxValie1(int a, int b);
int maxValie1(int a, int b) {

return a < b ? a : b;

}

// int(*)(int, int) 原类型
// PFUNC 新类型
//typedef int (*PFUNC)(int, int);
typedef int(*PFUNC)(int, int);
// 函数指针作为参数
//int getValue(int a, int b, int (*p) (int, int));
int getValue(int a, int b, PFUNC p);
int getValue(int a, int b, PFUNC p) {

return p(a, b);

}

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

if 0

// 函数调用

int r = sum(3, 5);
printf("%d\n", r);


// 函数的三要素: 声明/定义/调用
// 函数原型 函数类型
// int (int, int)
// 函数指针类型 = 函数原型(类型) *
// int (*) (int, int)
// p                    变量名
// NULL                 空指针
int (*p) (int, int) = NULL;
p = sum;
p = sub;
int r1 = p(3, 5);
printf("%d\n", r1);

// 练习: 定义两个函数,一个求最大值,一个求最小值,输入maxValue分别求3和5的最大值和最小值 (提示: 定义一个 函数指针,根据输入内容指向不同函数, 最后一次调用完)
char c = 0;
scanf("%c", &c);
int (*pp) (int, int) = NULL;
if ('a' == c) {
    pp = maxValue;
}   else if ('i' == c) {
    pp = maxValie1;
}
int r2 = pp(3, 5);
printf("%d\n", r2);

endif

// 函数回调
int r3 = getValue(3, 5, sum);
printf("%d\n", r3);


// 结构体数组
Stu s1 = {"大娃", 16, 1, 155, 100};
Stu s2 = {"三爷", 21, 185, 150, 100};
Stu s3 = {"Beta", 18, 190, 120, 101};
Stu s4 = {"春", 20, 170, 120, 102};
Stu s5 = {"11", 25, 169, 140, 59.9};
Stu s[5] = {s1, s2, s3, s4, s5};
// 排序

// 年龄
sortStu(s, 5, byAge);
// 身高
sortStu(s, 5, byHeight);


// 函数指针作为返回值
FUNCSTRUCT f1 = {"max", max};
FUNCSTRUCT f2 = {"min", min};
FUNCSTRUCT f[] = {f1, f2};
FUNC op = returnFunc("max", f, 2);
int result = op(3, 5);
printf("%d\n", result);



return 0;

}


MyFunc.h 文件
//
// MyFunc.h
// C10_函数指针
//
// Created by Marry W. on 11/23/15.
// Copyright (c) 2015 www.lanou3g.com 蓝鸥科技. All rights reserved.
//

import <Foundation/Foundation.h>

// .h
// 动态排序
struct stu {

char name[20];
int age;
float height;
float weight;
float score;

};
typedef struct stu Stu;
// 条件函数
// 年龄比较
BOOL byAge(Stu s1, Stu s2);
// 身高
BOOL byHeight(Stu s1, Stu s2);

// 排序函数
// SORTOP 排序条件
typedef BOOL(*SORTOP)(Stu, Stu);
void sortStu(Stu *s, int count, SORTOP p);


MyFunc.m 文件
//
// MyFunc.m
// C10_函数指针
//
// Created by Marry W. on 11/23/15.
// Copyright (c) 2015 www.lanou3g.com 蓝鸥科技. All rights reserved.
//

import "MyFunc.h"

// .m
// 年龄比较
BOOL byAge(Stu s1, Stu s2) {

return s1.age > s2.age;

}
// 身高
BOOL byHeight(Stu s1, Stu s2) {

return s1.height > s2.height;

}
// 排序函数
void sortStu(Stu *s, int count, SORTOP p) {

for (int i = 0; i < count - 1; i++) {
    for (int j = 0; j < count - 1 - i; j++) {
        // 通过函数指针得到比较结果
        if (p(s[j], s[j + 1])) {
            Stu temp = s[j];
            s[j] = s[j + 1];
            s[j + 1] = temp;
        }
    }
}
for (int i = 0; i < count; i++) {
    Stu t = s[i];
    printf("%s %d %f %f %f\n", t.name, t.age, t.height, t.weight, t.score);
}
printf("-------------华丽丽的分割线----------\n");

}


MyFunc2.h 文件
//
// MyFunc2.h
// C10_函数指针
//
// Created by Marry W. on 11/23/15.
// Copyright (c) 2015 www.lanou3g.com 蓝鸥科技. All rights reserved.
//

import <Foundation/Foundation.h>

// 函数
int max(int a, int b);
int min(int a, int b);

typedef int(*FUNC)(int, int);

struct func {

char fName[20];// 函数名的字符串描述
FUNC p;

};
typedef struct func FUNCSTRUCT;

// 函数指针作为返回值
// 参数1: 字符串
// 参数2: 函数指针结构体数组
// 参数3: 个数
FUNC returnFunc(char c, FUNCSTRUCT fs, int count);


MyFunc2.m 文件
//
// MyFunc2.m
// C10_函数指针
//
// Created by Marry W. on 11/23/15.
// Copyright (c) 2015 www.lanou3g.com 蓝鸥科技. All rights reserved.
//

import "MyFunc2.h"

// 函数
int max(int a, int b) {

return a > b ? a : b;

}
int min(int a, int b) {

return a < b ? a : b;

}
FUNC returnFunc(char c, FUNCSTRUCT fs, int count) {

for (int i = 0; i < count; i++) {
    FUNCSTRUCT f = fs[i];
    // 根据传入的字符串匹配 找到对应的函数通过函数指针返回
    if (strcmp(c, f.fName) == 0) {
        return f.p;
    }
}
return NULL;

}