You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言如何判断函数是否为尾递归?示例代码求判定及原因说明

尾递归判断规则

尾递归的核心特征是:函数执行的最后一步仅为递归调用自身,调用的返回值直接作为当前函数的返回值,不存在任何额外运算(算术运算、逻辑运算、赋值操作等),也不需要保留当前函数的栈帧数据等待递归返回后再处理。
C语言场景下判断可以直接遵循两个判断点:

  • 递归调用是函数退出前的最后一个可执行操作
  • 递归调用的返回值不需要参与任何运算,直接被返回
你提供的代码不属于尾递归

你编写的list_size_count函数不符合尾递归要求,核心原因如下:

struct link 
{
  int value; //data    
  link_t *next; //link
};

struct list
{
    link_t *first;
    link_t *last;
};

int list_size_count(link_t *first, int acc)
{
  if (first != NULL)
  {
    // 问题点:递归调用结束后,还需要执行 acc + 递归返回值 的加法操作,才能得到当前函数的返回值
    // 程序必须保留当前栈帧中的acc值,等递归调用完成后做加法,无法触发尾递归优化
    return (acc + list_size_count((first->next), 1));
  }
  return acc;
}

int linked_list_size(list_t *list)
{
  return list_size_count((list->first),0);
}

上述代码的递归逻辑虽然能算出正确的链表长度,但额外的加法操作打破了尾递归的要求。如果需要改写为尾递归版本,可以参考如下实现:

int list_size_count(link_t *first, int acc)
{
  if (first != NULL)
  {
    // 累加逻辑提前放到参数中传递,最后一步仅执行递归调用,返回值直接作为当前函数返回值
    return list_size_count(first->next, acc + 1);
  }
  return acc;
}

改写后的版本满足尾递归的所有特征,编译器开启优化选项(如O2)时会直接将递归转化为循环执行,不会出现递归深度过高导致的栈溢出问题。

内容的提问来源于stack exchange,提问作者fireproofiii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:39:01