Regarding Example 1.4:
Code:
#include <stdio.h>

int main() {
    int n[5] = {1,2,3,4,5};
    int *ptr;

    /* points to n[0]*/
    ptr = &n[0];
    printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);

    /* points to n[1] */
    *(ptr+1); /* this expression references n[1], but ptr remains the same */
    printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);

    /* points to n[2] */
    (*ptr)++; /* this increments what ptr is pointing to, and ptr remains the same  */
    printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);

    /* However, increments the value of the content of the location pointed by ptr */
    ++*ptr; 
    printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);

    return 0;
}

/* my output
ptr now points to n[0] whose value is 1
ptr now points to n[0] whose value is 1
ptr now points to n[0] whose value is 2
ptr now points to n[0] whose value is 3
*/