前言
??????? 在前幾篇文章中,已經介紹了指針一些基本概念、用途和一些不同類型的指針,下文將介紹某些指針類型的運用。本文主要介紹函數指針數組、轉移表(函數指針的用途)、回調函數、qsort使用舉例等。
函數指針數組
??????? 函數指針數組即每個元素都是函數地址的數組。
//函數指針數組
int jia(int x, int y) {//加法函數return x + y;
}
int jian(int x, int y) {//減法函數return x - y;
}
int cheng(int x, int y) {//乘法函數return x * y;
}
int chu(int x, int y) {//除法函數return x / y;
}
int main() {int (*p[4]) (int, int) = {jia,jian,cheng,chu};//保證p與[]先結合成數組,之后再與*結合,構成指針數組,最后再和函數結合return 0;
}
?轉移表(函數指針的用途)
??????? 假如我們寫個程序完成對兩個數之間的簡單數學運算(加減乘除),按照正常的寫法,選擇一種計算后進入判斷環節,之后再輸入數字,這樣寫每一種運算下都會有代碼重復,有沒有辦法簡化代碼呢?
回調函數
??????? 即一個通過函數指針調用的函數。
??????? 通過回調函數,可以消除特定場景中因為多分支造成的重復代碼,例如:一個實現加減乘除的程序中,每個分支下都有一種運算,每個運算可寫成一個函數,我們可以再寫一個函數將每種分支下的重復代碼包含進去,通過傳入函數指針來調用運算函數,從而完成運算。
//回調函數
int jia(int x, int y) {return x + y;
}
int jian(int x, int y) {return x - y;
}
int cheng(int x, int y) {return x * y;
}
int chu(int x, int y) {return x / y;
}
void menu() {printf("**********************\n");printf("***1.加法 2.減法****\n");printf("***3.乘法 4.除法****\n");printf("*** 0.exit ****\n");printf("**********************\n");
}
int hui(int(*p)(int, int)) {int x, y;printf("請輸入操作數\n");scanf("%d%d", &x, &y);return p(x, y);
}
int main() {int i, x, y,ret;do {menu();printf("請選擇—>");scanf("%d", &i);switch (i) {case 1:ret = hui(jia);printf("%d\n", ret);break;case 2:ret = hui(jian);printf("%d\n", ret);break;case 3:ret = hui(cheng);printf("%d\n", ret);break;case 4:ret = hui(chu);printf("%d\n", ret);break;case 0:printf("退出計算\n");break;default:printf("輸入錯誤,重新輸入\n");break;}} while (i);return 0;
}
qsort使用舉例
??????? qsort函數是C語言的庫函數,包含在<stdlib.h>頭文件中,它可用于對所有數據類型進行排序,包括結構體,使用這個庫函數,必須再寫個比較元素的函數,返回int型(大于0:大于、等于0:等于、小于0:小于),默認升序,如要進行逆序輸出,則在比較函數中,交換操作數的位置。
排序整型數組
//qsort函數,排序整型數組
#include<stdio.h>
#include<stdlib.h>
int intcmp (const void* p1, const void* p2) {//比較函數,兩個元素的比較return (*(int*)p1) - (*(int*)p2);
}
int main() {int arr[6] = { 3,6,2,0,3,8 };int sz = sizeof(arr) / sizeof(arr[1]);qsort(arr,//數據類型void*base,用于接受待排序的數組的數組名,也就是首元素的地址sz,//數據類型sizeof_t,待排序數組的元素個數sizeof(arr[0]),//數據類型sizeof_t,待排序數組元素字節大小intcmp);
//數據類型 int(*) (const void*,const void*),用于接收倆個元素比較的函數,
//返回值:大于0(表示大于),等于0(等于),小于0(小于)for (int i = 0; i < sz; i++) {printf("%d ", arr[i]);}return 0;
}
運行結果:
排序結構體
按字符排
//qsort函數,結構體
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu {char name[100];int age;int height;
};
int namecmp(const void* p1, const void* p2) {//按名稱排return strcmp((*(struct stu*)p1).name, (*(struct stu*)p2).name);
}
int main() {struct stu arr[] = { {"zk",18,163},{"tian",19,180},{"xing",17,170} };int sz = sizeof(arr) / sizeof(arr[1]);qsort(arr,sz,sizeof(arr[0]),namecmp);for (int i = 0; i < sz; i++) {printf("%s %d %d\n", arr[i].name, arr[i].age, arr[i].height);}return 0;
}
運行結果
?按照整形排
//qsort函數,結構體
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu {char name[100];int age;int height;
};
//int namecmp(const void* p1, const void* p2) {//按名稱排
// return strcmp((*(struct stu*)p1).name, (*(struct stu*)p2).name);
//}
int agecmp(const void* p1, const void* p2) {//按照年齡排return (*(struct stu*)p1).age - (*(struct stu*)p2).age;
}
int main() {struct stu arr[] = { {"zk",18,163},{"tian",19,180},{"xing",17,170} };int sz = sizeof(arr) / sizeof(arr[1]);qsort(arr,sz,sizeof(arr[0]),agecmp);for (int i = 0; i < sz; i++) {printf("%s %d %d\n", arr[i].name, arr[i].age, arr[i].height);}return 0;
}
?運行結果