字符串逆序输出与main函数的递归调用

来源:互联网 发布:二手淘宝网首页 编辑:程序博客网 时间:2024/05/22 13:50

昨天有人问问了我这样一道题,如何不利用第三方变量,将字符串逆序输出。我给出了几种方案,有非递归的,也有递归的。

一:

首先来非递归的,这个就比较简单了,直接利用strlen函数求得字符串长度,然后逆序输出即可。

代码如下:

#include <iostream>#include <string.h>void reverse_str(const char *str){auto len = strlen(str);for(int i=len-1; i>=0; --i){std::cout << str[i];}}int main(int argc, char ** argv){if(argc != 2){fprintf(stdout, "Usage %s <string>\n", argv[0]);exit(EXIT_FAILURE);}reverse_str(argv[1]);return 0;}

二:

其次为递归方法,递归的思路是函数压栈,当检测到\0,递归终止,然后函数出栈,逆序打印每个字符。

其中有两点值得注意:

1、字符串作为全局变量

<pre name="code" class="cpp">#include <iostream>const char *str = "iloveyou";void reverse_string(const char *){if(*str != '\0')reverse_string(++str);if(*str != '\0')std::cout << *str;--str;}int main(int argc, char** argv){reverse_string(str);return 0;}

这种递归方法显然可以成功,然后我又想用字符串定义在主函数,利用主函数调用的方式。

2.字符串作为主函数局部变量

(1)++str

我首先用了这样的写法:

//wrong#include <iostream>void reverse_string(const char *str)   //error,因为++str如果在底层函数中改变,想要在上一层保留变动结果,需要传递引用。{if(*str != '\0')reverse_string(++str);   //if(*str != '\0')std::cout << *str;--str;}int main(int argc, char** argv){const char *str = "iloveyou";reverse_string(str);return 0;}

这个写法困扰了我好长时间,它总是打印不到第一个字母,后来我突然意识到,如果需要在递归子程序里面改变参数的值,就需要传递引用给它,这样才能保留你要做的改动,并返回给上一层。下面这种写法才是正确的:

#include <iostream>void reverse_string(const char *&str)   //right,传递引用{if(*str != '\0')reverse_string(++str);   if(*str != '\0')std::cout << *str;--str;}int main(int argc, char** argv){const char *str = "iloveyou";reverse_string(str);return 0;}
(2)str+1

另外一种写法就是直接用str+1,这样你的str指针始终指向不变,只是传递给下一层的参数,是你的str+偏移量的那个地址,相当于tmp = str +偏移量,tmp传给下一层子函数。而不是str++, str++其实是 str = str + 1,str自身指向也改变了。
由于每一层子函数都有自己的str+偏移量结果,自然不需要传递引用了,因为我们不需要也不会改变str的指向,也就不需要--str了。代码如下:

#include <iostream>void reverse_string(const char *str)   //由于不用改变str,所以不需要传递引用{if(*str != '\0')reverse_string(str+1);   //对应str+1if(*str != '\0')std::cout << *str;//--str;     //每一层都有自己的str+偏移量}int main(int argc, char** argv){const char *str = "iloveyou";reverse_string(str);return 0;}

三:

终极方法:main函数的递归调用实现字符串逆序输出。

1.首先我给出了这样的写法:

#include <iostream>char* str = "iloveyou";int main(char *, char **argv = NULL){if(*str != '\0')main(++str);if(*str != '\0')std::cout << *str;--str;return 0;}
这种写法编译有警告,但可执行且输出结果正确。


不过本着好学的精神,我自己把它的几个警告一一解决掉了。

2.完美无敌版如下:

#include <iostream>const char *str = "iloveyou";int main(int argc , char** argv = NULL){char ch = (char)argc;if(ch != '\0')main(*((int *)const_cast<char*>(++str)));  //const_cast解除const限定if(ch != '\0')std::cout << *str;--str;return 0;}
首先给字符串加上const解决第一个警告,但是由于加了const之后,再将str作为参数传递时,接受参数也必须为const,但是main函数参数如上图第二个警告所说,第一个必须为int型,所以先用const_cast去掉str的const限定,将str转为为Int类型,用argc参数接收,然后在函数内部进行强转赋给ch,通过char类型的ch作为判断条件,利用类似子函数递归逆序的方法,实现main函数的递归调用。
正确输出为:

0 0
原创粉丝点击