在 C 语言中的函数中定义函数
defining a function inside a function in c
我想创建一个通用函数,该函数返回指向C/C++中另一个函数的函数指针。但是,第二个返回的函数应该能够使用第一个函数中的变量。
例
typedef double (*func_t)(double);
func_t inverse(func_t fn) {
// define another function here that uses fn
double solve(double x) {
// use fn
}
return &solve;
}
double sqr(double x) { return x * x; }
int main() {
func_t inv = inverse(sqr);
printf("sqrt %d = %fn", 100, inv(100));
}
显然 gcc、g++ 不允许我这样做。我可以在不使用类或结构的情况下实现这一点吗?
这不是关于嵌套函数; 这是关于闭包。GCC 的嵌套函数是一种半实现的闭包形式,它不做问题所要求的。
按照任何标准,C 根本不支持闭包。
C++11 支持通过 lambda 进行闭包,还有一些特定于C++的其他解决方案。
Apple的Clang编译器确实支持闭包作为C模式下的扩展,以"块"的形式。与嵌套函数不同,这些函数实际上适用于请求的用例(即返回到更高的调用级别)。
你会把它写成这样:
typedef double (^func_t)(double); // block type is slightly different from function pointer
func_t inverse(func_t fn) {
return ^ double(double x) {
//use fn
};
}
// ...etc., same from here
但是如果你想广泛使用闭包,你真的需要使用不同的语言。由于缺乏任何类型的内存管理,您将在 C 语言中遇到严重的并发症(无限制的闭包是手动管理的噩梦)。
回答 C:
C不支持嵌套函数(在另一个函数中定义一个函数),但gcc
允许它作为 C 的 GNU 扩展。
http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html
这在 C++11 中使用 lambda 是可能的:
#include <cstdio>
#include <cmath>
#include <functional>
typedef std::function<double(double)> func_t;
func_t inverse(func_t fn) {
return [=](double x) { printf("fn(x): %fn", fn(x)); return sqrt(x); };
}
double sqr(double x) { return x * x; }
int main() {
auto inv = inverse(sqr);
printf("sqrt %d = %fn", 100, inv(100));
}
如果你可以使用C++11,那么lambda函数就是你的朋友:
#include <functional>
#include <iostream>
std::function<double(double)> identity(std::function<double(double)> fn)
{
return [fn](double x){
// Do your logic here
return fn(x);
};
}
double sqr(double x) { return x * x; }
int main() {
auto f = identity(sqr);
std::cout << "sqr(100) = " << f(100) << std::endl;
}
如果您不打算支持 C++11,可以通过以下方式执行以下操作:
#include <iostream>
typedef double (*func_t)(double);
struct func
{
func_t fn;
double (*calc)(func_t, double);
double operator()(double x) {return calc(fn, x);}
};
double identity_calc(func_t fn, double x) {return fn(x);}
func identity(func_t fn)
{
func f = {fn, identity_calc};
return f;
}
double sqr(double x) { return x * x; }
int main() {
func f = identity(sqr);
std::cout << "sqr(100) = " << f(100) << std::endl;
}
但我认为普通 C 不会有太多运气。
标准 C 中不允许嵌套函数
但是,它们在 GCC 中可作为语言扩展使用
由于问题被标记为C++。C++也不支持嵌套函数。您可能有这样的解决方法:-
int main()
{
struct ABC {
static void xyz()
{
}
};
ABC::xyz();
return 0;
}
即,您可以有本地类。
在 C 中的函数中定义函数?
称为嵌套函数。
嵌套函数不是 ANSI C 的一部分,但是,它们是 Gnu C 的一部分。
来自维基百科
支持词法嵌套函数的已知语言包括:
基于 ALGOL的语言,如 ALGOL 68、Simula、Pascal、Modula-2、Modula-3、Oberon、Seed7 和 Ada。
Lisp的现代版本(具有词汇范围),如Scheme和Common Lisp。
ECMAScript(JavaScript 和 ActionScript)。
斯卡拉(完全支持)
对脚本语言(如Ruby,Python,Perl)的各种支持(从版本6开始)。
标准 C 和 C++ 不支持嵌套函数,但:GCC 支持 C 中的嵌套函数,作为语言扩展。
与 C 相关的 D 语言具有嵌套函数。
Fortran,从Fortran-90开始,支持一级嵌套(CONTAINed)子例程和函数。
MATLAB(完全支持)
GNU C 语法中的示例(C 扩展与嵌套函数):
float E(float x)
{
float F(float y)
{
return x + y;
}
return F(3) + F(4);
}
comp.lang.c FAQ list ·问题20.24:
实现嵌套函数以使它们能够正确访问包含函数中的局部变量并非易事,因此为了简化,它们被故意排除在 C 之外。(GCC确实允许它们作为扩展。对于嵌套函数的许多潜在用途(例如 qsort 比较函数),一个足够但稍微繁琐的解决方案是使用带有静态声明的相邻函数,必要时通过一些静态变量进行通信。(一个更干净的解决方案,虽然不受 qsort 支持,但传递一个指向包含必要上下文的结构的指针。
通常你把函数写在一个额外的文件/模块中。让你的内部功能静态,外面没有人可以使用它。
制造
- 不同翻译单元中不可重载的非内联函数定义
- Visual Studio中的函数声明和函数定义问题
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 具有enable_if外部类原型的模板类构造函数定义
- 类的前向声明之后的类成员函数定义,在类声明之前
- 为函数定义符号不明确的指针参数
- C++模板专用化 - 无法匹配函数定义
- 错误:在第 6 行'{'标记之前,此处不允许使用函数定义
- 找不到 #define 的函数定义
- 根据类型特征更改函数定义?
- 将抽象基类中的所有纯虚函数定义为 varaidaic 模板
- 命名空间更改函数定义
- "Type&"与C++函数定义中的"Type*"
- C++:为什么允许在另一个函数中声明函数,而不允许在函数定义中声明?
- 如何从 C++ 中的现有模板函数定义新函数
- 私有在函数定义/实现的返回值范围内是什么意思 (c++)?
- 越界成员函数定义是否需要一个完全限定的类名,直到全局范围
- 为什么c++允许成员函数定义中实例的私有成员访问
- Qt基类函数定义
- C++函数定义中参数列表后面额外一对括号的含义