C 使用递归函数返回字符

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数组的函数,如果数组中的元素是字母和小写,它会将元素更改为大写,反之亦然

我调试了代码,它似乎可以工作,我唯一的问题是我不知道如何重建char数组,因为每次我返回一个char,根据我的理解,它应该创建一个char数组

有人能告诉我我做错了什么吗

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);
}