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

C语言递归实现字符反转:scanf段错误、getchar正常的原因解析

递归字符反转代码中scanf触发段错误的原因解析

核心问题:类型不匹配+scanf的EOF处理行为

1. EOF的本质

EOF是C标准定义的int类型常量,值通常为-1。而代码中用char ch存储读取的字符,这就埋下了类型不匹配的隐患:

  • 如果系统中char是有符号类型,-1可以被存入ch;
  • 如果是无符号类型,-1会被转换为UCHAR_MAX(比如255),此时ch永远不可能等于EOF(int类型的-1)。

2. getchar()能正常运行的原因

getchar()的返回值是int类型:

  • 读取正常字符时,返回字符的ASCII值(转换为int);
  • 到达EOF或读取失败时,返回EOF(int的-1)。

当输入结束时,getchar()返回EOF并赋值给char ch:

  • 若char是有符号类型,ch会被设为-1,此时ch == EOF的判断成立,递归终止;
  • 即使char是无符号类型,部分环境的输入结束处理逻辑可能让递归提前终止(但本质属于未定义行为,只是恰好正常运行)。

3. scanf("%c", &ch)触发段错误的原因

scanf的行为和getchar()有关键区别:

  • 当输入到达EOF时,scanf("%c", &ch)会返回EOF,但不会修改ch的内存值。而代码中char ch是未初始化的局部变量,值为随机垃圾值。
  • 如果这个随机值不等于EOF(-1),递归会无限调用,每次递归都会在栈上创建新的ch变量,最终导致栈溢出,触发段错误。
  • 若系统中char是无符号类型,ch在和EOF比较时会被提升为unsigned int,此时ch的值永远是正数,不可能等于-1,递归会无条件无限进行,必然触发栈溢出。

修复方案

要解决这个问题,需要从两个方面修正:

  • 把ch的类型改为int,匹配EOF的类型;
  • 检查scanf的返回值,而不是只判断ch的值:
#include <stdio.h>
void reverse()
{
    int ch;
    // 检查scanf的返回值,判断是否到达EOF
    if (scanf("%c", &ch) == EOF) {
        return;
    }
    reverse();
    printf("%c", ch);
}
int main()
{
    reverse();
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:27:22