函数指针

是一个指针,指向函数的指针,指针存放的都是地址,所以函数指针存放的是函数的地址。数组名就是数组的首地址,函数名就是函数的首地址。与数组类似。

代码demo

   int (*p) (int ,int ) = NULL;

// int (*) (int ,int )   这就是指针变量的类型  (除了函数名)
p = maxValue; 指针变量存储的是函数的地址(函数名) // 定义一个有两个整形参数且返回为整型的函数指针
#import <Foundation/Foundation.h>

//    求两个数字的最大值
// 函数的类型就是由 返回值类型 + 参数个数及类型
int maxValue(int , int );
int maxValue(int a , int b ){
return a > b ? a :b ;
}
int minValue(int ,int );
int minValue(int a, int b){
return a < b ? a : b;
}
//char getString(); 不能这样写
char *getString();//类型 char * 函数名 getString 返回值类型为 char * 而且没有参数的函数
char *getString(){
// char a[10] = "hello";
char *a = "hello";
return a;
} void outputNumber(int a); // 类型 void ()
void outputNumber(int a){//void * 是一个泛型 返回泛型的指针 ???
printf("\noutputNumber 输出传入数字 %d\t",a);
} // 定义一个函数求两个浮点数的和
float requireTwoFloatSum(float a, float b);
float requireTwoFloatSum(float a, float b){
return a + b;
}
int main(int argc, const char * argv[]) { // 定义一个有两个整形参数且返回为整型的函数指针
int (*p) (int ,int ) = NULL;
// int (*) (int ,int ) 这就是指针变量的类型 (除了函数名)
p = maxValue; // 指针变量存储的是函数的地址(函数名)
int value = p (,);
printf("\nvalue = %d \t",value);
int (*p0) (int , int ) = NULL;
p0 = minValue;
int min = p0( , );
printf("\n min = %d\n",min); // 分别定义函数指针,来指向对应的函数,然后使用此指针实现函数的调用
// char (*p1) = NULL;
// p1 = getString;
char * str = getString();//没有参数小括号 不能省略
// 练习:分别定义函数指针,来指向对应的函数,然后使用此指针实现函数的调用
char *(*p1)() = NULL; //第二个 * 是标记 p1 是一个指针 p1的类型是char *(* )()
printf("%s\t",str); // outputNumber 输出传入数字
int (*p2)(int) = NULL;
p2 = outputNumber;
p2(); // 定义一个函数求两个浮点数的和
float (*p3)(float ,float) = NULL;
p3 = requireTwoFloatSum;
float a = p3(15.44,14.33);
printf("\n定义一个函数求两个浮点数的和 %.2f",a);
return ;
}
#import <Foundation/Foundation.h>

//    定义一个函数求两个整数的和
int requireTwoSum(int a, int b);
int requireTwoSum(int a, int b){
return a + b;
} // 求两个数字的最大值
int maxValue(int , int );
int maxValue(int a , int b ){
return a > b ? a :b ;
}
// 求两个数字的最小值
int minValue(int ,int );
int minValue(int a, int b){
return a < b ? a : b;
} //函数当成一个函数形参
typedef int (*FUNCTION)(int ,int); //如果这里不写 typedef 的话, typedef FUNCTION f;这句就要报错 ,typedef 只是为数据类型重命名
//这个 FUNCTION 可以指向任意一个 int (* )(int ,int) 这种类型的函数(上面的求和,求最大值,求最小值)
typedef FUNCTION f;
int getValue(int ,int ,f );//声明了一个可以传递函数的函数
int getValue(int a ,int b ,f f1 ){
int q = f1(a,b);
return q;
} int main(int argc, const char * argv[]) { int arr = getValue(, , maxValue);
printf("maxValue = %d\t",arr);
int brr = getValue(, , minValue);
printf("minValue = % d\t",brr);
int crr = getValue(, , requireTwoSum);
printf("TwoSum = %d\t",crr); return ;
}

函数指针 demo

typedef 给结构体 与 指针函数 定义新的名字的时候,要注意  把新名字存放正确的地方。typedef 只是给数据类型重新定义名字

应用实战

#import <Foundation/Foundation.h>
#import "runSort.h"
#import "teacher.h" int main(int argc, const char * argv[]) {
/*
Student stu[5] ={
{"zhang san", 12 , 89},
{"li si", 15 , 98},
{"wang wu", 45 , 78},
{"liu guang dan ", 18, 45},
{"hei li qi", 11, 49}
};
match fun[3] = {
{compaerByAge,"age"},
{compaerByName,"name"},
{compaerByScore,"score"}
};
compareMethood pp = getFunction(fun, 2, "name");
sortArrAccending(stu, 5 ,pp);
*/
Teacher teacher[]={
{"wang ma zi",'m',,,8.9},
{"li si",'m',,,9.6},
{"huang xing",'f',,,4.9},
{"zhang ming",'f',,,},
{"zhang san",'f',,,7.5} };
match2 fun2[]={
{compareNameByAscending,"namesx"},
{compareNmaeByDescending,"namejx"},
{compareNumByAscending,"numsx"},
{compareNumByDescending,"numjx"},
{compareMarkByAscending,"marksx"},
{compareMarkByDescending,"marksx"},
};
compareMethood2 p2 = getFounction(fun2, , "numsx");
sortTeachers(teacher,,p2); return ;
}

mian 

#import <Foundation/Foundation.h>

typedef struct teacher{
char name[];
char gender;
int age;
int num;
float mark;
}Teacher;
//指针函数(对比下面好多升序降序的函数)
typedef BOOL (* compareMethood2)(Teacher teacher1,Teacher teacher2) ;
typedef struct Match2{
compareMethood2 Function2;
char fname2[];
}match2; //打印 teacher 信息
void printTeacher(Teacher * teacher);
//函数指针类型
typedef BOOL(*compareFunctionPointer)(Teacher teacher1,Teacher teacher2);
//老师数组排序函数
void sortTeachers(Teacher *teacher,int count ,compareFunctionPointer cfp);
//声明一个打印数组中所有老师的函数
void printTeachers(Teacher *teachers,int count);
//两个比较姓名的函数 升序
BOOL compareNameByAscending(Teacher teacher1, Teacher teacher2);
//降序
BOOL compareNmaeByDescending(Teacher teacher1, Teacher teacher2);
//分别声明两个比较Teacher员工编号的函数 升序
BOOL compareNumByAscending(Teacher taecher1, Teacher teacher2);
//降序
BOOL compareNumByDescending(Teacher teacher1,Teacher teacher2);
//分别声明两个比较Teacher员工评分的函数 升序
BOOL compareMarkByAscending(Teacher teacher1,Teacher teacher2);
//降序
BOOL compareMarkByDescending(Teacher teacher1,Teacher teacher2);
//声明一个输出教师数组中全部男老师的函数
void printMaleTeacher(Teacher *teacher,int count);
//声明一个输出教师数组中全部女老师的函数
void printFemaleTeacher(Teacher *teacher,int count);
//条件匹配函数
compareMethood2 getFounction(match2 * match2, int count ,char * frame2);

teacher.h

#import "teacher.h"

//打印 teacher 信息
void printTeacher(Teacher * teacher){
printf("姓名: %s 性别: %c 年龄: %d 工号: %d 评分: %.2f \n",teacher->name,teacher->gender,teacher->age,teacher->num,teacher->mark);
}
//老师数组排序函数
void sortTeachers(Teacher *teacher,int count ,compareFunctionPointer cfp){
if (cfp == NULL) {
printf("没有匹配");
}else{
for (int i = ; i < count - ; i++) {
for (int j = ; j < count - - i; j++) {
if (cfp(*(teacher + j),*(teacher + j + ))) {
Teacher temp = *(teacher + j);
*(teacher + j) = *(teacher + j + );
*(teacher + j + ) = temp;
}
}
}
}
printTeachers(teacher ,count);
}
//声明一个打印数组中所有老师的函数
void printTeachers(Teacher *teachers,int count){
for (int i = ; i < count ; i++) {
printf("姓名: %s 性别: %c 年龄: %d 工号: %d 评分: %.2f \n",(teachers + i)->name,(teachers + i)->gender,(teachers + i)->age,(teachers + i)->num,(teachers + i)->mark);
}
}
//两个比较姓名的函数 升序
BOOL compareNameByAscending(Teacher teacher1, Teacher teacher2){
return strcmp(teacher1.name,teacher2.name);
}
//降序
BOOL compareNmaeByDescending(Teacher teacher1, Teacher teacher2){
return strcmp(teacher2.name, teacher1 .name);
}
//分别声明两个比较Teacher员工编号的函数 升序
BOOL compareNumByAscending(Teacher teacher1, Teacher teacher2){
return teacher1.num > teacher2.num;
}
//降序
BOOL compareNumByDescending(Teacher teacher1,Teacher teacher2){
return teacher2.num > teacher1.num;
}
//分别声明两个比较Teacher员工评分的函数 升序
BOOL compareMarkByAscending(Teacher teacher1,Teacher teacher2){
return teacher1.mark > teacher2.mark;
}
//降序
BOOL compareMarkByDescending(Teacher teacher1,Teacher teacher2){
return teacher2.mark > teacher1.mark;
}
//声明一个输出教师数组中全部男老师的函数
void printMaleTeacher(Teacher *teacher,int count){
for (int i = ; i < count; i++) {
if ((teacher + i)->gender == 'm') {
printTeacher((teacher + i));
}
}
}
//声明一个输出教师数组中全部女老师的函数
void printFemaleTeacher(Teacher *teacher,int count){
for (int i = ; i < count; i++) {
if ((teacher + i)->gender == 'f') {
printTeacher((teacher + i));
}
}
}
//条件匹配函数
compareMethood2 getFounction(match2 * match2, int count, char *fname2){
for (int i = ; i < count; i++) {
if (strcmp(match2[i].Function2, fname2)) {
return match2[i].Function2;
break;
}else{
return NULL;
}
}
return ;
}

teacher.m

#import <Foundation/Foundation.h>

typedef struct{//学生信息
char name[];
int age;
float score;
}Student;
typedef BOOL(*compareMethood)(Student,Student);
typedef struct Match{
compareMethood Function ;
char fname[];
}match;
//打印学生信息
void outputAllStuInfo(Student *stu,int count);
//升序排序信息
void sortArrAccending(Student *stu,int count ,compareMethood Condition);
//比较两者年龄
BOOL compaerByAge(Student stu1, Student stu2);
//比较两者成绩
BOOL compaerByScore(Student stu1,Student stu2);
//比较两者姓名
BOOL compaerByName(Student stu1,Student stu2);
//条件匹配函数
compareMethood getFunction(match * match ,int count , char *Fname);

runSort.h

#import "runSort.h"

//打印学生信息
void outputAllStuInfo(Student *stu,int count){
for (int i = ; i < count; i++) {
printf("name = %s ,age = %d score = %.2f\n",(stu + i)->name,(stu + i)->age,(stu + i)->score);
}
} //升序排序信息
void sortArrAccending(Student *stu,int count,compareMethood Condition){
if (Condition == NULL) {
printf("没有匹配");
}else{
for (int i = ; i < count - ; i++) {
for (int j = ;j < count - - i; j++) {
if (Condition(*(stu + j),*(stu + j + ))) {
Student temp = *(stu + j);
*(stu + j ) = *(stu + j + );
*(stu + j + ) = temp;
}
}
}
}
outputAllStuInfo(stu, );
} //比较两者年龄
BOOL compaerByAge(Student stu1, Student stu2){
return stu1.age > stu2.age;
} //比较两者成绩
BOOL compaerByScore(Student stu1,Student stu2){
return stu1.score > stu2.score;
} //比较两者姓名
BOOL compaerByName(Student stu1,Student stu2){
return strcmp(stu1.name ,stu2.name);
} //条件匹配函数
compareMethood getFunction(match * match ,int count , char *Fname){
for (int i = ; i < count; i++) {
if (strcmp( match[i].Function , Fname)) {
return match[i].Function;
}else{
return NULL;
}
}
return ;
}

runSort.h

C:函数指针、回调函数的更多相关文章

  1. C语言笔记 08_函数指针&回调函数&字符串&结构体&位域

    函数指针 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调用函数.传递参数. 函数指针变量的声明: / ...

  2. typedef void(*Fun) (void)是什么意思 函数指针(回调函数) 和函数对象总结

    https://blog.csdn.net/FreeApe/article/details/49124043 bool (*pf)(const string &,const string &a ...

  3. delphi 中的函数指针 回调函数(传递函数指针,以及它需要的函数参数)

    以下代码仅仅是测试代码:delphi XE7 UP1 interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.V ...

  4. C/C++回调方式系列之一 函数指针和函数回调模式

    一.函数指针 1. 函数的定义 return_type function_name(parameter list) { function_body } return_type: 返回值,函数一定有返回 ...

  5. Delphi 函数指针(函数可以当参数)

    首先学习: 指向非对象(一般的)函数/过程的函数指针 Pascal 中的过程类型与C语言中的函数指针相似,为了统一说法,以下称函数指针.函数指针的声明只需要参数列表:如果是函数,再加个返回值.例如声明 ...

  6. C++中类成员函数作为回调函数

    注:与tr1::function对象结合使用,能获得更好的效果,详情见http://blog.csdn.net/this_capslock/article/details/38564719 回调函数是 ...

  7. Day8 函数指针做函数参数

    课堂笔记 课程回顾         多态 virtual关键字 纯虚函数 virtual func() = 0;         提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. ...

  8. C++中 线程函数为静态函数 及 类成员函数作为回调函数

    线程函数为静态函数: 线程控制函数和是不是静态函数没关系,静态函数是在构造中分配的地址空间,只有在析构时才释放也就是全局的东西,不管线程是否运行,静态函数的地址是不变的,并不在线程堆栈中static只 ...

  9. JS中的匿名函数、回调函数、匿名回调函数

    工欲善其事必先利其器 在学习JavaScript设计模式一书时,遇到了“匿名回调函数”这个概念,有点疑惑,查找了些资料重新看了下函数的相关知识点之后,对这个概念有了认识.九层之台,起于垒土.在熟悉这一 ...

  10. 【知识点】inline函数、回调函数、普通函数

    目录 一.inline内联函数 1.1 使用 1.2 编译器对 inline 函数处理步骤 1.3 优缺点 1.3.1 优点 1.3.2 慎用内联 1.3.3 不宜使用内联 1.4 虚函数(virtu ...

随机推荐

  1. 前台实现下载xml功能

    阅读目录 介绍问题 MIME TYPE 解决问题 介绍问题 平时我们通过href去链接文件时,一般情况是对于zip.jar等下载功能,而对于xml.css.html.js等都是查看功能. 现在下面的代 ...

  2. .vdat文件怎么打开

    http://tieba.baidu.com/p/2947300642 无需转换,把后缀修改为MP4,就可以了

  3. 定制Bootstrap遇到无法下载的解决——Blob下载注意事项

    今天定制bootstrap(在这里),全部的勾都选过了,于是兴高采烈地点击“编译并下载”.等了一会儿,迅雷7跳出来了“新建下载任务”,但是它居然说这个url不合法! url像这样: blob:http ...

  4. ylb:子查询(嵌套子查询)和子查询(相关子查询)

    ylbtech-SQL Server:SQL Server-子查询(嵌套子查询)和子查询(相关子查询) SQL Server 子查询(嵌套子查询)和子查询(相关子查询). 1,ylb:1,子查询(嵌套 ...

  5. Dev gridControl z

    Dev gridControl 添加表标题 1.OptionsView ->ShowViewCaption = True 2.ViewCaption = "标题" Dev g ...

  6. 用ASP.Net写一个发送ICQ信息的程序

    用ASP.Net写一个发送ICQ信息的程序 这里我给大家提供一个很实用的例子,就是在线发送ICQ信息.想一想我们在网页上直接给朋友发送ICQ信息,那是多么美妙的事情啊.呵呵,在吹牛啊,其实ICQ本来就 ...

  7. Cocos2d-android (05) 渐变动画(颜色,淡入淡出。。。)

    淡入淡出.颜色渐变及动作重复执行 import org.cocos2d.actions.base.CCRepeatForever; import org.cocos2d.actions.interva ...

  8. 【DWT笔记】基于小波变换的降噪技术

    [DWT笔记]基于小波变换的降噪技术 一.前言 在现实生活和工作中,噪声无处不在,在许多领域中,如天文.医学图像和计算机视觉方面收集到的数据常常是含有噪声的.噪声可能来自获取数据的过程,也可能来自环境 ...

  9. QQ群聊天记录文件分割

    嗯,如题 是个蛋疼物 目前QQ的聊天记录导出功能很让人郁闷 三种聊天记录格式的导出 1  TXT   没图 2  BAK  只能再导入QQ使用 3  MHT 有图有字,缺点是一旦聊天记录很多,文件体积 ...

  10. gem openssl 出错

    Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources 1. ...