我在使用 C 中的以下语法时遇到问题:
float (*func(unsigned id))(float value) {
...
}
我的理解是:
- 它是一个名为
func
的函数的定义 func
接受一个类型为unsigned
的参数,称为id
func
返回指向函数的指针,如下所示:float f(float value)
但是我不明白为什么f
的返回值(返回的函数指针)和它的参数列表是分开的。
此外,func(unsigned id)
是一个计算结果为某个指针的表达式吗?这就是 (*func(unsigned id))
起作用的原因吗?
有人可以逐步阐明这个语法吗?
最佳答案
表达式 func(id)
返回一个指向函数的指针,该函数以 float 作为参数并返回一个 float 。
float(*f)(float v); // pointer to a function
float val;
f = func(3); // returns a pointer to a function
val = (*f)(3.14); // calls the function pointed to with argument 3.14
当然,你可以重写最后一条语句:
val = (*func(3))(3.14); // take the ptr returned by func(3) and call the function pointed to.
如果你有这样的功能:
float fct1 (float v) { return 2.0f*v+3.1f; }
你可以这样写:
f = fct1; // reassign the pointer to function f to the adress of fct1
让我们看一下语法。 C11 标准(草案 N1570)在 6.5.2.2 第 1 点中声明:“表示被调用函数的表达式)应具有指向函数的类型指针”,在第 3 点中:“A后缀表达式后跟圆括号 () 包含一个可能为空的逗号分隔的表达式列表是一个函数调用。”
这当然涵盖了常见的情况:
val = fct1 (3.14); // fct1 is the function designator which adresses the function
val = (*f) (3.14); // (*f) the dereferenced function pointer, so it addresses the function
但根据标准,以下内容也是有效的:
val = f(3.14); // This works as well, because f is a pointer to a function
val = func(3)(3.14) // works also because func(3) is a pointer to a function
然而,第一个表达式对于人类读者来说是模棱两可的,他们可能会将 f 视为函数指示符,期望它在某处定义。第二个也不寻常。此外,早期版本的 C 无法识别它们。我的 1978 年 K&R 版本需要 (*f)() 形式来调用函数指针。
最后的句法说明:如果将 f 定义为 float *f (float);
,它不会被理解为指向函数的指针,而是普通函数的前向声明调用 f 并返回一个指向 float 的指针。为什么 ?因为C precedence rules赋予 ()
比 *
更高的优先级,这意味着编译器会将其理解为 (float *)(f(float))
。这就是为什么需要显式括号来表明 (*f)
是函数指针的原因。
关于c - 返回函数指针语法的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25671410/