在下面的简单反向函数中,我总是一个接一个,这意味着传入的第一个字符永远不会像最后一样打印出来:
void reverse(char * c)
{
if(*c != '\0')
{
reverse(++c);
printf("%c", *c);
}
else {
return;
}
}
然而,当我将反向调用更改为c + 1时,一切正常。任何想法为什么,一元预增量运算符应该与c + 1完全相同。我知道递归函数不是解决这个问题的最佳表现方式,但我现在只是在试验。谢谢!
答案 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.