我正在制作一个与此类似的代码:
#include <stdio.h>
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;
}
Run Code Online (Sandbox Code Playgroud)
这在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)
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
谢谢.
(编辑)抱歉这个可怜的例子.在我的原始代码中,我有点需要做这些事情.我正在使用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);
}
Run Code Online (Sandbox Code Playgroud)
我有很多这种结构的函数:它们是函数与大量外部参数集成的结果.并且实现数值积分的函数必须接收指向类型函数的指针:
double f(double x, void * par)
Run Code Online (Sandbox Code Playgroud)
我真的希望函数以这种方式嵌套,所以我的代码不会膨胀很多很多函数.我希望我能用ICC编译它以加快速度.
Jon*_*ler 22
其他人都给了你规范的答案"标准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!
}
Run Code Online (Sandbox Code Playgroud)
既然你说积分器等功能需要
Run Code Online (Sandbox Code Playgroud)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);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码应该在C89中工作(除非像初始化'par'那样存在问题)或C99; 此版本的代码仅适用于C99,使用参数的复合文字(第6.5.2.5节复合文字):
double stuff(double a, double b)
{
return integrate(f, &(struct parameters){a, b});
}
Run Code Online (Sandbox Code Playgroud)
您对"结构参数"类型只有几个变体的可能性非常大.您需要为各种函数提供单独的(充分)有意义的名称 - f每个源文件只能有一个名为' '的函数.
嵌套函数版本唯一的微不足道的好处是你可以确定除了stuff调用之外没有其他功能f.但是考虑到示例代码,这不是主要的好处; 静态定义f意味着除非传递指向函数的指针,否则此文件外的任何函数都不能调用它.
正如上面的许多答案所提到的,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;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这个答案不应该暗示我认为内部函数在您显示的用法中是个好主意.
几年后编辑:
C++现在允许我们使用lambdas作为内部函数.对于我上面的玩具示例,它看起来很像这样:
double some_function( double x, double y)
{
auto inner_function = [&]() { return x * x; }
double z;
z = inner_function ();
return z + y;
}
Run Code Online (Sandbox Code Playgroud)
注意局部变量x是在lambda内部自动捕获的,这是一个非常好的功能.