Q:

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 just experimenting at the moment.  Thanks!

A:

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

A:

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) { /* ... */ }

A:

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.

