內容:
回憶1,2,3
四,數組傳參和指針傳參
一維數組的傳參
[]裏面的內容能夠省略
arr是首元素地址
傳遞的是地址可使用指針變量接收
也可使用相同類型的數組進行接收,可是不要求數組長度
二維數組的傳參
能夠省略行可是不能省略列
二維數組傳參時
當作一維數組的組合
首元素看作一維數組首元素的地址
利用數組指針進行接收
int (*)[5]是指針類型
arr是指針變量名
指向的是數組長度爲5類型爲int的數組
指針傳參
形式參數是一級指針
實際參數能夠是變量的地址
也能夠是一級指針變量
形式參數是二級指針
實際參數能夠是一級指針變量的地址
也能夠是二級指針變量
還能夠是指針數組
五,函數指針
&數組名取出的是數組的地址
數組名取出的是函數首元素的地址
類比:
&函數名取出的是函數的地址
函數名取出的是函數的地址,兩者如出一轍
函數指針的寫法
函數的返回類型 (void)(指針變量p )(形參類型char*)
函數指針的指針類型爲
void (*)(char*)
兩段有趣的代碼(推薦一本書《C陷阱與缺陷》)
代碼分析:
括號裏面放一個類型,說明進行強制類型轉換
(0強制類型轉換爲函數指針類型)就是函數的地址
這個函數爲無參,無返回類型的函數
(*)解引用,找到這個函數
()而後調用這個函數
代碼分析:
函數的返回類型是去掉函數名(形式參數)剩下 的就是函數的返回類型
signal函數的返回類型爲void(*)(int)
他的返回類型也是個函數指針
代碼二太複雜進行簡化
重命名產生函數指針類型
注意:
函數指針的重命名與普通類型的重命名不同
將void(*)(int)函數的返回類型重命名爲pfun_t
因此函數的聲明變爲(函數返回類型)pfun_t (函數名)signal (函數形參)(int , *pfun_t )
函數指針的使用:
解引用*函數指針變量名,而後傳參
也能夠屢次解引用
或者不解引用
均可以
pa是函數指針變量名
存放的是函數的地址
通常函數的調用Add(2,3);
因此(pa)(2,3);也能夠
pa是函數指針變量名
存放的是函數的地址
*pa解引用pa就是根據pa所存儲的函數的地址調用這個函數
因此(*pa)(2,3);也能夠
注意:
*的優先級低於()的優先級
因此若是沒打括號pa先與函數調用的括號結合在與*結合
就使用錯誤了
若是要使用*pa必須將其用括號括起來(*pa)
六,函數指針數組
函數指針數組的定義
多個函數的返回類型與參數都同樣
相似指針數組,建立函數指針數組
parr先與[4]結合說明parr[4]是一個數組,每一個元素的類型是int(*)(int,int)
函數指針數組的使用:(*可加可不加)
練習:
1.char* my_strcpy(char* dest,const char* src);
char*(*pf)(char* ,const char* )=my_strcpy;
2.char*(*pfArr[4])(char* ,const char* )={my_strcpy1,my_strcpy2,my_strcpy3,my_strcpy4};
函數指針數組的案例:(計算器)
算法的通常實現:算法
#include<stdio.h> void mnue() { printf("------------------------------------------\n"); printf("------1.Add 2.Sub-----------------\n"); printf("------3.Mul 4.Div-----------------\n"); printf("------ 0.exit -----------------\n"); printf("------------------------------------------\n"); } int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { int input = 0; int x = 0; int y = 0; do { mnue(); printf("請選擇:"); scanf("%d", &input); switch (input) { case 1: printf("請輸入兩個操做數:"); scanf("%d%d", &x, &y); printf("%d + %d = %d\n", x, y, Add(x, y)); break; case 2: printf("請輸入兩個操做數:"); scanf("%d%d", &x, &y); printf("%d - %d = %d\n", x, y, Sub(x, y)); Sub(x, y); break; case 3: printf("請輸入兩個操做數:"); scanf("%d%d", &x, &y); printf("%d * %d = %d\n", x, y ,Mul(x, y)); break; case 4: printf("請輸入兩個操做數:"); scanf("%d%d", &x, &y); printf("%d / %d = %d\n", x, y, Div(x, y)); break; case 0: printf("退出\n"); break; default: printf("輸入錯誤,請從新輸入!\n"); } } while (input); return 0; }
封裝函數,利用回調函數優化case裏面的冗餘項:
回調函數:數組
#include<stdio.h> void mnue() { printf("------------------------------------------\n"); printf("------1.Add 2.Sub-----------------\n"); printf("------3.Mul 4.Div-----------------\n"); printf("------ 0.exit -----------------\n"); printf("------------------------------------------\n"); } int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } void Cacl(int (*pf)(int, int)) { int x = 0; int y = 0; printf("請輸入兩個操做數:"); scanf("%d%d", &x, &y); printf("%d\n", pf(x, y)); } int main() { int input = 0; do { mnue(); printf("請選擇:"); scanf("%d", &input); switch (input) { case 1: Cacl(Add); break; case 2: Cacl(Sub); break; case 3: Cacl(Mul); break; case 4: Cacl(Div); break; case 0: printf("退出\n"); break; default: printf("輸入錯誤,請從新輸入!\n"); } } while (input); return 0; }
利用函數指針數組實現:
當功能多了的時候,case語句不會那麼長了ide
#include<stdio.h> void mnue() { printf("------------------------------------------\n"); printf("------1.Add 2.Sub-----------------\n"); printf("------3.Mul 4.Div-----------------\n"); printf("------ 0.exit -----------------\n"); printf("------------------------------------------\n"); } int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { int input = 0; int x = 0; int y = 0; do { mnue(); printf("請選擇:"); scanf("%d", &input); int (*pArr[5])(int, int) = { 0,Add,Sub,Mul,Div }; //故意設5個,使得選擇的函數能夠對應下標 if (input >= 1 && input <= 4) { printf("請輸入兩個操做數:"); scanf("%d%d", &x, &y); printf("%d\n", pArr[input](x, y)); } else if (input == 0) { printf("退出\n"); } else { printf("輸入錯誤,請從新輸入!\n"); } } while (input); return 0; }