在C中使用qsort我们传递比较函数,例如
int cmp(const void*, const void*);
qsort的protoype期望一个int(*)(const void*,const void*)所以我们调用:
qsort(..., cmp);
但同样有效的是:
qsort(..., &cmp);
如果我们在C++中传入静态成员函数,这就是我们必须要做的.Kernighan&Ritchie(第2版,5.11"Pointers To Functions"p119)声明"因为[cmp]已知是一个函数,所以&运算符不是必需的,就像在数组名称之前不需要它一样. "
是否有人对此感到有点不舒服(特别是关于型号安全性)?
无论您是否感到不舒服,都不会改变C不被视为类型安全语言的事实.例证:
int main() { int integer = 0xFFFFFF; void (*functionPointer)() = (void(*)())integer; functionPointer(); return 0; }
这在编译时完全有效,但显然不安全.
嗯,答案是按值传递函数会产生一个函数指针,就像通过值传递数组一样,会产生一个指向其第一个元素的指针.一个人说阵列和功能"衰变".只有少数情况下不会发生衰变.例如sizeof(array)产生数组的大小,而不是它的第一个元素指针之一.sizeof(函数)无效(函数不是对象),你必须做sizeof(&function).其他场合绑定参考:
void baz(); void foo(void (&bar)()) { bar(); } // doesnt work, since a reference to a function is requested. // you have to pass 'bar' itself, without taking its address // explicitely. foo(&baz);
这个,顺便说一句就是你能做到的
templatevoid ByRef(T (&foo)[N]) { ... }
因为在考虑参考参数时阵列还没有衰减.