C语言学习笔记:利用递归实现字符串倒序输出

1. 题目要求

编写一个C语言程序,利用递归函数将输入的字符串倒序输出。

  • 输入提示:input your string:\n

  • 输入格式:%s

  • 输出格式:%c

2. 方法一:使用指针实现 (Pointer Approach)

这是C语言中最常用的递归处理字符串的方法。利用指针算术运算 s+1 逐步向后移动,直到遇到结束符 \0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

void reverse_print(char *s) {
if (*s == '\0') {
return; // 基准情况:遇到结束符停止
} else {
reverse_print(s + 1); // 递:移动指针到下一个字符
printf("%c", *s); // 归:打印当前字符
}
}

int main() {
char s[1024];
printf("input your string:\n");
scanf("%s", s);
reverse_print(s);
return 0;
}

3. 方法二:使用数组下标实现 (Index Approach)

如果不熟悉指针或被要求不使用指针运算,可以通过传递一个额外的整型参数 i 作为数组下标来访问字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

// 增加参数 i 表示当前访问的下标
void reverse_print(char s[], int i) {
if (s[i] == '\0') {
return; // 基准情况
} else {
reverse_print(s, i + 1); // 递:下标 + 1
printf("%c", s[i]); // 归:打印 s[i]
}
}

int main() {
char s[1024];
printf("input your string:\n");
scanf("%s", s);
reverse_print(s, 0); // 初始下标为 0
return 0;
}

4. 深入理解:为什么会倒序?(递归的“归”)

在编写递归时,初学者常有的疑问是:“当程序执行到末尾返回时,为什么会回到上一层(例如 i=2)继续执行?”

核心原理:函数调用栈 (Call Stack)

递归并不是单向的“一去不复返”,而是包含“递(压栈)”和“归(出栈)”两个过程。

暂停与等待:当代码执行到 reverse_print(s, i + 1); 时,当前层的函数并没有结束,而是被“暂停”了,它必须等待下一层函数执行完毕。

压栈(Stacking): 每一次调用都会将当前状态压入系统栈中。就像叠盘子一样,i=0 在最底下,i=1 在上面……直到遇到 \0

出栈(Unwinding): 当遇到 \0 触发 return 时,最上面的函数结束,控制权回到下一层(即刚才暂停的地方)。

后进先出 (LIFO): 因为栈是“后进先出”的,所以最后进入的字符(字符串末尾)最先被打印,最先进入的字符(字符串开头)最后被打印。

执行流可视化 (以输入 “abc” 为例)

main 调用 f(0) -> 暂停,等 f(1)

    f(1) 调用 f(2) -> 暂停,等 f(2)

        f(2) ('c') 调用 f(3) -> 暂停,等 f(3)

            f(3) ('\0') -> 遇到基准情况,返回

        回到 f(2) -> 执行 printf('c') -> 结束返回

    回到 f(1) -> 执行 printf('b') -> 结束返回

回到 f(0) -> 执行 printf('a') -> 结束返回

这就是为什么代码看起来是顺序写的,结果却是倒序输出的原因。


希望能帮到正在学习C语言递归的朋友!