找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3618|回复: 0
打印 上一主题 下一主题
收起左侧

C语言函数指针,函数动态回调

[复制链接]
跳转到指定楼层
楼主
ID:91442 发表于 2015-10-29 15:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
      经常有人问,学习这些理论有什么用?我无语了。因为懂行的人不会问这种问题;不懂行的人,你再怎么解释人家也不会明白这个道理。如果人家追问:“这个能换钱吗?”,我就直接SB了。

       这是一个经典的C语言函数指针,函数动态回调callback例程。写出来,闲暇时刻自己可以随时学习,温故。通过不断深入学习C语言,了解到C++,C#,java都是C语言的儿孙辈,他们都继承了C语言的至少90%基因。越来越感受到C语言的博大精深。在嵌入式学习的路上正真的绊脚石和瓶颈通常都是因为C语言不扎实,导致感觉越学越难。函数指针与函数动态回调在系统软件如uc/os-ii操作系统,STemWin以及fat32文件系统中常常遇到。函数动态回调的这种程序设计模式值得学习。

        本例程主要知识点:1,冒泡排序算法,2,结构体数组,3,指向函数的指针变量,4,函数回调,5,通过输入与函数名相同的字符串调用相对应的函数(重点!)。


////////////////////////////////////////
.c源码:////////////////////////////////////////////////////////////


 
#include"stdio.h"
#include"string.h"
//#include"stdlib.h"

/*  函数指针;即指向函数的指针变量,函数名就是函数的入口地址
int (*PFUN)(int x,int y)=NULL;//3部分:类型,变量名,初值
如:typedef int(*PFUN)(int x,int y);//PFUN就代表返回值是int类型并且带有2个形参x,y的函数的入口地址;PFUN就是函数名
 */
struct Student
char *name;
float score;
int age;
    
};
//typedef struct  Student ST;//这样定义一个类型也可以“ST st[4];”

Student st[4]={
{"zhangsan",89,28},
{"lisi",90,24},
{"wangwu",79,20},
{"zhaoda",77,18}
};//结构体数组

void sort(Student *s,int count)//另一种冒泡排序,从小到大排序;注意:只能传递指针!
{
for(int i=0;i<count-1;i++)//第一层循环:从数列中找出最大数放到数列末尾
{
  for(int j=0;j<(count-1-i);j++)//第二层循环:从数列中找出次大数放到数列尾部排序
                {
if(s[j].age>s[j+1].age)
{
 Student temp;
 temp.age=s[j].age;
 s[j].age=s[j+1].age;
                          s[j+1].age=temp.age;//大的往后排一个位置,通过这一轮count-1-i次循环就将数列中最大数排到了末尾
}
}
 
}
//printf("%s\n\r %.2f\n\r %d\n\r",st[i].name,st[i].score,st[i].age);

}
void display(void)
{
for(int i=0;i<4;i++)
{
    //  sort(st,4);
//  printf("%s\n\r %.2f\n\r %d\n\r",st[i].name,st[i].score,st[i].age);
printf("4个结构体学生的年龄从小到大排序: %d\n\r",st[i].age);
     printf("4个结构体学生的score从小到大排序: %.2f\n\r",st[i].score);
     printf("4个结构体学生的name从小到大排序: %s\n\r",st[i].name);
}

}
typedef int (*PFUN)(int x,int y);//typedef后定义的新类型名
int Sum(int x,int y)//求和函数
{
return (x+y);
}
int Maxvalue(int x,int y)//求最大值函数
{
return x>y?x:y;//三目运算符,如果x大于y则输出x,否则输出y
}
int Minus(int x,int y)//求差值函数
{
return x-y;//
}
/*
如:Sum1(int x,int y,Sum);//这句就代表实际上运行的是Sum(int x,int y)函数即“求和”
*/
int Sum1(int x,int y,PFUN Funname)//求和函数
{
return Funname(x,y);
}
int Maxvalue1(int x,int y,PFUN Funname_Max)//求最大值函数
{
return Funname_Max(x,y);
//return x>y?x:y;//三目运算符,如果x大于y则输出x,否则输出y
}
int Minus1(int x,int y,PFUN Funname_Minus)//求差值函数
{
    return  Funname_Minus(x,y);
//return x-y;//
}
struct FuntionPair
{
   char name[20];
   PFUN Pfun_name;
};
//typedef struct FuntionPair FP;
/* 
定义并初始化一个FuntionPair结构体数组;
*/
FuntionPair FPs[3]={
    {"Summ",Sum},
    {"Minus",Minus},
     {"Maxvalue",Maxvalue}
};
//函数指针,动态回调,将传入的字符串名与结构体数组的字符串
PFUN CallBackWithName(char * Name)
{  
for(int i=0;i<3;i++)//循环比较
{
      if(strcmp(FPs[i].name,Name)==0)//FPs[i].name是字符串
 {
   return FPs[i].Pfun_name;
  
 }
};
 // return FP[i].Pfun_name;
return Maxvalue;//如果没有匹配的函数名,就返回Maxvalue函数,即运行该函数

}
void main(void)
{
   
   PFUN p=Minus;//这里p就可以以int类型函数函数名赋值
   int a=p(30,50);
   printf("差值:%d\n\r",a);
   
   PFUN p1=Sum;//这里p就可以以int类型函数函数名赋值
   int b=p1(30,50);
   printf("求和:%d\n\r",b);

   PFUN p2=Maxvalue;//这里p就可以以int类型函数函数名赋值
   int c=p2(30,50);
   printf("最大值:%d\n\r",c);

   
   int d=Minus1(90,80,Sum);
   printf("回调函数例程:%d\n\r",d);
///////////////////////函数动态回调////////////////////
   PFUN p3=CallBackWithName("summ");
   int e=p3(90,80);
   printf("函数指针例程:%d\n\r",e);
////////////注意打印结果区别///////////
   PFUN p4=CallBackWithName("Summ"); //传入与函数名相同的字符串就相当于执行了对应的函数
   int f=p4(90,80);
   printf("函数指针例程:%d\n\r",f);



   sort(st,4);
   display();


} 

////////////////////////////////////////.c源码:////////////////////////////////////////////////////////////

   “有修行的人是高尚的!” 。 这句话
送给那些默默无闻的学习者,探索者。
                                                                                          by   GKXW
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表