函式指標有意思的地方在於,它使用從0到n-1這個n個連續的整數下標直接對映到函式上。
和前面一樣,我們也是模擬著定義普通指標陣列來定義函式指標陣列。首先,考慮乙個浮點數指標陣列,陣列的長度為10.我們都知道用下面的形式來定義:
float * pfloatarray[10];
從形式上分析,用中括號明確了是定義指標變數還是定義指標陣列這個語義。用數字10明確了這個陣列能容納多少個函式指標這個語義。形式上看,中括號是緊接在指標名稱的後面再中括號裡面是乙個需要在編譯時期間就能夠確定的常數。
現在我們來模擬函式指標陣列的定義,定義乙個指向函式指標型別為:float (*)(float,float)的函式指標陣列,陣列長度為10.正確的形式為:
float(* pfunctionarray[10])(float,float)
從形式上看,這種定義方式和定義普通指標的定義方式是一致的:都是在指標名稱後面緊接著乙個中括號,然後裡面是乙個編譯期間能夠確定的常數。這種形式上的一致性,可以方便我們對形式的記憶,進而達到對內容的理解。
下面是乙個例子程式:
/**author:choas lee
*date:2012-02-28
*/#include
float
add(
float
a,float
b) float
minus(
float
a,float
b) float
multiply(
float
a,float
b) float
divide(
float
a,float
b) int
main()
; int
i=0;
float
a=10.0,b=5.0;
for(i=0;i<4;i++)
return
0; }
以下為對應的執行結果:
resultis15.000000
result is
5.000000
result is
50.000000
result is
2.000000
從哲學角度講,形式過於複雜的話,還是抽象的層次太低。如果我們使用多層次的抽象,這樣最上層的表示就會簡化很多。這就是引入typedef的原因,使用typedef可以簡化函式指標的定義,因為typedef可以定義新的型別:
同樣,在使用typedef定義函式指標型別的時候,也和普通的使用typedef引入新型別的方式不一樣。我們和前面一樣對照著普通的定義方式來學習:
typedef int bool;
這在c語言中很常用,由於c語言中沒有bool型別,這樣定義之後可以從形式上引入乙個bool型別,提高**可讀性。所以形式為:
typedef 已知型別
新型別;
現在我們要將float (*)(float,float)型別宣告為一種新型別,按照上面的方式,貌似為:typedef float(*)(float,float) fptype;然而,前面的經驗告訴我們應該這樣定義啊:
typedef float(*fptype)(float,float);
這樣我們就可以用fptype來表示float (*)(float,float)這種型別了。所以定義乙個新的指向float (*)(float,float)型別的指標變數的時候,我們就可以採用下面這種形式了:
fptype pfunction;
在定義函式指標陣列的時候可以這樣定義:
fptype pfunctions[10];
在定義函式指標型別引數時可以這樣定義:
void func(fptype pfunction);
在定義函式指標型別的返回值時可以這樣定義:
fptype func(int a);
現在我們再來看一下,unix中的那個signal函式,其形式為:
void (*signal)(int signo,void (*func)(int)))(int);
現在我們定義乙個型別為:
typedef void (*psgntype)(int);
這樣上面的函式就能表達為:
psgntype signal(int signo,psgntype func);
這樣是不是看起來清爽多了。
其實上面的signal函式也能這樣定義:
首先引入新型別:
typedef void sgntype(int)
然後signal函式的宣告改為:
sgntype *signal(int signo,sgntype *func);
按照前面對這些形式的解釋,理解這個應該沒難度~~
現在在引入最後乙個例子,關於使用typedef來簡化函式指標定義的:
/**author:choas lee
*date:2012-02-29 00:25
*/#include
#include
#include
float
add(
float
a,float
b) float
minus(
float
a,float
b) float
multiply(
float
a,float
b) float
divide(
float
a,float
b) typedef
float
(*parithmeticoperations)(
float
,float
); typedef
float
arithmeticoperations(
float
,float
); int
main()
; arithmeticoperations *ao=add;
arithmeticoperations *aos[4]=;
float
a=10.0,b=5.0;
float
result=0.0;
inti=0;
result=pao(a,b);
printf("the result of pao is %f\n"
,result);
printf("the results of paos are:\n"
); for
(i=0;i<4;i++)
result=ao(a,b);
printf("\n\nthe result of ao is :%f\n"
,result);
printf("the results of aos are:\n"
); for
(i=0;i<4;i++)
return
0; }
輸出結果為:
result=15.000000result=5.000000
result=50.000000
result=2.000000
the result of
ao is
:15.000000
the results of
aos are:
result=15.000000
result=5.000000
result=50.000000
result=2.000000
時間不早了,該回去睡覺了~
引用:function pointer tutorial.
嗯,讓我們徹底搞懂C C 函式指標吧(二)
如果你已經明白了函式的引數機制,而且完全理解並實踐了3.3節的內容,這一節其實是很簡單的。只需要在函式的引數列表中,宣告乙個函式指標型別的引數即可,然後再呼叫的時候傳給它乙個實參就可以了。你可以這麼想象,就是把函式指標的賦值語句的等號換成了形參和實參結合的模式就行。下面給乙個簡單的例子 author...
讓我們徹底搞懂C C 函式指標吧(二)
如果你已經明白了函式的引數機制,而且完全理解並實踐了3.3節的內容,這一節其實是很簡單的。只需要在函式的引數列表中,宣告乙個函式指標型別的引數即可,然後再呼叫的時候傳給它乙個實參就可以了。你可以這麼想象,就是把函式指標的賦值語句的等號換成了形參和實參結合的模式就行。下面給乙個簡單的例子 author...
讓我們的領域邏輯徹底裸奔吧
菜阿斌以前寫了兩篇很好的文章 為什麼要讓我們的 領域模型 裸奔?上 下 在我的 架構視角面面觀中也介紹了領域邏輯經常被web 元件api 分布元件api orm元件api ado api 等汙染,上面的幾篇文章講了領域裸奔的重要性 以及常見專案中的領域被汙染的問題,關於如何解決該問題,網上關於這方面...