溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

c++函數(shù)名指針和函數(shù)指針怎么定義

發(fā)布時(shí)間:2022-02-11 13:47:59 來源:億速云 閱讀:121 作者:iii 欄目:開發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“c++函數(shù)名指針和函數(shù)指針怎么定義”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“c++函數(shù)名指針和函數(shù)指針怎么定義”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識(shí)吧。

前言

我們先來看一下函數(shù)指針式如何定義的,假如我們有一個(gè)函數(shù)int fun(int){…};那么他對(duì)應(yīng)的函數(shù)指針寫法就應(yīng)該是int (*p)(int);然后再對(duì)他進(jìn)行賦值,即p=fun;之后你就可以在接下來的地方按p作為函數(shù)名來調(diào)用它用起來完全和fun一樣。(注意這里的p指針并不是只能接受fun這個(gè)函數(shù)名,任何返回值是int,參數(shù)只有一個(gè)int的函數(shù)都可以把函數(shù)名賦給p)

首先說一下C/C++在創(chuàng)建一個(gè)變量的時(shí)候比如int a;相應(yīng)的在內(nèi)存就會(huì)分配一個(gè)4個(gè)字節(jié)(根據(jù)不同機(jī)器可能不同)空間來存放這個(gè)int變量,而假設(shè)這4個(gè)字節(jié)的起始地址是0XFF0A,那么實(shí)際上就存在一種變量名和內(nèi)存地址的映射,即a可以看做是一個(gè)標(biāo)示符,他只是代表著0XFF0A這個(gè)地址,在程序中你對(duì)a進(jìn)行的操作實(shí)際上也就是對(duì)內(nèi)存中以0XFF0A為首地址的4個(gè)字節(jié)的操作,特別是如果對(duì)a進(jìn)行取地址操作也就是&a實(shí)際上就是返回0XFF0A這個(gè)地址值,實(shí)際上你可以看成就是返回一個(gè)指向這個(gè)地址的指針(如果你覺的不能理解,就當(dāng)我沒說吧).同理對(duì)于我們?cè)诔绦蛑袆?chuàng)建的函數(shù),他是保存在程序中的單獨(dú)區(qū)域的,而我們調(diào)用它們就像使用變量一樣需要一個(gè)地址來唯一的指向它,所以每個(gè)函數(shù)都需要一個(gè)地址來唯一標(biāo)識(shí)自己(也就是我們常說的入口地址),就像上面的a對(duì)應(yīng)0XFF0A,那么假設(shè)我們定義了一個(gè)int fun(int){};函數(shù)的入口地址是0XAAEE,則fun也就是函數(shù)名他會(huì)映射0XAAEE,和上面的int變量a一樣如果對(duì)它進(jìn)行取地址&fun的話就會(huì)返回0XAAEE,實(shí)際上fun也是一種類型,就當(dāng)它是函數(shù)名類型好了,只要記住函數(shù)名本身并不是一個(gè)指針類型就可以了。

在調(diào)用函數(shù)的時(shí)候有函數(shù)名就夠了,比如fun(2);不要以為只要有函數(shù)名就能調(diào)用函數(shù)了,其實(shí)這只是寫法上的一個(gè)迷惑點(diǎn),而編譯器在編譯的時(shí)候一律都會(huì)進(jìn)行所謂的"Function-to-pointer conversion",也就是把函數(shù)名隱式轉(zhuǎn)換成函數(shù)指針類型,也就是要通過函數(shù)指針來調(diào)用函數(shù),所以如果你在調(diào)用函數(shù)的時(shí)候?qū)懗?&fun)(2)也是一樣能工作的,因?yàn)?amp;fun實(shí)際上就是返回一個(gè)函數(shù)指針,參照上一段中&a的例子,只是這種寫法很不常見,即使你不顯式的寫出&的話編譯器也會(huì)隱式的進(jìn)行轉(zhuǎn)換,注意&fun左右的括號(hào)必須有,這是因?yàn)檫\(yùn)算符優(yōu)先級(jí)的問題。

其實(shí)即使寫成(fun)(2)也是可以正常運(yùn)行的,這是因?yàn)楫?dāng)編譯器看到fun的時(shí)候發(fā)現(xiàn)它前面沒有&也就是沒有給他顯示的轉(zhuǎn)換成指針那么他就要隱式的轉(zhuǎn)換成指針,當(dāng)轉(zhuǎn)換完之后發(fā)現(xiàn)前面又有一個(gè)這時(shí)候也就是要進(jìn)行所謂的"解引用"操作,也就是到*后面里指針里取出來值,而那么值實(shí)際上也就也就是0XAAEE也就是函數(shù)名fun,這么一次隱式換然后再來一次解引用實(shí)際上相當(dāng)于什么也沒做,所以系統(tǒng)還會(huì)再進(jìn)行一次隱式的"Function-to-pointer conversion",即使你寫成(*******fun)(2)也會(huì)正常運(yùn)行,和剛才的一個(gè)道理,只是多做了幾次反復(fù)的轉(zhuǎn)解操作而已,都是編譯器自己完成的,不必去理會(huì)!

例 1

#include<iostream>
using namespace std;
void fun(int a)
{

}

int main()
{
    cout<<fun<<endl;
    cout<<*fun<<endl;
    cout<<&fun<<endl;
    cout<<*****fun<<endl;
}

結(jié)果輸出的值都是一樣的,也就是都是指向同一個(gè)函數(shù)地址的指針值。

例 2

下面再結(jié)合自己定義的函數(shù)指針來看看:

#include<iostream>
using namespace std;
int fun(int a)
{
    cout<<"fun"<<endl;
    return 0;
}

void main()
{
    int(*p)(int)=fun;
    int(*p1)(int)=*fun;
    int(*p2)(int)=&fun;
    p(1);
    p1(1);
    p2(1);
}

例 3

發(fā)現(xiàn)函數(shù)都能正常的運(yùn)行,其實(shí)p1,p2,p和fun賦值之后大家一樣理解就行了。

代碼:

#include<iostream>
using namespace std;
int fun(int a)
{
    cout<<"fun"<<endl;
    return 0;
}
 
void main()
{
    int(*p)(int)=fun;
    p(1);
//  (&p)(1);   
    (*p)(1);
    (****p)(1);
}

上面的程序也都會(huì)正常的運(yùn)行,只要再理解的時(shí)候把p當(dāng)成只是對(duì)函數(shù)名多做了一次轉(zhuǎn)換就可以了,接下來理解都一樣!注意上面注釋掉的哪一行是不能運(yùn)行的,因?yàn)閜是我們自己定義的函數(shù)指針類型,如果你對(duì)指針取地址那么將得到p這個(gè)變量本身的地址,這就不能正確調(diào)用函數(shù)了!再多說一句,其實(shí)你如果運(yùn)行&&fun這個(gè)式子也是非法的,至于為什么,大家一起幫我思考思考,我個(gè)人認(rèn)為當(dāng)我們運(yùn)行&fun的時(shí)候他會(huì)轉(zhuǎn)換成函數(shù)指針而實(shí)際上這個(gè)指針只是一個(gè)臨時(shí)值而臨時(shí)值是沒有實(shí)際存放的內(nèi)存地址的所以也就無法繼續(xù)取地址了!

讀到這里,這篇“c++函數(shù)名指針和函數(shù)指針怎么定義”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI