博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
递归实现字符串逆序打印
阅读量:4124 次
发布时间:2019-05-25

本文共 1900 字,大约阅读时间需要 6 分钟。

01递归方式逆序打印

02递归和全局变量(把逆序的结果存入全局变量)

03递归和非全局变量(递归指针做函数参数)

#define _CRT_SECURE_NO_WARNINGS#include"stdio.h"#include"stdlib.h"#include"string.h"//01递归方式逆序打印int reverse01(char *p){	if (p == NULL)    //递归结束的异常条件	{		return -1;	}	if (*p == '\0')   //递归结束的条件	{		return 0;	}	reverse01(p+1);  //此时并不会接着执行打印,而是p的地址+1,不断入栈	                 //开始递归调用,保护程序执行现场,以便程序返回	                 //补充一个额外的知识点:p++相当于p=p+1,给p做了重新赋值。而p+1并不给p重新赋值	printf("%c\n",*p);}//02递归和全局变量(把逆序的结果存入全局变量)char g_buf[1000];//用全局变量把逆序的结果保存下来int reverse02(char *p){	if (p == NULL)     //递归结束的异常条件	{		return -1;	}	if (*p == '\0')    //递归结束的条件	{		return 0;	}	reverse02(p + 1);  	//printf("%c\n", *p);	//strncpy(g_buf, p, 1);    //每次拷的都是同一个位置,覆盖了	strncat(g_buf, p, 1);      //不断向后连接,不会覆盖}//03递归和非全局变量(递归指针做函数参数)int reverse03(char *p, char *bufResult){	if (p == NULL)    //递归结束的异常条件	{		return -1;	}	if (*p == '\0')   //递归结束的条件	{		return 0;	}	reverse03(p + 1,bufResult);	//printf("%c\n", *p);	strncat(bufResult, p, 1);}void main(){	int ret = 0;	char *p = "123456789";	//ret = reverse01(p);	/*memset(g_buf, 0, sizeof(g_buf));	reverse02(p);	printf("全局变量g_buf:%s\n", g_buf);*/	char mybuf[1024] = { 0 };	reverse03(p, mybuf);	printf("局部变量mybuf:%s\n", mybuf);}

关于reverse(p++)和reverse(p+1):

在递归函数中递归时,若使用reverse(p++),跟踪调试,发现每次递归传进去的p都是完整的“123456789”,并没有实现地址+1的操作。
下面是reverse(p++)调试截图:

reverse(p++)时反汇编:

下面是reverse(p+1)的调试截图:

reverse(p+1)时反汇编:

分析:

       从上面的调试可以看出:p++时执行死循环,没有ECX寄存器控制(ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器)。而p+1时,则lea  ecx,[esi+1],最后对esi进行逐个pop。 

       突然觉得这个话题好低能,看上面的递归,这里用p++和p+1时,对于传入的参数值不同,前者就是p,而后者是p+1。虽然p++会对后续使用p带来影响,但此处的递归函数reverse01需要的是p所指向的下一个地址,可写成p+1或者++p。但是++p改变了p值,反而后续输出则变得不正常。

通过反汇编,也可以看到reverse(p++)成了一个死循环,因为每次reverse(p++)传入的参数都是p,虽然p发生了变化,但是用不上!

       p++相当于p=p+1,给p做了重新赋值,p发生了更新。而p+1并不给p重新赋值,p不会发生更新。

void main(){	char *p = "123456";	for (; *p != '\0' ; p+1)     //死循环不断输出"1"	{		printf("%c", *p);	}}
所以什么时候用p++什么时候用p+1,一定要明白这两个的不同之处。
你可能感兴趣的文章
记CSDN访问量10万+
查看>>
Linux下Oracle数据库账户被锁:the account is locked问题的解决
查看>>
记CSDN访问20万+
查看>>
Windows 环境下Webstorm 2020.3 版本在右下角找不到Git分支切换部件的一种解决方法
查看>>
Electron-Vue项目中遇到fs.rm is not a function问题的解决过程
查看>>
飞机换乘次数最少问题的两种解决方案
查看>>
有向无回路图的理解
查看>>
设计模式中英文汇总分类
查看>>
WPF实现蜘蛛纸牌游戏
查看>>
单例模式
查看>>
工厂方法模式
查看>>
模板方法模式
查看>>
数据结构之队列、栈
查看>>
数据结构之树
查看>>
数据结构之二叉树
查看>>
二叉树非递归遍历算法思悟
查看>>
红黑树算法思悟
查看>>
从山寨Spring中学习Spring IOC原理-自动装配注解
查看>>
实例区别BeanFactory和FactoryBean
查看>>
Spring后置处理器BeanPostProcessor的应用
查看>>