Hello,寶子們!今天我們來模擬實現一下我們生活中的應用最頻繁的工具:計算器,實現計算器有三種方式。
廢話不多說,直接上代碼,計算器的一般實現:
#include <stdio.h>
int add(int a, int b)//加法函數
{return a + b;
}
int sub(int a, int b)//減法函數
{return a - b;
}
int mul(int a, int b)//乘法函數
{return a * b;
}
int div(int a, int b)//除法函數
{return a / b;
}
int main()
{int x, y;int input = 1;int ret = 0;do{//首先一上來就打印菜單,下面進行選擇,所以要用到do while 循環結構printf("*************************\n");printf(" 1:Add 2:Sub \n");printf(" 3:Mul 4:Div \n");printf(" 0:Exit \n");printf("*************************\n");printf("請選擇:");scanf("%d", &input);switch (input){case 1:printf("輸?操作數:");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret = %d\n", ret);break;case 2:printf("輸?操作數:");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret = %d\n", ret);break;case 3:printf("輸?操作數:");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret = %d\n", ret);break;case 4:printf("輸?操作數:");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret = %d\n", ret);break;case 0:printf("退出程序\n");break;default:printf("選擇錯誤\n");break;}} while (input);return 0;
}
像這樣的代碼看完之后有什么問題?雖然也不影響最后計算的結果,但是這樣的代碼是不是太冗余了,case
里面重復的代碼太多了,這還只有加減乘除四個選項,要是再多擴張幾個選項呢,比如:&&
,||
,>>
,<<
等運算呢?所以這樣的代碼效率太低下,不推薦使用。
那有沒有比較高效,不這么冗余的方法呢?當然了,這里就要用到我們前面所講的函數指針數組了,如果還不知道函數指針數組是什么的話,可以看看我前面講的這篇文章https://blog.csdn.net/weixin_66058866/article/details/136136008
相信聰明的你看完這篇文章,心里應該已經有答案了吧😎
函數指針數組代碼實現如下:
#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a*b;
}
int div(int a, int b)
{return a / b;
}
int main()
{int x, y;int input = 1;int ret = 0;int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //為了跟菜單里的選項對應起來,需要在數組元素中的最前面加了一個元素,//這樣就不至于出現當我們輸入下標為1的元素時,訪問的是sub這類問題了。do{printf("*************************\n");printf(" 1:Add 2:Sub \n");printf(" 3:Mul 4:Div \n");printf(" 0:Exit \n");printf("*************************\n");printf( "請選擇:" );scanf("%d", &input);if ((input <= 4 && input >= 1))//判斷輸入的值是否在選項當中{printf( "輸?操作數:" );scanf( "%d %d", &x, &y);ret = (*p[input])(x, y);printf( "ret = %d\n", ret);}else if(input == 0){printf("退出計算器\n");}else{printf( "輸?有誤\n" );}}while (input);return 0;
}
上面我們創建了函數指針數組,并且把加減乘除函數的地址都存放進去,然后想實現什么運算,直接通過下標的方式去調用對應的函數,這種方式就很好的解決了代碼冗余的問題,而且如果你還想再擴張選項的時候,也不需要再像第一種方法那樣麻煩了。
根據input
下標,找到對應的函數,然后再調用對應的函數,這種方法有沒有發現它像一個跳板一樣,在做一個轉移的動作,所以這種方法也被稱為轉移表。
那么是否還有其他的方式呢?這時候我們就涉及到一種高級的玩法了。
首先來看代碼:
#include <stdio.h>
int add(int a, int b)//加法函數
{return a + b;
}
int sub(int a, int b)//減法函數
{return a - b;
}
int mul(int a, int b)//乘法函數
{return a * b;
}
int div(int a, int b)//除法函數
{return a / b;
}
void calc(int(*fp)(int x,int y))//使用函數指針來接收函數的地址
{int x=0;int y=0;int ret=0;printf("輸?操作數:");scanf("%d %d", &x, &y);ret = fp(x, y);printf("ret = %d\n", ret);
}
int main()
{int x, y;int input = 1;int ret = 0;do{//首先一上來就打印菜單,下面進行選擇,所以要用到do while 循環結構printf("*************************\n");printf(" 1:Add 2:Sub \n");printf(" 3:Mul 4:Div \n");printf(" 0:Exit \n");printf("*************************\n");printf("請選擇:");scanf("%d", &input);switch (input){case 1:calc(Add);//把相對應的函數的地址傳過去break;case 2:calc(Sub);break;case 3:calc(Mul);break;case 4:calc(Div);break;case 0:printf("退出程序\n");break;default:printf("選擇錯誤\n");break;}} while (input);return 0;
}
像這種實現方式,你會發現并沒有在主函數里直接調用Add
,Sub
,Mul
,Div
等函數,而是把這些函數的地址傳給了clac函數,然后再calc函數內部通過指針變量來調用calc指向的函數,這也是一種回調函數的機制,當然這種機制現在理解不了也沒關系,在之后的深入理解指針(4)里面我會詳細講到喲!
創作不易,看完別忘了給博主一鍵三連喲!謝謝大家呀💖