(void(*)(void))func()的解读

根据 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程序设计》,说的比较啰嗦,不过好理解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章