C语言递归拷贝字符串时s1++、s2++传参无输出问题
问题描述
实现基于字符指针的递归字符串拷贝逻辑时,若将递归调用copy()函数的传入参数从前置自增写法(++s1, ++s2)替换为后置自增写法(s1++, s2++),程序运行后无任何输出,可正常运行的原代码如下:
#include<stdio.h> void copy ( char *, char * ); int main ( void ) { char st[] = "hello"; char st2[10]; copy ( st, st2 ); printf ( "%s", st2 ); } void copy ( char *s1, char *s2 ) { *s2 = *s1; if ( *s1 == '\0' ) { return; } copy ( ++s1, ++s2 ); }
问题原因
核心是C语言前置、后置自增运算符的行为差异直接触发了无限递归栈溢出,程序在执行到printf前就被操作系统强制终止,自然没有输出:
- 前置自增
++p的逻辑:先把指针p存储的地址值+1,返回加1后的新地址作为表达式结果。原代码用该写法时,每一层递归传给下一层的都是字符串下一个字符的地址,递归会按顺序遍历h->e->l->l->o->\0,最终触发终止条件正常返回,完整走完拷贝流程。 - 后置自增
p++的逻辑:先返回自增前的原地址作为表达式结果,等函数传参动作全部完成后,才会修改当前函数栈帧内p存储的地址值。替换成该写法后,每一层递归传给下一层的永远是当前层持有的原指针:第一层递归传给第二层的是字符串首地址,第二层拿到首地址后传给第三层的还是首地址,所有递归层的s1永远指向首字符h,永远无法触碰到结束符\0,递归完全不会终止。 - 无限递归会持续消耗进程栈空间,直到栈容量耗尽触发段错误保护,进程被直接杀死,根本没有机会执行后面的
printf语句,因此看不到任何输出。
内容的提问来源于stack exchange,提问作者dumb
相关产品推荐
相关产品推荐

