古詩詞大全網 - 成語解釋 - C語言 指針函數 函數指針 什麽區別聯系?最好有例子?壹定采納

C語言 指針函數 函數指針 什麽區別聯系?最好有例子?壹定采納

沒覺得指針函數這個概念有什麽大的意義。。。。可能其最大的意義就是拿過來和函數指針壹起混淆初學者的視聽吧。

指針函數指的是返回壹個指針的函數,比如我們常見的gets(),strcpy(),strcat(),malloc()等等。如果單獨把它當成壹個新概念真的沒有什麽意義。這些函數除了返回壹個指針之外沒有任何***性,但是返回的指針又天差地遠。

下面說說函數指針。

指針分為三種類型:對象指針,函數指針和void指針。

函數指針的聲明形式是T (*p)(...),其中*p使用括號括起來的原因是函數類型解析的優先級高於指針的解析,故使用括號防止解析成上面的指針函數(其實這兩個之間就相差了壹對括號)。

函數指針可以綁定到與其返回值和參數類型都相同的函數上。比如:

int?foo(int,?double);?//?函數聲明

int?(*bar)(int,?double)?=?foo;?//?函數指針

在上面的初始化中,寫成&foo也是可以的。

函數指針的最大特點就在於,其不能做壹元+-運算(當然也不能做+= -= ++ --等),且對其做壹元*運算的結果還是其本身。例如:(接著上面的例子)

bar(1,1.0);

(*bar)(1,1.0);?//?兩種情況等價

甚至妳還可以這樣:

(**************bar)(1,1.0);

依然是對的。

所以實際應用中壹般采取類似函數調用的方式,這樣更加自然。

剛剛去測試了壹下,還有壹個更加隱蔽的問題:

C中的函數可以采用使用原型或者不使用兩種方式。(不使用原型被視為過時)

原型即在函數頭中將參數類型及個數都聲明,而不使用就是很簡單的壹對括號。例如:

int?foo();?//?非原型

int?bar(void);?//?原型

int?foo1(int);?//?原型

這有什麽影響呢?看壹看下面的壹段代碼:

int?foo(int?i){return?i;}?//?原型

int?foo1(double?c){return?(int)c;}?//?原型

int?bar(){return?1;}?//?非原型

int?main(void)

{

int?(*foobar)(int);?//?原型

int?(*barfoo)();?//?非原型

foobar?=?foo;

foobar?=?&foo;

foobar?=?bar;

foobar?=?foo1;?//?this

barfoo?=?foo;

barfoo?=?bar;

barfoo?=?foo1;

foobar(1);

(*foobar)(1);

(*************foobar)(1);

return?0;

}

我的編譯器對this指的壹行進行了警告,提醒指針類型不匹配。

我們可以看到,非原型的函數指針可綁定到任意的函數上,而帶有原型的函數指針在綁定時可以起到更嚴格的類型限制。

容易忽略的壹點是,不接受任何參數的函數(帶原型)的聲明方式是int foo(void);,不應該省略void,特別是在使用對應類型的函數指針時,如果省略void,那麽錯誤的綁定也不會被警告。

我還註意到了壹個現象:

int?foo(char);

int?(*bar)()?=?foo;

這段代碼同樣也給了警告。為什麽呢?

因為在不使用原型的情況下,char,short,float等會被隱式提升到與其對應的更高級類型。

而在這個綁定中,bar是非原型,這時可能會進行整型提升,而foo帶有原型,調用時不需要進行提升。這樣就有可能引發錯誤。

以上就是函數指針使用過程中需要註意的壹點。不過提醒LZ,函數指針使用過程中最好還是使用帶有原型的函數指針。