C 使用递归函数返回字符
我试图创建一个获取char数组的函数,如果数组中的元素是字母和小写,它会将元素更改为大写,反之亦然 我调试了代码,它似乎可以工作,我唯一的问题是我不知道如何重建char数组,因为每次我返回一个char,根据我的理解,它应该创建一个char数组 有人能告诉我我做错了什么吗C 使用递归函数返回字符,c,recursion,C,Recursion,我试图创建一个获取char数组的函数,如果数组中的元素是字母和小写,它会将元素更改为大写,反之亦然 我调试了代码,它似乎可以工作,我唯一的问题是我不知道如何重建char数组,因为每次我返回一个char,根据我的理解,它应该创建一个char数组 有人能告诉我我做错了什么吗 char reverseLetter(char str[]) { char temp; if (strlen(str) == 0) return 0; if (str[strlen(str
char reverseLetter(char str[])
{
char temp;
if (strlen(str) == 0)
return 0;
if (str[strlen(str) - 1] >= 'A' && str[strlen(str) - 1] <= 'Z')
{
temp = tolower(str[strlen(str) - 1]);
str[strlen(str) - 1] = '\0';
return reverseLetter(str) + temp;
}
else if (str[strlen(str) - 1] >= 'a' && str[strlen(str) - 1] <= 'z')
{
temp = toupper(str[strlen(str) - 1]);
str[strlen(str) - 1] = '\0';
return reverseLetter(str) + temp;
}
else
{
str[strlen(str) - 1] = '\0';
return reverseLetter(str);
}
}
void main()
{
char str[4] = { 'a', 'b', 'C', '\0' };
printf("%c", reverseLetter(str));
}
char reverseLetter(char str[])
{
焦炭温度;
如果(strlen(str)==0)
返回0;
如果(str[strlen(str)-1]>='A'&&str[strlen(str)-1]='A'&&str[strlen(str)-1]如果您真的需要递归执行此操作,这里有一个递归函数,可以将案例从A切换到Z
您可以让用户创建一个新字符串,并将其作为参数提供给您:
char reverseLetter(char*dest,char const*source)
{
while(*来源)
{
如果(*源='a')
*dest=*源-'a'+'a';
else if(*source='A')
*dest=*源-'A'+'A';
其他的
*dest=*来源;
++目的地;
++来源;
}
*dest='\0';
}
内部主(空)
{
字符src[]=“abC09”;
char-dst[6];
反向器(dst、src);
printf(“%s-->%s\n”,src,dst);
返回0;
}
请注意,source
具有限定符const
,因此用户知道您不会修改源字符串
如果您绝对希望它是递归的:
char reverseLetter(char*dest,char const*source)
{
如果(*源='a')
*dest=*源-'a'+'a';
else if(*source='A')
*dest=*源-'A'+'A';
其他的
*dest=*来源;
如果(*来源)
反向选择器(目标+1,源+1);
}
让我们将您的代码重写为等效代码:
char str[4] = { 'a', 'b', 'C', '\0' };
char c = reverseLetter(str);
printf("%c", c);
上面的内容完全相同,所以应该很清楚为什么它永远无法工作。您返回一个字符并打印一个字符
我会使用这种方法。首先,我会创建一个函数来翻转角色:
char flip(char c) {
if(isupper(c)) return tolower(c);
return toupper(c);
}
然后递归函数很简单:
char * reverseLetter(char str[]) {
if(str[0]) {
reverseLetter(str+1);
str[0] = flip(str[0]);
}
return str;
}
然后主要是:
int main() {
// Zero terminator not necessary. It gets appended automatically.
char str[] = {'a', 'b', 'C', '0', '9'};
printf("%s\n", str);
reverseLetter(str);
printf("%s\n", str);
}
为什么要使用递归函数执行此操作?问题是迭代的。它会打印什么?您希望它打印什么?函数应该在适当的位置修改字符串还是返回指向新字符串的指针?在这两种情况下,您都需要考虑返回类型。将返回类型设为char
而不是char*
或>void
是有问题的。他们要求我们使用递归函数,所以这不是我的选择。我支持AKX。但是如果有通常的原因(即“老师这么说”)然后,请仔细检查他们是否想要一个单个字符的返回值。这是因为使用指向字符的指针可以轻松实现目标,并且具有教学意义。@Yunnosch现在是使用isupper(int c)
并编写*p=isupper(c)→tolower(c):toupper(c)
。这假设p
可以修改。我错过了递归性。我的错误。@意思很重要,是的。这就是为什么它不是,例如const char*p
。此外,isupper
/toupper
tolower
可能与此代码有不同的语义,这取决于有效的区域设置。@AKX:“尾部递归”并不意味着“对恰好位于函数末尾的函数的递归调用”。C不支持通过函数调用语法进行尾部递归。您的递归调用正在消耗堆栈空间,如果目标字符串中有足够的字符,则会因堆栈溢出而失败。如果您希望这样做tail recursive“您需要A)用更新的值替换参数p
,B)在函数开头分支到标签。不复杂,但从实现的角度来看很有趣。
char * reverseLetter(char str[]) {
if(str[0]) {
reverseLetter(str+1);
str[0] = flip(str[0]);
}
return str;
}
int main() {
// Zero terminator not necessary. It gets appended automatically.
char str[] = {'a', 'b', 'C', '0', '9'};
printf("%s\n", str);
reverseLetter(str);
printf("%s\n", str);
}