今天寫程序時,在DSP2833x_PieVect.h看到typedef interrupt void (*PINT)(void)忽然一愣,上網查了下發如今這是加了interrupt 中斷關鍵字的函數指針,順便記一下並複習一下函數指針。數組
本文參照下面的博客整理而來函數
http://blog.csdn.net/lg2lh/article/details/7459138fetch
函數型指針
一個函數被執行時,在程序空間中佔據必定空間,這個空間的起始地址是用函數名來表示的,稱爲函數的入口地址。也能夠用指針指向這個入口地址,並經過該指針變量來調用這個函數。這種指針變量稱爲函數型指針變量,其通常形式爲:
數據類型標識符 (*指針變量名) ();
例如:int (*f)();
上式定義了指針f, f指向的函數並返回整型類數據。注意其中(*f)中的括弧不可缺乏,標識f是先與*結合,是指針變量,而後再與後面的()結合,表示此指針指向函數。this
在281x C中(),還增長了interrupt 中斷關鍵字(見下面的內容),所以可定義以下數據類型:spa
typedef interrupt void (*PINT)(void);
在上句中,定義了指針PINT爲指向一個特殊的函數interrupt型函數的指針類型。因爲在使用interrupt時,函數應被定義成返回void,並且無參數調用,所以在(*PINT)的後面加上(void),表示PINT是指向函數的指針,且無參數調用。在(*PINT)的前面加上interrupt void,表示PINT指向中斷函數,無參數返回值。這樣,在描述PIE中斷矢量表時,能夠定義以下的結構:.net
typedef interrupt void(*PINT)(void); // Define Vector Table: struct PIE_VECT_TABLE { // Reset is never fetched from this table. // It will always be fetched from 0x3FFFC0 in // boot ROM PINT PIE1_RESERVED; PINT PIE2_RESERVED; PINT PIE3_RESERVED; PINT PIE4_RESERVED; PINT PIE5_RESERVED; PINT PIE6_RESERVED; PINT PIE7_RESERVED; PINT PIE8_RESERVED; PINT PIE9_RESERVED; PINT PIE10_RESERVED; PINT PIE11_RESERVED; PINT PIE12_RESERVED; PINT PIE13_RESERVED;
..... ......
即該結構體的元素爲函數指針類型 ,注意這裏的interrupt只是說明PINT是指向中斷函數類型指針。若是沒有interrupt,typedef void (*PINT)(void),則PINT仍是表示指向函數的指針類型。只是不屬於中斷函數。指針
其中,PIE_VECT_TABLE是一個結構類型,其中的全部成員均爲中斷函數的首地址,即指向中斷函數的指針。所以,在定義其成員如PIE1_RESERVED等時,要在其前面加PINT,表示PIE1_RESERVED是PINT類型的變量,即指向中斷函數的指針。這樣程序顯得比較簡潔。code
理解複雜聲明可用的「右左法則」:從變量名看起,先往右,再往左,碰到一個圓括號就調轉閱讀的方向;括號內分析完就跳出括號,仍是按先右後左的順序,如此循環,直到整個聲明分析完。舉例:blog
int (*func)(int *p);get
首先找到變量名func,外面有一對圓括號,並且左邊是一個*號,這說明func是一個指針;而後跳出這個圓括號,先看右邊,又遇到圓括號,這說明(*func)是一個函數,因此func是一個指向這類函數的指針,即函數指針,這類函數具備int*類型的形參,返回值類型是int。
int (*func[5])(int *);
func右邊是一個[]運算符,說明func是具備5個元素的數組;func的左邊有一個*,說明func的元素是指針(注意這裏的*不是修飾func,而是修飾func[5]的,緣由是[]運算符優先級比*高,func先跟[]結合)。跳出這個括號,看右邊,又遇到圓括號,說明func數組的元素是函數類型的指針,它指向的函數具備int*類型的形參,返回值類型爲int。