C - Off by one error
in the following simple reverse function I'm always off by one, meaning the first character passed in is never printed last like it should be:
void reverse(char * c)
{
if(*c != '\0')
{
reverse(++c);
printf("%c", *c);
}
else {
return;
}
}
yet when I change the call to reverse to be c+1, everything works fine. Any ideas as to why, the unary pre-increment operator should be doing exactly the same as c + 1. I know a recursive function isn't the best performing way to go about this problem but I'm jus开发者_开发知识库t experimenting at the moment. Thanks!
Because c+1
does not change c
whereas ++c
does.
Think about this when c
is pointing to address 1234
:
reverse(++c); // c is now 1235 and you pass that.
printf("%c", *c); // so we print the second character at 1235.
With the c+1
version:
reverse(c+1); // c is still 1234 but you pass 1235.
printf("%c", *c); // so we print the first character at 1234.
For what it's worth, your reverse
function is needlessly complicated.The else return
is redundant and I personally prefer recursion calls that check terminating conditions first since I've often found these are usually easier for compilers to do tail-end recursion optimisations on.
The following complete test program shows you the way I'd do it:
#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;
}
Running this with testprog hello goodbye
gives you:
olleh
eybdoog
No the unary pre-increment is not the same like addition by one.
f(++c)
is equivalent to
c = c + 1
f(c);
whereas f(c+1)
is equivalent to
auto d = c + 1;
f(d);
And just for completeness: f(c++)
is the same like
f(c);
c = c+1;
However sequence points matter, e.g. if(c++ > 0 && c++ < 10)
would evaluate like
auto a = c;
c = c + 1;
auto b = c;
c = c + 1;
if(a > 0 || b < 10) { /* ... */ }
and consequently preincrement
c = c + 1;
auto a = c;
c = c + 1;
auto b = c;
if(a > 0 || b < 10) { /* ... */ }
Calling with c + 1
won't change the value of c
in the local context (the one used when printing *c
), but using ++c
in the call will.
No, it doesn't do the same thing.
It increments it then sends it to your function.
when you put c+1
, it doesn't change the value of c
, but ++c
does change the value of c
.. as an example for difference between pre and post increment operators:
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.
FIXED: You shouldn't use increment operator. Operator+ would be better.:
reverse(c + 1);
printf("%c", *c);
精彩评论