在开始学习lisp时,我遇到了尾递归这个术语.这究竟是什么意思?
language-agnostic algorithm recursion functional-programming tail-recursion
很简单,什么是尾部调用优化?更具体地说,任何人都可以显示一些可以应用的小代码片段,而不是在哪里,并解释为什么?
language-agnostic algorithm recursion tail-recursion tail-call-optimization
在我看来,在C和C++中进行尾递归优化是完美的,但是在调试时我似乎永远不会看到表示此优化的帧堆栈.这有点好,因为堆栈告诉我递归的深度.但是,优化也会很好.
是否有任何C++编译器进行此优化?为什么?为什么不?
我如何告诉编译器这样做?
/O2或/Ox-O2或-O3如何在某种情况下检查编译器是否已完成此操作?
我仍然会建议如何确定编译器是否对某个函数进行了优化(尽管我发现它让人放心,Konrad告诉我假设它)
总是可以通过进行无限递归来检查编译器是否完成此操作,并检查它是否导致无限循环或堆栈溢出(我用GCC做了这个并且发现这-O2已经足够了),但我想成为能够检查我知道的某个功能无论如何都会终止.我很想有一个简单的方法来检查这个:)
经过一些测试,我发现析构函数破坏了进行优化的可能性.有时可能值得更改某些变量和临时值的范围,以确保它们在return语句开始之前超出范围.
如果在尾调用后需要运行任何析构函数,则无法进行尾调用优化.
我刚刚问了一个与编译器如何优化某些C++代码有关的问题,我正在寻找有关如何验证编译器是否已执行某些优化的任何问题.我试图查看用g ++(g++ -c -g -O2 -Wa,-ahl=file.s file.c)生成的汇编列表,可能会看到底层发生了什么,但输出对我来说太神秘了.人们使用什么技术来解决这个问题,是否有任何关于如何解释优化代码的汇编列表或特定于GCC工具链的文章的讨论这个问题的参考?
我正在用C++搞乱尾递归函数,而且我在使用g ++编译器时遇到了一些麻烦.
当numbers[]大小超过几百个整数时,以下代码导致堆栈溢出.检查由g ++生成的汇编代码,表明twoSum_Helper正在call对自身执行递归指令.
问题是以下哪一项导致了这种情况?
我正在g++ -O3 -Wall -fno-stack-protector test.c通过MinGW和g ++ 4.5.0在Windows Vista x64上进行编译.
struct result
{
int i;
int j;
bool found;
};
struct result gen_Result(int i, int j, bool found)
{
struct result r;
r.i = i;
r.j = j;
r.found = found;
return r;
}
// Return 2 indexes from numbers that sum up to target.
struct result twoSum_Helper(int numbers[], int size, int target, int i, …Run Code Online (Sandbox Code Playgroud) 可能重复:
递归是否比循环更快?
大约15年前,我第一次接受C语言培训.我的雇主想要高度优化的代码来处理计算困难的任务.我记得不止一次被建议将递归重写为循环,即使是在昂贵的可读性方面,以避免"递归开销".正如我所理解的那样,递归开销是将数据推送到堆栈然后将其弹出所需的额外工作.
现在我用C,Python,Perl编写,有时用Java编写代码,我有时会想到递归.还有什么东西可以通过重写来获得吗?如果它们是尾递归怎么办?现代编译器让所有这些问题都没有实际意义吗?这些担忧是否与解释语言无关?
optimization recursion programming-languages tail-recursion interpreted-language
我使用递归编写了一个函数.事实证明,在测试时,该函数在没有任何明显原因的情况下被终止,而递归仍然在运行.
为了测试这个,我写了一个无限的递归.
在我的电脑上,此功能在约2秒后退出,最后一个输出约为327400.最后一个数字并不总是相同.
我使用的是Ubuntu Lucid Lynx,GCC编译器和Eclipse作为IDE.如果有人知道问题是什么以及我如何阻止程序退出,我会非常高兴.
#include <iostream>
void rek(double x){
std::cout << x << std::endl;
rek(x + 1);
}
int main(int argc, char **argv) {
rek(1);
}
Run Code Online (Sandbox Code Playgroud) 使编译器生成尾递归代码似乎是一个简单的想法.但是大多数常用语言编译器(包括C和Pascal)都没有这样做,因此这些语言不能仅仅根据过程调用来表示迭代过程.这些语言中尾递归的难点在于它们的实现使用堆栈来存储过程参数和局部变量以及返回地址.
我无法理解为什么如果将堆栈用于过程参数,局部变量和返回地址,则无法实现尾递归.
我正在开发一个应尽可能少使用内存的库(我不关心其他任何东西,比如二进制大小或速度优化).
我可以使用任何GCC标志(或任何其他与GCC相关的选项)吗?我应该避免某种程度的-O*优化吗?