我在C中遇到以下语法问题:
float (*func(unsigned id))(float value) {
...
}
我理解:
func
func
接受一个名为unsigned
id
类型的参数
func
返回指向以下内容的函数的指针:float f(float value)
但我不明白为什么f
(返回的函数指针)的返回值与其参数列表分开。
另外,是:func(unsigned id)
一个表达式,计算为某个指针?这是(*func(unsigned id))
工作的原因吗?
有人可以一步一步地澄清这种语法吗?
答案 0 :(得分:7)
表达式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)
是函数指针的原因。
答案 1 :(得分:5)
float (*func(unsigned id))(float value) { ... }
首先替换" func"用" f"因为这个漂亮的网站在" func"然后删除参数名称。
float (*f(unsigned ))(float )
// declare f as function (unsigned) returning pointer to function (float) returning float
由此,f
是一个unsigned id
的函数声明。这是f(unsigned )
部分。
它返回一个变量x
,就像它被声明为float (*x)(float )
一样。正如OP观察到的那样,前半部分与函数的原始声明中的第二部分是分开的。
建议对该网站进行实验,记住不要使用" func"
示例:
int f2(unsigned );
// declare f2 as function (unsigned) returning int
int (*f3(unsigned ));
// declare f3 as function (unsigned) returning pointer to int
int (*f4)(unsigned );
// declare f4 as pointer to function (unsigned) returning int
int (*f5(unsigned ))(char);
// declare f5 as function (unsigned) returning pointer to function (char) returning int
答案 2 :(得分:4)
float (*func(unsigned id))(float value);
是一个函数的声明,它将 unsigned int 作为参数并返回指向函数的指针。
指针指向的函数(函数f
)将 float作为参数,返回float 。它的声明是:
float f(float value);
func
功能的名称:
float (*func(unsigned id))(float value);
^^^^
函数func
的参数:
float (*func(unsigned id))(float value);
^^^^^^^^^^^
函数func
的返回类型:
float (*func(unsigned id))(float value);
^^^^^^^^ ^^^^^^^^^^^^^
如果函数有无参数,它将如下所示:
float (*func())(float value);
你问过:另外,是:func(unsigned id)
一个表达式,它是一个指针吗?
否,它是名称func
和函数的参数(unsigned id)
你现在开始看到func
是什么?它是一个返回指向另一个声明函数的指针的函数。
我包含了一些代码,您可以在其中明确地看到func
函数的返回值与f
函数的引用相比较。
#include <stdio.h>
float f(float value);
float (*func(unsigned id))(float value);
int main()
{
/* print the address of the f function
* using the return value of function func
*/
printf("func return value: %p\n\n", func(2));
/* print the address of the f function referencing
* its address
*/
printf("referencing f address: %p\n", &f);
return 0;
}
float (*func(unsigned id))(float value)
{
printf("Original function with argument id = %d called\n", id);
return f;
}
float f(float value)
{
printf("f function\n");
return 0.1;
}