函数指针

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

代码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. php的session_start

    如果session使用cookie记录,那么在session_start时会设置一个cookie,参数取决于php.ini的设置,当然也可以通过session_set_param在程序里设置.不同站点 ...

  2. 输出图片的php代码前面不能有空白行

    第一行增加一个空白行,就至少会输出一个换行符在图片数据流的前面而图片是按图片流提供的信息显示的,前面多了内容就无法解析了.

  3. 更新的packages.config所有的软件包?

    1. 你NuGet.exe的恢复你的包.运行的每个项目. nuget install packages.config 或用NuGet的2.7可以恢复所有包中的行. nuget restore Your ...

  4. 15、NFC技术:使用Android Beam技术传输文件

    传输文件的API 从Android4.1开始,NfcAdapter类增加了如下两个推送数据的方法. NfcAdapter.setBeamPushUris NfcAdapter.setBeamPushU ...

  5. Asp.Net学习进度备忘(第一步:ASP.NET Web Forms)

    书签:“Web Pages”和“MVC”跳过:另外跳过的内容有待跟进 __________________ 学习资源:W3School. _________________ 跳过的内容: 1.ASP. ...

  6. Go语言相关图书推荐

    Go语言编程 作      者 许式伟 等 著 出 版 社 人民邮电出版社 出版时间 2012-08-01 版      次 1 页      数 245 印刷时间 2012-08-01 开      ...

  7. spark connect to Cassandra problem

    Cassandra rowkey is Blob type, cannot select by spark. How?

  8. android LocalActivityManager说明

          类概述 Helper class for managing multiple running embedded activities in the same process. This c ...

  9. Zookeeper Hello World

    1.Zookeeper的安装使用 在官网上下载zk的安装包(http://labs.renren.com/apache-mirror/zookeeper/),解压后cd到zk的目录下. 单机版安装方法 ...

  10. 徐汉彬:亿级Web系统搭建——单机到分布式集群(转载)

    文章转载自http://www.csdn.net/article/2014-11-06/2822529/1 当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的 ...