C++ 为什么我可以在另一个函数中定义一个函数?
参见下面的代码,我在另一个函数中定义了一个函数C++ 为什么我可以在另一个函数中定义一个函数?,c++,c,gcc,C++,C,Gcc,参见下面的代码,我在另一个函数中定义了一个函数 void test1(void) { void test2(void) { printf("test2\n"); } printf("test1\n"); } int main(void) { test1(); return 0; } 这种用法很奇怪,是c89/c99的用法,还是只是gcc的扩展(我在Ubuntu12中使用了GCC4.6.3)。我运行这段代码,它输出“test2”和“test1”。test2只能在test1中调
void test1(void)
{
void test2(void)
{
printf("test2\n");
}
printf("test1\n");
}
int main(void)
{
test1();
return 0;
}
这种用法很奇怪,是c89/c99的用法,还是只是gcc的扩展(我在Ubuntu12中使用了GCC4.6.3)。我运行这段代码,它输出“test2”和“test1”。test2只能在test1中调用
更重要的是,这种用法的常见场景是什么?这种用法的用途是什么?
嵌套函数说明。是的,这是一个
它不是C语言,也不是可移植的,因此不太推荐使用,除非您知道GCC会
- 是用于生成代码的唯一编译器
- 将在未来版本中继续支持此功能
- 不在乎
作为书面的,它不是合法的C++。但是,您可以定义 函数中的类,并在该类中定义函数。 但即便如此,在C++11之前,它仍然只是词汇嵌套; 您定义的类不“捕获”任何上下文 外部功能(除非您实现捕获 明确地);在真正的嵌套函数中,嵌套函数可以 访问外部函数中的局部变量。在C++11中,您可以 可以定义lambda函数,具有自动捕获功能
< C和C++没有采用嵌套函数的原因是因为 为了使捕获工作正常进行,您需要其他信息, 结果,指向函数的指针变得更加复杂。 结果是,您无法获取 嵌套函数(缺少正交性),指向嵌套函数的指针 函数与指向函数的普通指针不兼容 (最终需要太多的外部细节才能感知 out),或者所有指向函数的指针都有额外的信息(并且你为大部分时间不使用的东西付费)。嵌套函数只允许在C中使用,但很少使用,因为它们仅在该函数范围内可见。但是,如果您想绕过嵌套函数,可以执行以下操作
#include<stdio.h>
typedef void (*fptr)(void);
fptr test1(void) {
void test2(void) {
printf("test2\n");
}
printf("test1\n");
return test2;
}
int main(void) {
void (*f)(void);
f = test1();
f();
return 0;
}
#包括
类型定义无效(*fptr)(无效);
fptr测试1(无效){
无效测试2(无效){
printf(“test2\n”);
}
printf(“test1\n”);
返回test2;
}
内部主(空){
无效(*f)(无效);
f=test1();
f();
返回0;
}
它限制了test2()的范围。
您不能在test1()之外调用它。
当然,如果您有C++11,您几乎可以用lambdas定义嵌套函数。是否可以只调用test1而排除test2的执行?@bjskishore123,自动test2=[]{printf(“test2\n”);}
将不执行它,但仍然像函数定义一样发挥作用。@如果它是一个gcc扩展,则展开它,此用法的目的是什么?@CTMacUser:甚至不需要变量:[]{return printf(“test3\n”);}()代码>。但这与Perl的关系越来越近了。你说的“捕获”是指“关闭”?@Marcus-“捕获”是目的,“关闭”是一种实现。只有编译器应该关心关闭,并且它可以选择不同的实现(虽然关闭是正常的,但理由很好)。@ McCuror扩展到Stest314的响应,我使用了“捕获”,因为这是C++标准中使用的词。正如C++所定义的,它与闭包有些不同,正如我所知道的。特别是,在C++中,捕获可以通过拷贝或引用来实现,它只影响特定的变量,并且不会影响这些变量的生存期。但是我使用lambdas就是为了这个目的——基本上是为了替换语言缺少的#define
宏,以便在静态项目列表上进行测试(即没有运行时迭代)。@Steve314 C或Java怎么可能有嵌套函数?在这两种语言中,所有函数都必须是类的成员。