递归实现字符串逆序打印

来源:互联网 发布:软件开发实施方案范文 编辑:程序博客网 时间:2024/06/02 15:55

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,一定要明白这两个的不同之处。
0 0
原创粉丝点击