經常有人問,學習這些理論有什么用?我無語了。因為懂行的人不會問這種問題;不懂行的人,你再怎么解釋人家也不會明白這個道理。如果人家追問:“這個能換錢嗎?”,我就直接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 |