C語(yǔ)言超詳細(xì)講解函數(shù)指針的運(yùn)用
前言
前面我們學(xué)習(xí)了各種各樣的指針類型,有些指針可以說(shuō)是稀奇百怪,特別是函數(shù)指針,有些朋友可能覺(jué)得,函數(shù)指針有些多余,調(diào)用函數(shù)為什么要用指針調(diào)用,直接調(diào)用不好嗎?
接下來(lái)我們從具體的實(shí)例來(lái)回答同學(xué)們的問(wèn)題,加深對(duì)函數(shù)指針的理解。
計(jì)算器的例子
接下來(lái)我們寫(xiě)一個(gè)簡(jiǎn)單的計(jì)算器程序,完成不同的計(jì)算功能比如加減乘除:
#include <stdio.h>
//相加函數(shù)
int add(int a, int b)
{
return a + b;
}
//相減函數(shù)
int sub(int a, int b)
{
return a - b;
}
//相乘函數(shù)
int mul(int a, int b)
{
return a * b;
}
//相除函數(shù)
int div(int a, int b)
{
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
do
{
printf("*************************\n");
printf(" 1:add 2:sub \n");
printf(" 3:mul 4:div \n");
printf("*************************\n");
printf("請(qǐng)選擇:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("輸入操作數(shù):");
scanf("%d %d", &x, &y);
ret = add(x, y);
printf("ret = %d\n", ret);
break;
case 2:
printf("輸入操作數(shù):");
scanf("%d %d", &x, &y);
ret = sub(x, y);
printf("ret = %d\n", ret);
break;
case 3:
printf("輸入操作數(shù):");
scanf("%d %d", &x, &y);
ret = mul(x, y);
printf("ret = %d\n", ret);
break;
case 4:
printf("輸入操作數(shù):");
scanf("%d %d", &x, &y);
ret = div(x, y);
printf("ret = %d\n", ret);
break;
case 0:
printf("退出程序\n");
break;
default:
printf("選擇錯(cuò)誤\n");
break;
}
} while (input);
return 0;
}我們很明顯地感覺(jué)到,是不是代碼實(shí)在是有些繁瑣,不同的功能之間有著高度的相似性,比如說(shuō)進(jìn)去之后都需要對(duì)x和y賦值,最后又都需要打印一個(gè)返回值,但在當(dāng)前的框架下似乎又很難進(jìn)行簡(jiǎn)化。
這時(shí),我們就進(jìn)入了今天的主題,如何使用函數(shù)指針來(lái)給程序瘦瘦身。
回調(diào)函數(shù)
我們先來(lái)看看使用回調(diào)函數(shù)修改之后的程序。
首先我們?cè)谠瓉?lái)的基礎(chǔ)上構(gòu)造了一個(gè)新的函數(shù),函數(shù)的形參就是一個(gè)函數(shù)指針的形式:
//使用回調(diào)函數(shù)
void cumulate_numbers(int (*cumulate)(int, int))
{
int x, y;
int ret = 0;
printf("輸入操作數(shù):");
scanf("%d %d", &x, &y);
ret = cumulate(x, y);
printf("ret = %d\n", ret);
}然后我們來(lái)看看調(diào)用函數(shù)方面有什么改變:
scanf("%d", &input);
switch (input)
{
case 1:
cumulate_numbers(add);
break;
case 2:
cumulate_numbers(sub);
break;
case 3:
cumulate_numbers(mul);
break;
case 4:
cumulate_numbers(div);
break;
case 0:
printf("退出程序\n");
break;
default:
printf("選擇錯(cuò)誤\n");
break;
}
} while (input);我們可以清楚地認(rèn)識(shí)到每次實(shí)現(xiàn)功能,通過(guò)函數(shù)指針使一開(kāi)始的
printf("輸入操作數(shù):");
scanf("%d %d", &x, &y);
ret = div(x, y);
printf("ret = %d\n", ret);轉(zhuǎn)變?yōu)橹灰{(diào)用一個(gè)函數(shù),一行代碼就搞定了。我們這些功能比較簡(jiǎn)單,功能的數(shù)量也不多,使四行代碼變成了一行,如果功能復(fù)雜一些,功能的數(shù)量再多一些,對(duì)于代碼的簡(jiǎn)化量還是非??捎^的。
那么接下來(lái)能否讓我們更進(jìn)一步呢?
轉(zhuǎn)移表
我們?cè)賮?lái)看看更加簡(jiǎn)潔的代碼:
int (*p[5])(int, int) = { 0, add, sub, mul, div };
do
{
printf("*************************\n");
printf(" 1:add 2:sub \n");
printf(" 3:mul 4:div \n");
printf("*************************\n");
printf("請(qǐng)選擇:");
scanf("%d", &input);
if ((input <= 4 && input >= 1))
{
printf("輸入操作數(shù):");
scanf("%d %d", &x, &y);
ret = (*p[input])(x, y);
printf("ret = %d\n", ret);
}
else if(input != 0)
printf("輸入有誤\n");
} while (input);運(yùn)用了指針數(shù)組,這個(gè)方法叫做轉(zhuǎn)移表。
到此這篇關(guān)于C語(yǔ)言超詳細(xì)講解函數(shù)指針的運(yùn)用的文章就介紹到這了,更多相關(guān)C語(yǔ)言函數(shù)指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一道超經(jīng)典的C++結(jié)構(gòu)體的題目
以下小編就為大家介紹一道超經(jīng)典的關(guān)于C++結(jié)構(gòu)體的題目。需要的朋友可以過(guò)來(lái)參考下2013-09-09
手動(dòng)添加bits/stdc++.h到vs2017的詳細(xì)步驟
這篇文章主要介紹了手動(dòng)添加bits/stdc++.h到vs2017的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二叉樹(shù)詳解
二叉樹(shù)(Binary tree)是樹(shù)形結(jié)構(gòu)的一個(gè)重要類型。許多實(shí)際問(wèn)題抽象出來(lái)的數(shù)據(jù)結(jié)構(gòu)往往是二叉樹(shù)形式。本文將通過(guò)示例詳細(xì)講解一下二叉樹(shù),需要的可以參考一下2022-03-03
C++控制權(quán)限關(guān)鍵字protected
這篇文章主要介紹了C++控制權(quán)限關(guān)鍵字protected,protected和private類似,而對(duì)于派生類來(lái)說(shuō),protected與public類似,下面來(lái)一起倆姐更多詳細(xì)內(nèi)容吧,需要的小伙伴可以參考一下2022-01-01
C語(yǔ)言遞歸函數(shù)與漢諾塔問(wèn)題簡(jiǎn)明理解
遞歸(recursive)函數(shù)是“自己調(diào)用自己”的函數(shù),無(wú)論是采用直接或間接調(diào)用方式。間接遞歸意味著函數(shù)調(diào)用另一個(gè)函數(shù)(然后可能又調(diào)用第三個(gè)函數(shù)等),最后又調(diào)用第一個(gè)函數(shù)。因?yàn)楹瘮?shù)不可以一直不停地調(diào)用自己,所以遞歸函數(shù)一定具備結(jié)束條件2022-07-07

