函数指针

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

代码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. 【转】这些编程语言程序员工资最高!Java才第四

    原文网址:http://tech.hexun.com/2016-07-18/185009761.html 在众多行业中,程序员属于高薪职业.无论是在国外还是国内,程序员的薪金水平普遍高于其他行业的工作 ...

  2. asp.net读取xml方法

    这个适合刚学asp.net的同学,大神直接略过好了,asp.net经常会有很多用到XML的地方,比如全国省市的联动,以及一些菜单读取等等都有xml的影子,直接贴代码,以便我以后用到的时候忘了,注释我写 ...

  3. 常用的Oracle数据库语句 (待更新完毕)

    一.常用的查询语句 1.1 常用查询 查表中有多少个字段 select count(*) from user_tab_columns where table_name=upper('表名') 或者 s ...

  4. eclipse quick diff功能

    Eclipse文本编辑器和Java编辑器都提供了quick diff功能.这就使得你可以快速地识别出当前所编辑文件版本和该文件的参考版本之间的不同. 如果编辑器的quick diff功能没有启用,可以 ...

  5. 部署WAR文件到tomcat

    1.启动tomcat服务 2.在浏览器的地址栏输入地址“http://localhost:8080/manager/html”进入tomcat管理界面. 如果要管理的服务器是在网络中,则将localh ...

  6. spring依赖注入原理剖析

    PropertyDefinition.java package junit.test; public class PropertyDefinition { private String name; p ...

  7. Github在windows7环境下使用入门

    1.下载并安装 下载和安装一般都没什么问题,网上的链接一大堆,不过还是在此给一个安装的地址和安装的参考吧. 当然,安装完成后要保证git能使用,必须配置github 2.配置github 首先是要创建 ...

  8. MySQL Connector_J_5.1.34_2014.10

    5.1版本符合JDBC3.0和JDBC4.0规范 跟MySQL4.1-5.7兼容 5.1.21以后支持JDK7的JDBC4.1规范 在MySQL4.1之前,是不支持utf8的 com.mysql.jd ...

  9. 快速入门linux系统的iptables防火墙 1 本机与外界的基本通信管理

    概述 iptables是一种运行在linux下的防火墙组件,下面的介绍可以快速的学习iptables的入门使用. 特点(重要) 它的工作逻辑分为 链.表.规则三层结构. 数据包通过的时候,在对应表中, ...

  10. extjs 学习笔记(二)

    EXTJS实用开发指南 1. 要使用ExtJS 框架的页面中一般包括下面几句: <link rel="stylesheet" type="text/css" ...