0

我通常很好地理解递归,但是因为我是 C 函数strcpy和指针的新手,所以我无法弄清楚这种递归如何反转字符串:

char *reverse(char *string)
{
    if (strlen(string) <= 1)
        return string;

    else
    {
        char temp = *string;

        strcpy(string, reverse(string+1));

        *(string+strlen(string)) = temp;

        return string;
    }
}

strcpy部分对我来说似乎有点复杂,这行的目的是什么:
*(string+strlen(string)) = temp;

我意识到在翻转字符串后,您需要将开头的字符添加到字符串的结尾,但我不确定我是否理解这段代码背后的逻辑。

4

3 回答 3

2

这段代码效率极低,但它的作用是:

  1. 保存原来的第一个字符
  2. 递归地反转字符串的其余部分(string+1是指向字符串中第二个字符的指针)。
  3. 将(反转的)字符串的其余部分复制到左侧一个字符。
  4. 将原始的第一个字符放在末尾 ( *(string+strlen(string)) = temp;)。

*(string+strlen(string)) = temp;相当于如果那string[strlen(string)] = temp;更容易理解。

我根本不推荐使用这段代码,因为它效率极低——它在每次迭代中复制整个字符串(并测量其长度两次),更不用说浪费堆栈空间了。

更好的实现是:

void reverse(char *s) {
  char *e = s+strlen(s)-1;
  while (e > s) {
    char tmp = *s;
    *s=*e;
    *e=tmp;
    s++; e--:
  }
}
于 2012-09-30T17:08:30.837 回答
0

*(string+strlen(string)) = temp是所谓的指针算术- 该代码相当于string[strlen(string)] = temp. 因此,这会将临时字符放在字符串的末尾。请注意,字符串仍然以零结尾,因为 reverse() 返回与其参数长度相同的字符串。

再次是指针运算,这次reverse(string+1)reverse(&string[1])- 即reverse()将从第二个字符开始镜像字符串,但strcpy()会将其放在字符串的开头,覆盖存储在temp中的第一个字符并放在字符串的末尾。

然而,整个代码看起来不必要的复杂和低效,所以在吸取任何关于如何从中做事的教训之前,我会三思而后行。

于 2012-09-30T17:05:42.033 回答
0

这就是代码的工作方式。输入字符串分为两部分,第一个字符和其余部分。第一个字符存储在 中temp,其余字符通过递归调用反转。递归调用的结果放在结果的开头,in 的字符temp放在结尾。

string is [1234567890]

temp is 1, string+1 is [234567890]

reverse(string+1) is [098765432], temp is 1

strcopy行是从reverse(string+1)的开头复制结果的部分string,并且*(string+strlen(string)) = temptemp在 的末尾复制的部分string

于 2012-09-30T17:24:36.230 回答