canucksfan96 canucksfan96 - 1 year ago 134
C Question

Simple C pointer confusion

I'm stuck with this question, and need to understand what's going on each line step-by-step. The first two lines I do understand, but the problem comes at line 3 and 4. Also, what's the difference between the two different print statements?

int a[] = {11, 22, 33};
int *p = a, *q = a + 1, *r = a + 2;
*p++ = *r--;
*++q = *r--;
--*p; ++*q; --*r;
printf("%d %d %d", a[0], a[1], a[2]);
printf("%d %d %d", *p, *q, *r);

Answer Source

A simple way to explain what each line does is to expand it into equivalent code that is easier to parse when you are not too familiar with pointers and pre/post increment:

// *p++ = *r--; 
*p = *r;  // copies value in r over to p
p = p+1;  // then increments p, so it now points to a+1
r = r-1;  // and decrements r, so it points to a+1 too

// *++q = *r--;
q = q+1;  // q now points to a+2
*q = *r;  // places value at a+1 in a+2
r = r-1;  // decrements r, so it points to a+0

// --*p; ++*q; --*r;
*p = *p-1; // decrements value at p, that is, a+1
*q = *q+1; // increments value at q, that is, a+2
*r = *r+1; // decrements value at r, that is, a+0

// displays values at a+0, a+1, and a+2
printf("%d %d %d", a[0], a[1], a[2]);

// displays values at a+1, a+2, and a+0
printf("%d %d %d", *p, *q, *r);

If the pre increment/decrement is before the *, then you are modifying values at the position pointed by the pointer; if it is after the *, then you are changing where the pointer points to. In the case of post increment/decrement expressions, you need to use parenthesis if you want to modify values: *p++ changes what p points to and evaluates to that value, (*p)++ changes the value pointed-to by p.

As a fun** exercise, the following code, from The C Programming Language, copies a zero-terminated string from location t to s:

void strcpy(char *s, char *t) {
   while (*s++ = *t++);

** your idea of fun may differ from K&R's. Use of strcpy has been proven to cause buffer overflows and premature baldness - use strncpy instead.