C - 关闭一个错误

时间:2011-04-18 07:22:16

标签: c

在下面的简单反向函数中,我总是一个接一个,这意味着传入的第一个字符永远不会像最后一样打印出来:

  void reverse(char * c)
{
    if(*c != '\0')
    {
        reverse(++c);
        printf("%c", *c);
    }
    else {
        return;
    }
}

然而,当我将反向调用更改为c + 1时,一切正常。任何想法为什么,一元预增量运算符应该与c + 1完全相同。我知道递归函数不是解决这个问题的最佳表现方式,但我现在只是在试验。谢谢!

6 个答案:

答案 0 :(得分:7)

由于c+1 更改c,而++c 会更改。{/ em>

c指向地址1234

时,请考虑这一点
reverse(++c);      // c is now 1235 and you pass that.
printf("%c", *c);  // so we print the second character at 1235.

使用c+1版本:

reverse(c+1);      // c is still 1234 but you pass 1235.
printf("%c", *c);  // so we print the first character at 1234.

对于它的价值,你的reverse函数是不必要的复杂。else return是多余的,我个人更喜欢首先检查终止条件的递归调用,因为我经常发现它们对于编译器来说通常更容易在...上进行尾端递归优化。

以下完整的测试程序向您展示了我的方式:

#include <stdio.h>

void reverse (char *c) {
    if (*c == '\0') return;
    reverse (c + 1);
    putchar (*c);
}

int main (int argc, char *argv[]) {
    int i;
    for (i = 1; i < argc; i++) {
        reverse (argv[i]);
        putchar ('\n');
    }
    return 0;
}

使用testprog hello goodbye运行此功能会为您提供:

olleh
eybdoog

答案 1 :(得分:4)

没有一元的预增量与添加一样不一样。

f(++c)相当于

c = c + 1
f(c);

f(c+1)相当于

auto d = c + 1;
f(d);

只是为了完整性:f(c++)

相同
f(c);
c = c+1;

然而,序列点很重要,例如if(c++ > 0 && c++ < 10)会评估为

auto a = c;
c = c + 1;

auto b = c;
c = c + 1;

if(a > 0 || b < 10) { /* ... */ }

因此preincrement

c = c + 1;
auto a = c;

c = c + 1;
auto b = c;

if(a > 0 || b < 10) { /* ... */ }

答案 2 :(得分:3)

使用c + 1进行调用不会更改本地上下文中c的值(打印*c时使用的值),但在调用中使用++c

答案 3 :(得分:0)

已修复:您不应使用增量运算符。运营商+会更好。:

reverse(c + 1);
printf("%c", *c);

答案 4 :(得分:0)

不,它没有做同样的事情。

它递增它然后将它发送到您的函数。

答案 5 :(得分:0)

当您放置c+1时,它不会更改c的值,但++c会更改c的值...作为差异的示例前后增量运算符:

int a = 1; 
int b = ++a; 
// Now a is 2 and b is also 2. 

int a = 1; 
int b = a++; 
// Now a is 2 but b is 1.