我有一个函数被传递给另一个函数,但我不确定为什么这两个函数都有效并且不产生任何警告。
typedef short (*COMP)(char *, char *);
DATA *bst_get(BST *, char *, COMP);
short cmp(char *a, char *b)
{
if (strstr(a, b))
return 0;
return strcmp(a, b);
}
// Both of these produce the same results
// the difference is '&cmp' vs 'cmp'
data = bst_get(bst, "textA", &cmp);
data = bst_get(bst, "textA", cmp);
那么正确的用法是什么?重要吗?
cmp
是一个带有“函数类型”的表达式。具有这些类型的表达式(几乎)总是隐式转换为具有相应函数指针类型的表达式,类似于(*参见末尾的注释)具有数组类型的表达式是如何转换的隐式转换为指向第一个数组元素的指针。这种隐式转换通常称为衰减,尽管这不是 C 语言标准(而是 C++)使用的术语。
另一方面,
&cmp
使转换显式:在这里您获取函数的地址,从而接收函数指针。
所以,底线是:它们是等价的,至少在 C 中,使用一个与另一个之间没有实际区别。
标准中的相关部分:
A function designator is an expression that has function type. Except when it is the operand of the sizeof
operator, the _Alignof
operator, or the unary &
operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
[N1570 §6.3.2.1/4]
注意:这意味着,始终“显式”意味着像这样编写函数调用:
#include <stdio.h>
void foo(void) {
printf("Awesome\n");
}
int main() {
(&foo)();
return 0;
}
*) 重要:提到的相似之处在于发生了隐式转换。 func
和 &func
产生完全相同的结果(值和类型),array
和 &array
产生不同的 结果(不同的指针类型)。原因是array
被隐式转换为&(array[0])
。所以,重复一遍,相似之处在于发生了隐式转换。实际转化不同。