C++ 为什么可以';我不能递归调用我的函数吗?
我试图编译此代码以反转字符串:C++ 为什么可以';我不能递归调用我的函数吗?,c++,C++,我试图编译此代码以反转字符串: void reverse(char *str, int n) { if (n==0 || n==1) { return; //acts as quit } else { char i = str[0]; //1st position of string char j = str[n-1]; //Last position of string char temp
void reverse(char *str, int n)
{
if (n==0 || n==1) {
return; //acts as quit
} else {
char i = str[0]; //1st position of string
char j = str[n-1]; //Last position of string
char temp = str[i];
str[i] = str[j]; //Swap
str[j] = temp;
reverse(str[i+1],n-1); // <-- this line
}
}
#include <iostream>
int main()
{
char *word = "hello";
int n = sizeof word;
reverse(word, n);
std::cout << word << std::endl;
return 0;
}
void反向(char*str,int n)
{
如果(n==0 | | n==1){
return;//作为退出
}否则{
char i=str[0];//字符串的第一个位置
char j=str[n-1];//字符串的最后位置
char temp=str[i];
str[i]=str[j];//交换
str[j]=温度;
反向(str[i+1],n-1);//如下使用:
reverse(&str[i+1],n-1);
第(i+1)位的传递地址不是值。str[i+1]
是一个字符,而不是指向字符的指针;因此会显示错误消息
当您进入函数时,str
指向您要与n
交换的字符:远离str
的第个字符
递归中需要做的是增加指针,使其指向下一个字符。
您还需要将n
减少2,因为它应该是距离str+1
,而不是距离str
(这很容易出错;有关示例,请参阅此答案的编辑历史记录。)
交换时,您还将字符串中的字符用作字符串的索引。
(如果您输入了“ab”
,您将执行char temp=str['a'];str['a']=str['b'];str['b']=temp;
。这显然是不正确的。)
str[0]
不是第一个字符的位置,而是第一个字符
如果允许,请使用std::swap
,否则请参见下文
更多问题:您不应该使用sizeof word
,因为这取决于您的目标体系结构,可能是4或8,这相当于sizeof(char*)
您应该使用strlen
来确定字符串的长度
此外,你应该得到一个警告
char *word = "hello";
由于这种特殊的转换是危险的-“hello”
是一个常量
数组,修改它是未定义的。
(如果您从未修改过阵列,这将是安全的,但您确实修改了,所以它不是。)
将其复制到非常量数组中:
char word[] = "hello";
并提高编译器的警告级别
这里有一个固定版本:
void reverse(char *str, int n)
{
if(n <= 1) // Play it safe even with negative n
{
return;
}
else
{
// You could replace this with std::swap(str[0], str[n-1])
char temp = str[0]; //1st character in the string
str[0] = str[n-1]; //Swap
str[n-1] = temp;
// n - 2 is one step closer to str + 1 than n is to str.
reverse(str + 1, n - 2);
}
}
int main()
{
char word[] = "hello";
// sizeof would actually work here, but it's fragile so I prefer strlen.
reverse(word, strlen(word));
std::cout << word << std::endl;
}
void反向(char*str,int n)
{
如果(n我要剖析你的代码,就好像你在上面发了帖子一样。毕竟,你要求其他的观察
首先,
char *word = "hello";
编译器应该警告您,将char*
指向文本字符串是未定义的行为(如果没有,请确保您实际启用了一组良好的警告。由于历史原因,许多编译器默认情况下发出的警告很少)。您需要确保有一个可写字符串;为此,您可以使用char[]
:
char word[] = "hello";
下一行
int n = sizeof word;
现在更改了含义,但仍然是错误的。在原始代码中,它是指向char
的指针的大小,不太可能与单词“hello”的长度相同。更改为char[]
,它现在是6个字符数组的大小,即6
。第六个字符是字符串文本结尾的NUL。您可能需要使用strlen()
函数,而不是sizeof
运算符
转到反向()
:
您从字符串中的位置读取字符,然后使用这些字符对其进行索引。这不是您想要的,GCC警告不要使用纯char
进行索引,因为它可能有符号或无符号。您只需要在一个位置进行索引,而i
和j
是不必要的
最后,您提出的问题。str[i+1]
是位于i+1
位置的字符,但是您的函数需要一个指向字符的指针,它就是str+i+1
。或者,因为我们已经解决了,所以我们不希望i
在那里,只要str+1
还要注意,您需要从n
中减去2,而不是1
,因为它将用作str+1
中的字符计数。如果只减去1,您将始终与最后一个字符交换,并且您将实现“滚动”而不是“反转”
以下是一个工作版本:
void reverse(char *str, int n)
{
if (n < 2)
// end of recursion
return; //acts as quit
char temp = str[0];
str[0] = str[n-1]; //Swap
str[n-1] = temp;
reverse(str+1,n-2);
}
#include <iostream>
#include <cstring>
int main()
{
char word[] = "hello";
int n = std::strlen(word);
reverse(word, n);
std::cout << word << std::endl;
}
并用反向调用它(word,word+n-1)
最后(我不打算提及std::reverse()
),这里是惯用的迭代版本:
void reverse(char *str, char *end)
{
while (str < end)
std::swap(*str++, *end--);
}
void reverse(char*str,char*end)
{
while(str
在发布问题之前,先听编译器的声音。reverse
很容易将char*
作为输入,而您将char
(即str[i+1]
)。str[i]
不是str
字符串中的i
th“位置”,它是存储在那里的值。即str[i+1]
是一个char
,编译器是对的。索引str[i]
和str[j]
看起来也不对-我认为它们应该是str[0]
和str[n-1]
分别。噢,您需要n-2
,而不是n-1
,或者始终使用最后一个字符进行交换。此外,原始main
函数正在传递sizeof(“hello”)
到反向函数。这会将终止的空字符反向到第一个字符-输出将为空!@Martin-错误略有不同,因为最初使用的是sizeof(char*)
,而不是sizeof(char[6])
。请参阅我的答案(我在编辑molbdnilo时编写的)@TobySpeight:噢,悲伤!所以这可能会给出“lleho”或未定义的行为,这取决于OP编译的是32位还是64位。快乐!
void reverse(char *str, char *end)
{
while (str < end)
std::swap(*str++, *end--);
}