C中函数内部的函数
我正在制作一个与此类似的代码:
#include double some_function( double x, double y) { double inner_function(double x) { // some code return x*x; } double z; z = inner_function(x); return z+y; } int main(void) { printf("%f\n", some_function(2.0, 4.0)); return 0; }
这在GCC中完美编译(没有警告)但无法在ICC中编译。
ICC给出:
main.c(16): error: expected a ";" { ^ main.c(21): warning #12: parsing restarts here after previous syntax error double z; ^ main.c(22): error: identifier "z" is undefined z = inner_function(x); ^ compilation aborted for main.c (code 2)
我究竟做错了什么?
谢谢。
(编辑)抱歉这个可怜的例子。 在我的原始代码中,我有点需要做这些事情。 我正在使用GSL数值积分器,有类似的东西:
double stuff(double a, double b) { struct parameters { double a, b; }; double f(double x, void * params) { struct parameters p = (struct parameters *) params; double a = p->a, b = b->b; return some_expression_involving(a,b,x); } struct parameters par = {a,b}; integrate(&f, &par); }
我有很多这种结构的函数:它们是函数与大量外部参数集成的结果。 并且实现数值积分的函数必须接收指向类型函数的指针:
double f(double x, void * par)
我真的希望函数以这种方式嵌套,所以我的代码不会膨胀很多很多函数。 我希望我能用ICC编译它以加快速度。
其他人都给了你规范的答案“标准C中不允许使用嵌套函数”(因此任何使用它们都取决于你的编译器)。
您修改后的示例如下:
double stuff(double a, double b) { struct parameters { double a, b; }; double f(double x, void * params) { struct parameters p = (struct parameters *) params; double a = p->a, b = b->b; return some_expression_involving(a,b,x); } struct parameters par = {a,b}; return integrate(&f, &par); // return added! }
既然你说积分器等function需要
double (*f)(double x, void * par);
我不明白为什么你真的需要嵌套函数。 我希望写:
struct parameters { double a, b; }; static double f(double x, void *params) { struct parameters p = (struct parameters *) params; double a = p->a, b = b->b; return some_expression_involving(a,b,x); } double stuff(double a, double b) { struct parameters par = { a, b }; return integrate(f, &par); }
上面的代码应该在C89中工作(除非像初始化’par’那样存在问题)或C99; 此版本的代码仅适用于C99,使用参数的复合文字(第6.5.2.5节复合文字):
double stuff(double a, double b) { return integrate(f, &(struct parameters){a, b}); }
很有可能你只对“结构参数”类型有一些变化。 您需要为各种函数提供单独的(足够)有意义的名称 – 每个源文件只能有一个名为“ f
”的函数。
嵌套函数版本唯一的微不足道的好处是你可以确定没有其他函数比stuff
调用f
。 但鉴于示例代码,这不是一个主要的好处; f
的静态定义意味着除非传递指向函数的指针,否则此文件外的任何函数都不能调用它。
嵌套函数在GCC中作为语言扩展提供 ,但它们不是标准语言的一部分,因此一些编译器不允许它们。
C没有嵌套函数。 GCC的嵌套函数是该语言的扩展。
GCC中的运行时错误是拼写错误。 inner_funcion
应该是inner_function
。
正如上面的许多答案所提到的,C中不支持内部函数,但是内部类可以在C ++中用于完成类似的事情。 不幸的是,它们使用起来有点笨拙,但如果您不介意编译为C ++,它可能是您的选择。
未经测试的例子:
double some_function( double x, double y) { struct InnerFuncs { double inner_function(double x) { // some code return x*x; } // put more functions here if you wish... } inner; double z; z = inner.inner_function(x); return z+y; }
请注意,这个答案不应该暗示我认为内部函数在您显示的用法中是个好主意。
几年后编辑:
C ++现在允许我们使用lambdas作为内部函数。 对于我上面的玩具示例,它看起来很像这样:
double some_function( double x, double y) { auto inner_function = [&]() { return x * x; } double z; z = inner_function (); return z + y; }
注意局部变量x是在lambda内部自动捕获的,这是一个非常好的function。
更多信息: C ++ 11中的lambda表达式是什么?
您正在使用嵌套函数 – C不支持此类操作。
这不是有效的C代码,C中不支持内部函数
函数内的局部函数定义在C中是非法的。
嵌套函数不是C标准的一部分。 因此,无法保证它适用于所有编译器,并且绝对应该避免。
如果您想知道如何关闭GCC扩展等。
您可以使用-ansi
标志,它基本上将标准设置为c89,并关闭与ISO C90不兼容的GCCfunction。
有关更多信息,请参阅文档 。 查看-std
标志。
我不是专家,但我愿意打赌这是C99规范明确禁止或未定义的,所以最好远离它。