讀書筆記系列之:c語言函式指標
笛風
2013.10.8
一、函式指標的定義
顧名思義,函式指標就是函式的指標。它是乙個指標,指向乙個函式。看例子:
a)char * (*fun1)(char * p1,char * p2);
b)char * *fun2(char * p1,char * p2);
c)char * fun3(char * p1,char * p2);
看看上面三個表示式分別是什麼意思?
c):這很容易,fun3 是函式名,p1,p2 是引數,其型別為char *型,函式的返回值為char *型別。
b):也很簡單,與c)表示式相比,唯一不同的就是函式的返回值型別為char**,是個二級指標。
a):fun1 是函式名嗎?回憶一下前面講解陣列指標時的情形。我們說陣列指標這麼定義或許更清晰:
int (*)[10] p;
再看看a)表示式與這裡何其相似!明白了吧。這裡fun1 不是什麼函式名,而是乙個指標變數,它指向乙個函式。這個函式有兩個指標型別的引數,函式的返回值也是乙個指標。同樣,我們把這個表示式改寫一下:char * (*)(char * p1,char * p2) fun1; 這樣子是不是好看一些呢?只可惜編譯器不這麼想。^_^。
二、函式指標的使用
1、函式指標使用的例子
上面我們定義了乙個函式指標,但如何來使用它呢?先看如下例子:
#include
#include
char * fun(char * p1,char * p2)
else
}intmain()
intmain()
這是在幹什麼?*(int*)&p=(int)function;表示什麼意思?別急,先看這行**:
void (*p)();
這行**定義了乙個指標變數p,p 指向乙個函式,這個函式的引數和返回值都是void。
&p 是求指標變數p 本身的位址,這是乙個32 位的二進位制常數(32 位系統)。
(int*)&p 表示將位址強制轉換成指向int 型別資料的指標。
(int)function 表示將函式的入口位址強制轉換成int 型別的資料。
分析到這裡,相信你已經明白*(int*)&p=(int)function;表示將函式的入口位址賦值給指標變數p。那麼(*p) ();就是表示對函式的呼叫。
講解到這裡,相信你已經明白了。其實函式指標與普通指標沒什麼差別,只是指向的內容不同而已。
使用函式指標的好處在於,可以將實現同一功能的多個模組統一起來標識,這樣一來更容易後期的維護,系統結構更加清晰。或者歸納為:便於分層設計、利於系統抽象、降低耦合度以及使介面與實現分開。
3、(*(void(*) ())0)()------這是什麼?
是不是感覺上面的例子太簡單,不夠刺激?好,那就來點刺激的,看下面這個例子:
(*(void(*) ())0)();
這是《c traps and pitfalls》這本經典的書中的乙個例子。沒有發狂吧?下面我們就來分析分析:
第一步:void(*) (),可以明白這是乙個函式指標型別。這個函式沒有引數,沒有返回值。
第四步:(*(void(*) ())0)(),這是函式呼叫。
好像還是很簡單是吧,上面的例子再改寫改寫:
(*(char**(*) (char **,char **))0) ( char **,char **);
如果沒有上面的分析,肯怕不容易把這個表示式看明白吧。不過現在應該是很簡單的一件事了。讀者以為呢?
4、函式指標陣列
現在我們清楚表示式「char * (*pf)(char * p)」定義的是乙個函式指標pf。既然pf 是乙個指標,那就可以儲存在乙個陣列裡。把上式修改一下:
char * (*pf[3])(char * p);
這是定義乙個函式指標陣列。它是乙個陣列,陣列名為pf,陣列內儲存了3 個指向函式的指標。這些指標指向一些返回值型別為指向字元的指標、引數為乙個指向字元的指標的函式。這念起來似乎有點拗口。不過不要緊,關鍵是你明白這是乙個指標陣列,是陣列。
函式指標陣列怎麼使用呢?這裡也給出乙個非常簡單的例子,只要真正掌握了使用方法,再複雜的問題都可以應對。如下:
#include
#include
char * fun1(char * p)
char * fun2(char * p)
char * fun3(char * p)
intmain()
5、函式指標陣列的指標
看著這個標題沒發狂吧?函式指標就夠一般初學者折騰了,函式指標陣列就更加麻煩,現在的函式指標陣列指標就更難理解了。
其實,沒這麼複雜。前面詳細討論過陣列指標的問題,這裡的函式指標陣列指標不就是乙個指標嘛。只不過這個指標指向乙個陣列,這個陣列裡面存的都是指向函式的指標。僅此而已。
下面就定義乙個簡單的函式指標陣列指標:
char * (*(*pf)[3])(char * p);
注意,這裡的pf 和上一節的pf 就完全是兩碼事了。上一節的pf 並非指標,而是乙個陣列名;這裡的pf 確實是實實在在的指標。這個指標指向乙個包含了3 個元素的陣列;這個數字裡面存的是指向函式的指標;這些指標指向一些返回值型別為指向字元的指標、引數為乙個指向字元的指標的函式。這比上一節的函式指標陣列更拗口。其實你不用管這麼多,明白這是乙個指標就ok 了。其用法與前面講的陣列指標沒有差別。下面列乙個簡單的例子:
#include
#include
char * fun1(char * p)
char * fun2(char * p)
char * fun3(char * p)
intmain()
{char * (*a[3])(char * p);
char * (*(*pf)[3])(char * p);
pf = &a;
a[0] = fun1;
a[1] = &fun2;
a[2] = &fun3;
pf[0][0]("fun1");
pf[0][1]("fun2");
pf[0][2]("fun3");
return 0;
c語言結構體的使用 笛風讀書筆記系列
讀書筆記系列之 c語言結構體的使用 笛風 2013.10.11 什麼是結構體?簡單的來說,結構體就是乙個可以包含不同資料型別的乙個結構,它是一種可以自己定義的資料型別,它的特點和陣列主要有兩點不同,首先結構體可以在乙個結構中宣告不同的資料型別,第二相同結構的結構體變數是可以相互賦值的,而陣列是做不到...
linux定時器的使用 笛風讀書筆記系列
讀書筆記系列之 linux定時器的使用 笛風 2013.11.16 首先來看看linux作業系統為每乙個程序提供的3個內部計時器。itimer real 給乙個指定的時間間隔,按照實際的時間來減少這個計數,當時間間隔為0的時候發出sigalrm訊號 itimer virtual 給定乙個時間間隔,當...
C語言讀書筆記
1.c語言中一共有32個關鍵字 分別是 auto int double long char short float unsigned signed sizeof extern static goto if else struct typedef union enum switch case brea...