首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >没有递归调用的递归?

没有递归调用的递归?
EN

Stack Overflow用户
提问于 2011-06-16 18:43:38
回答 2查看 920关注 0票数 20

在/prog/上找到了这个。我实际上用GDB处理了它,是的,它确实是一个递归。但是这是怎么发生的呢?

代码语言:javascript
运行
复制
// This works on 32-bit x86 Linux with gcc as long as you don't enable optimization.

#include <stdio.h>
#include <stdlib.h>

static void factorial(int in, int *out)
{
  *(&in-1)-=5-5*(1/in);
  *out*=in--;
}

int main(int argc, char **argv) 
{
  int result=1;
  int number=0;

  if (argc!=2) 
    exit(1);

  number=atoi(argv[1]);
  if (number<1)
    exit(2);

  factorial(number, &result);
  printf("%d! = %d\n", number, result);
  return 0;
}


$ ./factorial 3
3! = 6

$ ./factorial 5
5! = 120
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-06-16 18:52:14

甜。;)

这是非常不可移植的代码,只能在x86上运行。它所做的是更改堆栈上的返回地址,以便如果为in>1,函数不会返回到call指令后面的指令,而是返回到call指令本身。x86上的调用指令是5个字节(一个操作码加上调用目的地的4字节地址),因此需要从返回地址中减去5个字节。

代码语言:javascript
运行
复制
*(&in-1)-=5-5*(1/in);

只是一种模糊的说法

代码语言:javascript
运行
复制
if(in>1)
    *(&in-1)-=5;

&in-1是返回地址驻留在堆栈中的位置。

票数 22
EN

Stack Overflow用户

发布于 2011-06-16 18:50:09

它破坏了堆栈上的返回地址,导致了递归的发生。

代码语言:javascript
运行
复制
*(&in-1)-=5-5*(1/in);

&in-1可能是推送的返回地址。剩下的都是令人不快的魔法。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6370544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档