根據 Andrew Koening在他的《C 陷阱與缺陷》裏對(*(void (*)( ) )0)( )的分析得到以下結論。
1.如何聲明一個變量?
float *g():g是一個函數,他的返回值是一個指針,該指針指向一個float數。
float (*h)(float):h是一個指針,該指針指向一個函數,這個函數的返回值是float類型的,這個函數的參數是float類型。
2.得到類型轉換符。
把聲明中的變量名和聲明末尾的分好去掉,把剩下的作爲一個整體用一個括號封裝起來,就是一個類型轉換符。
(1)float f;去掉變量名和分號,得到(float),及得到一個類型轉換符
(2)float (*h)(float);去掉變量名和分號,得到(float(*)(float)),這樣就得到一個類型轉換符。
將(2) 中的float換成void就得到我們這裏的(void (*)(void)),function[i][0]是一個指針數組中的一個元素,即“Test_Zdma0”,“Test_Zdma0”是一個函數名,它表示這個函數的地址,那麼(void (*)(void)) (function[i][0])意思就是把Test——Zdma0這個地址轉換成一個可以調用的函數指針。
3.調用函數指針。
假定fp是一個函數指針,那麼*fp就是該指針指向的函數,那麼調用它的方法就是--(*fp)()。標準C允許將上式簡寫爲fp(),這種寫法只是一種簡寫形式。
將fp換成上面的(void (*)(void)) (function[i][0])那麼函數調用就得到(*((void (*)(void)) (function[i][0])))(),他的簡寫形式就是我們要分析的((void (*)(void)) (function[i][0]) )().
這個語句的意思其實就是,調用Test_Zdma0()這個函數,只是把它放到數組裏,何以根據自己的需要方便調用。它就是根據Andrew Koening的(*(void (*)( ) )0)( )這個語句得來的,這裏的function[i][0]和0的意義相同。
這個語句也可以用typedef 來表述,會更加清晰:
typedef void (*fp)();那麼以後fp就可以用來聲明或者轉換其他的變量
(*(fp)0)()/(fp)0();那麼這個語句明顯就是對0地址處函數的調用了
經典就是經典,以後得多讀些經典書。
Ps:聲明一個新的類型名的方法是:
①先按定義變量的方法寫出定義體,如int i;
②將變量名換成新類型名,如i->count
③在最前面加typedef,如typedef int count
④然後用新類型名即count去定義新的變量。
來自譚浩強的《C程序設計》,說的比較囉嗦,不過好理解。