c語言:轉移表的實現

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;
}

像這種實現方式,你會發現并沒有在主函數里直接調用AddSubMulDiv等函數,而是把這些函數的地址傳給了clac函數,然后再calc函數內部通過指針變量來調用calc指向的函數,這也是一種回調函數的機制,當然這種機制現在理解不了也沒關系,在之后的深入理解指針(4)里面我會詳細講到喲!


創作不易,看完別忘了給博主一鍵三連喲!謝謝大家呀💖

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/718463.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/718463.shtml
英文地址,請注明出處:http://en.pswp.cn/news/718463.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Foxmail快捷鍵設置問題

當快捷鍵設置錯誤時不會生效&#xff0c;原來的快捷鍵仍有效&#xff0c;即使禁用快捷鍵功能&#xff0c;原先快捷鍵仍有效。正確的快捷鍵&#xff1a; 1. 不能是空&#xff08;NULL&#xff09; 2. 應該設置按鍵值只有一個的鍵盤按鈕。

力扣字符串篇

以下解題思路來自代碼隨想錄以及官方題解。 文章目錄 344.反轉字符串541.反轉字符串||151.反轉字符串中的單詞28.找出字符串中第一個匹配項的下標459.重復的字符串 344.反轉字符串 編寫一個函數&#xff0c;其作用是將輸入的字符串反轉過來。輸入字符串以字符數組 s 的形式給…

怎樣查詢到pycharm終端中執行過的命令?

pycharm終端中記錄了曾經運行過的命令&#xff0c;怎樣才能查詢到全部曾經運行過的命令呢&#xff1f; 怎樣查詢到pycharm終端中執行過的命令&#xff1f;

【動態規劃專欄】

動態規劃基礎知識 概念 動態規劃&#xff08;Dynamic Programming&#xff0c;DP&#xff09;&#xff1a;用來解決最優化問題的算法思想。 動態規劃是分治思想的延伸&#xff0c;通俗一點來說就是大事化小&#xff0c;小事化無的藝術。 一般來說&#xff0c;…

【CSS】初學輕松學會使用Flex布局

目錄 什么是Flex布局如何開始使用Flex布局Flex容器的屬性Flex項目的屬性舉個例子 什么是Flex布局 Flex布局是一種基于盒子模型的布局方式&#xff0c;它讓我們可以輕松地控制容器內的元素在主軸和交叉軸上的排列方式。通過設置不同的Flex屬性&#xff0c;我們可以實現各種不同…

探索Hadoop的三種運行模式:單機模式、偽分布式模式和完全分布式模式

目錄 前言一、 單機模式二、 偽分布式模式三、 完全分布式模式&#xff08;重點&#xff09;3.1 準備工作3.2 配置集群3.2.1 配置core-site.xml 文件3.2.2 配置hdfs-site.xml 文件3.2.3 配置yarn-site.xml 文件3.2.4 配置mapred-site.xml 文件 3.3 啟動集群3.3.1 配置workers3.…

【百度】商業AIGC組_AIGC Java研發工程師(J70353)

北京市技術4人2024-02-28 工作職責&#xff1a; 負責商業AIGC平臺方向的工程架構設計及研發&#xff0c;致力于為廣告業務提供內容生成、內容知識化、內容多模態等中臺化服務&#xff0c;并將內容能力打通廣告檢索系統&#xff0c;于廣告的觸發、創意、模型和機制等聯動&#…

RK3568 android11 調試陀螺儀模塊 MPU6500

一&#xff0c;MPU6500功能介紹 1.簡介 MPU6500是一款由TDK生產的運動/慣性傳感器&#xff0c;屬于慣性測量設備&#xff08;IMU&#xff09;的一種。MPU6500集成了3軸加速度計、3軸陀螺儀和一個板載數字運動處理器&#xff08;DMP&#xff09;&#xff0c;能夠提供6軸的運動…

Matlab|基于Logistic函數負荷需求響應

目錄 1 基于Logistic函數的負荷轉移率模型 2 程序示例 3 效果圖 4 下載鏈接 負荷需求響應模型種類較多&#xff0c;有電價型和激勵型等類型&#xff0c;本次和大家分享一個基于Logistic函數的負荷轉移率模型&#xff0c;該模型屬于電價型&#xff0c;由于該方法使用的較少&a…

mysql 性能調優參數配置文件

########################################################################### ## my.cnf for MySQL 8.0.x # ## 本配置參考 https://imysql.com/my-cnf-wizard.html # ## 注意&#xff1a; …

python爬蟲之app爬取-charles的使用

專欄系列:http://t.csdnimg.cn/WfCSx 前言 前面介紹的都是爬取 Web 網頁的內容。隨著移動互聯網的發展,越來越多的企業并沒有提供 Web 網頁端的服務,而是直接開發了 App,更多更全的信息都是通過 App 來展示的。那么針對 App 我們可以爬取嗎?當然可以。 App 的爬取相比 …

FM AM WM DAB是啥

技術描述頻率范圍優點缺點調頻調制&#xff08;FM&#xff09;在FM廣播中&#xff0c;音頻信號的頻率被調制以匹配載波信號的變化&#xff0c;而載波信號的振幅保持不變。FM廣播通常具有較高的音質&#xff0c;并且在一定范圍內提供清晰的音頻。88 MHz 至 108 MHz- 高音質 - 清…

[linux] matplotlib plt畫training dynamics指標曲線時,標記每個點的值

plt畫折線圖時&#xff0c;plt.annotate標記折線圖的點的數值。 def plot_ret(*ret_dicts):plt.figure(figsize(10, 5))for ret_dict in ret_dicts:print(ret_dict["iters"])plt.plot([iter*4/1000 for iter in ret_dict["iters"]], ret_dict["ret&q…

億道信息發布兩款升級款全加固筆記本電腦

2022年5月19日&#xff0c;加固手持終端。加固平板電腦、加固筆記本電腦專業設計商和制造商&#xff0c;以及加固型移動計算機軟硬件整體定制解決方案提供商億道信息&#xff0c;宣布對其兩款廣受歡迎的加固筆記本電腦產品EM-X14U和EM-X15U進行重大升級。新發布的兩款升級款全加…

下載element-ui 資源,圖標 element-icons.woff,element-icons.ttf 無法解碼文件字體

css下載地址&#xff1a;https://unpkg.com/element-ui2.15.14/lib/theme-chalk/index.css js下載地址&#xff1a;https://unpkg.com/element-ui2.15.14/lib/index.js 圖標及文字文件下載地址&#xff1a; element-icons.woff:&#xff1a; ? https://unpkg.com/element-…

《TCP/IP詳解 卷一》第10章 UDP 和 IP 分片

目錄 10.1 引言 10.2 UDP 頭部 10.3 UDP校驗和 10.4 例子 10.5 UDP 和 IPv6 10.6 UDP-Lite 10.7 IP分片 10.7.1 例子&#xff1a;IPV4 UDP分片 10.7.2 重組超時 10.8 采用UDP的路徑MTU發現 10.9 IP分片和ARP/ND之間的交互 10.10 最大UDP數據報長度 10.11 UDP服務器…

【java、微服務、nacos】nacos學習筆記

Nacos服務分級存儲模型 ① 一級是服務&#xff0c;例如userservice ②二級是集群&#xff0c;例如杭州或上海 ③ 三級是實例&#xff0c;例如杭州機房的某臺部署了userservice的服務器 配置實例集群屬性 改變服務的yml文件 spring:cloud:nacos:discovery:cluster-name: H…

Docker將本地的鏡像上傳到私有倉庫

使用register鏡像創建私有倉庫 [rootopenEuler-node1 ~]# docker run --restartalways -d -p 5000:5000 -v /opt/data/regostry:/var/lib/registry registry:2[rootopenEuler-node1 ~]# docker images REPOSITORY TAG IMAGE…

Day 60 | 動態規劃 647. 回文子串 、 516.最長回文子序列 、動態規劃總結篇

647. 回文子串 題目 文章講解 視頻講解 class Solution {public int countSubstrings(String s) {char[] chars s.toCharArray();int len chars.length;boolean[][] dp new boolean[len][len];int result 0;for (int i len - 1; i > 0; i--) {for (int j i; j < l…

基于React低代碼平臺開發:構建高效、靈活的應用新范式

文章目錄 一、React與低代碼平臺的結合優勢二、基于React的低代碼平臺開發挑戰三、基于React的低代碼平臺開發實踐四、未來展望《低代碼平臺開發實踐&#xff1a;基于React》編輯推薦內容簡介作者簡介目錄前言為什么要寫這本書 讀者對象如何閱讀本書 隨著數字化轉型的深入&…