C語(yǔ)言超詳細(xì)講解指向函數(shù)的指針
一、函數(shù)的指針
首先,函數(shù)名代表函數(shù)的起始地址,調(diào)用函數(shù)時(shí),程序會(huì)從函數(shù)名獲取到函數(shù)起始地址,并從該地址起執(zhí)行函數(shù)中的代碼,函數(shù)名就是函數(shù)的指針,所以我們可以定義一個(gè)指向函數(shù)的指針變量,用來存放函數(shù)的起始地址,這樣一來,就可以通過該變量來調(diào)用其所指向的函數(shù)。
二、指向函數(shù)的指針變量
定義指向函數(shù)的指針變量
返回值類型(* 指針變量名)(形參類型列表);
例如:int(*p)(int, int);
,這行代碼定義了一個(gè)可以指向返回值為整型且有兩個(gè)整型形參函數(shù)的指針變量p,符合返回值為整型且有兩個(gè)整型形參的函數(shù)都可以將其地址(即其函數(shù)名)賦給p。
使用指向函數(shù)的指針變量
在使用指向函數(shù)的指針變量時(shí),只需要將函數(shù)名賦給指向函數(shù)的指針變量即可,因?yàn)楹瘮?shù)名就是該函數(shù)的入口地址。
由于指向函數(shù)的指針變量保存了函數(shù)的地址,則該指針變量就指向了對(duì)應(yīng)的函數(shù)。例如,求最大值的函數(shù)命名為max
,如果將其函數(shù)名賦給指向函數(shù)的指針變量p
(即p = max
)后,則p
就指向了max
函數(shù),并且可以通過(*p)(a, b);
的方式來調(diào)用max
函數(shù),因?yàn)橹羔樧兞?code>p保存了max
函數(shù)的地址,那么*p
就是max
。需要注意的是,其中*p
前的*
可以省略,故也可以寫成p(a, b);
三、調(diào)用函數(shù)的兩種方式
引例:自定義max
函數(shù),求整數(shù)a
和b
中的較大者并返回給主調(diào)函數(shù),不考慮兩數(shù)相等的情況通過函數(shù)名調(diào)用函數(shù)
#include <stdio.h> int max(int, int); // max函數(shù)的函數(shù)聲明 int main() { int a, b; printf("請(qǐng)輸入兩個(gè)整數(shù):"); scanf("%d%d", &a, &b); printf("兩數(shù)中的較大者的值為%d\n", max(a, b)); return 0; } int max(int a, int b) { if (a > b) return a; else return b; }
通過指向函數(shù)的指針變量調(diào)用函數(shù)
#include <stdio.h> int max(int, int); // max函數(shù)的函數(shù)聲明 int main() { int a, b; int(*p)(int, int); // 定義指向函數(shù)的指針p p = max; // p指向max函數(shù) printf("請(qǐng)輸入兩個(gè)整數(shù):"); scanf("%d%d", &a, &b); printf("兩數(shù)中的較大者的值為%d\n", (*p)(a, b)); // (*p)(a, b) 也可寫為 p(a, b) return 0; } int max(int a, int b) { if (a > b) return a; else return b; }
四、指向函數(shù)的指針的作用
看到這里有人可能會(huì)問,既然函數(shù)名就可以調(diào)用函數(shù),為什么還要弄個(gè)奇奇怪怪的指針?這難道不是多此一舉嘛?難倒是為了裝13?不管怎樣,使用指向函數(shù)的指針來調(diào)用函數(shù)肯定不是為了裝13,主要的原因是:用函數(shù)名調(diào)用函數(shù)時(shí)比較死板,只能調(diào)用所指定的一個(gè)函數(shù),而通過指針變量調(diào)用函數(shù)會(huì)比較靈活,可以根據(jù)不同的情況調(diào)用不同的函數(shù)。以下面的程序?yàn)槔?輸入兩個(gè)整數(shù),然后讓用戶選擇1或2,選1則調(diào)用max
函數(shù)求出兩個(gè)整數(shù)的較大者并將其輸出,選2則調(diào)用min
函數(shù)求出兩個(gè)整數(shù)的較小者并將其輸出,不考慮兩數(shù)相等的情況
#include <stdio.h> int max(int, int); // max函數(shù)的函數(shù)聲明 int min(int, int); // min函數(shù)的函數(shù)聲明 int main() { int a, b, c, n; int (*p)(int, int); // 定義指向函數(shù)的指針p p = NULL; // 先將p賦為空 printf("請(qǐng)輸入兩個(gè)整數(shù):"); scanf("%d%d", &a, &b); printf("輸入1獲取兩個(gè)數(shù)中的較大者,輸入2獲取兩個(gè)數(shù)中的較小者,請(qǐng)輸入:"); scanf("%d", &n); if (n == 1) p = max; // p指向max函數(shù) else if (n == 2) p = min; // p指向min函數(shù) c = p(a, b); // 調(diào)用p所指向的函數(shù) if (n == 1) printf("兩個(gè)數(shù)中的較大者為:%d\n", c); else printf("兩個(gè)數(shù)中的較小者為:%d\n", c); return 0; } int max(int a, int b) { if (a > b) return a; else return b; } int min(int a, int b) { if (a < b) return a; else return b; }
五、用指向函數(shù)的指針作函數(shù)參數(shù)(重點(diǎn))
指向函數(shù)的指針變量的一個(gè)重要用途是把函數(shù)的入口地址作為實(shí)參傳遞給其他函數(shù)。以下面的程序?yàn)槔?/p>
有兩個(gè)整數(shù)a
和b
,由用戶輸入1,2,3來決定進(jìn)行什么操作。輸入1則求出a
和b
中的較大者,輸入2則求出a
和b
中的較小者,輸入3則求出a
與b
之和,不考慮兩個(gè)數(shù)相等的情況
#include <stdio.h> int fun(int, int, int (*p)(int, int)); int max(int, int); int min(int, int); int sum(int, int); int main() { int a = 34, b = -21, n; printf("輸入1獲得兩數(shù)中的較大者,輸入2獲得兩數(shù)中的較小者,輸入3獲得兩個(gè)數(shù)的和,請(qǐng)輸入:"); scanf("%d", &n); if (n == 1) printf("兩數(shù)中的較大者為%d\n", fun(a, b, max)); // 向fun函數(shù)中傳參時(shí),只需要傳入兩個(gè)整數(shù)或整型變量以及想要在fun函數(shù)內(nèi)執(zhí)行的函數(shù)的函數(shù)名即可 // 函數(shù)名會(huì)傳遞給對(duì)應(yīng)的形參指針變量 else if (n == 2) printf("兩數(shù)中的較小者為%d\n", fun(a, b, min)); else if (n == 3) printf("兩個(gè)數(shù)的和為%d\n", fun(a, b, sum)); return 0; } // fun函數(shù)的作用是獲取最終結(jié)果 int fun(int x, int y, int (*p)(int, int)) { int result; result = p(x, y); // 用result接收最終結(jié)果,不管執(zhí)行max,min,sum中的哪個(gè)函數(shù),fun函數(shù)內(nèi)部代碼都不用改變 return result; } int max(int x, int y) { if (x > y) return x; else return y; } int min(int x, int y) { if (x < y) return x; else return y; } int sum(int x, int y) { return x + y; }
從上面的程序中可以清晰地看出,不管調(diào)用max
,min
,sum
中的哪個(gè)函數(shù),fun
函數(shù)均沒有任何變化,在fun
函數(shù)內(nèi)部的result
只用來獲取結(jié)果并將結(jié)果返回,但不去判斷到底要通過哪個(gè)函數(shù)來計(jì)算這一結(jié)果,主調(diào)函數(shù)向其傳入哪個(gè)函數(shù),其內(nèi)部就執(zhí)行哪個(gè)函數(shù)。max
,min
,sum
函數(shù)用來計(jì)算,fun
函數(shù)用來獲取結(jié)果,這體現(xiàn)出了整個(gè)程序的模塊化。
六、為什么要將指向函數(shù)的指針變量作為函數(shù)的形參(重點(diǎn))
舉一個(gè)例子,我們?cè)趯W(xué)習(xí)數(shù)組的過程中,想要把數(shù)組中的所有元素輸出,通常會(huì)接觸一個(gè)新詞,遍歷。其實(shí)遍歷的含義并不是將一個(gè)結(jié)構(gòu)中的元素輸出的過程,然而我在初學(xué)時(shí)便認(rèn)為遍歷等同于輸出,這是我在初學(xué)時(shí)對(duì)遍歷這個(gè)詞不準(zhǔn)確的理解,我相信也一定有人跟我一樣這樣認(rèn)為。其實(shí)遍歷指的是依次訪問某種結(jié)構(gòu)中的所有元素,至于對(duì)這些元素怎么操作,由程序員自己決定,比如,你想輸出所有的元素,那就可以調(diào)用輸出函數(shù)將每次獲取到的元素輸出;你想將所有元素的值翻倍,那就調(diào)用對(duì)應(yīng)的翻倍函數(shù)將每次獲取到的元素翻倍。但是這樣一來,遍歷函數(shù)的功能就變得十分單一,只能進(jìn)行一種操作,要么是遍歷并輸出,要么是遍歷并翻倍,如果在一個(gè)程序中,開始想要遍歷并翻倍,后又想要遍歷并輸出,就只能定義兩個(gè)函數(shù)來實(shí)現(xiàn),但是我們發(fā)現(xiàn)不管對(duì)元素怎么操作,訪問每個(gè)元素的代碼都是相同,并且只要想對(duì)結(jié)構(gòu)中的每個(gè)元素進(jìn)行操作,首先要做的就是訪問每個(gè)元素。但是如果為了輸出而定義一個(gè)先遍歷后輸出的函數(shù),為了將每個(gè)元素的值翻倍而定義一個(gè)先遍歷后翻倍的函數(shù),這樣遍歷元素的代碼就是重復(fù)的。那要怎么辦呢?既然遍歷的操作是重復(fù)的,那我們就定義一個(gè)專門的遍歷函數(shù),該函數(shù)只用來訪問元素,再定義其它多個(gè)操作數(shù)據(jù)的函數(shù),至于我們對(duì)遍歷后的數(shù)據(jù)執(zhí)行什么樣的操作,我們只需要將對(duì)應(yīng)的操作函數(shù)通過遍歷函數(shù)的形參接收過來,這樣就可以實(shí)現(xiàn)在遍歷函數(shù)中根據(jù)不同情況執(zhí)行不同操作的目的,如此一來既體現(xiàn)出了程序設(shè)計(jì)的結(jié)構(gòu)化與模塊化,又減少了編程時(shí)的代碼量。
到此這篇關(guān)于C語(yǔ)言超詳細(xì)講解指向函數(shù)的指針的文章就介紹到這了,更多相關(guān)C語(yǔ)言指向函數(shù)的指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++獲取當(dāng)前系統(tǒng)時(shí)間的方法總結(jié)
這篇文章主要介紹了C++獲取當(dāng)前系統(tǒng)時(shí)間的方法,實(shí)例總結(jié)了四個(gè)獲取系統(tǒng)時(shí)間的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04c++ priority_queue用法入門超詳細(xì)教程
priority_queue即優(yōu)先級(jí)隊(duì)列,它的使用場(chǎng)景很多,它底層是用大小根堆實(shí)現(xiàn)的,可以用log(n)的時(shí)間動(dòng)態(tài)地維護(hù)數(shù)據(jù)的有序性,這篇文章主要介紹了c++ priority_queue用法入門超詳細(xì)教程,需要的朋友可以參考下2023-12-12C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易版三子棋游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易版三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07C++之CNoTrackObject類和new delete操作符的重載實(shí)例
這篇文章主要介紹了C++之CNoTrackObject類和new delete操作符的重載實(shí)例,是C++程序設(shè)計(jì)中比較重要的概念,需要的朋友可以參考下2014-10-10linux c程序中獲取shell腳本輸出的實(shí)現(xiàn)方法
以下是對(duì)在linux下c程序中獲取shell腳本輸出的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下2013-08-08C/C++程序開發(fā)中實(shí)現(xiàn)信息隱藏的三種類型
這篇文章主要介紹了C/C++程序開發(fā)中實(shí)現(xiàn)信息隱藏的三種類型的相關(guān)資料,需要的朋友可以參考下2016-02-02