You're familiar with how to declare a pointer:
But it looks like initializing a pointer at the definition is confusing you. This is no doubt because declarations are designed to resemble use. The declaration above does not dereference anything, the asterisk is only saying that p is a pointer to char. When you initialize p in the same statement:
Code:
char buffer[10] = "testing";
char *p = buffer;
There is still no dereferencing going on. The asterisk is only used for the declaration of p, then buffer is assigned to p. The result is that p points to the first element of buffer, you could write it equivalently like this:
Code:
char buffer[10] = "testing";
char *p;
p = buffer; /* Or p = &buffer[0]; */
This is a subtle and confusing issue with C's declaration design. Just remember that when you initialize an object, you're initializing the object that was declared. p is declared as a pointer to char, so any initialization will be assigning to a pointer to char, not to a char.
Also note that p does not point to an array. It points to a char that simply happens to be part of an array. If you want to point to an array then a different declaration is required:
Code:
char buffer[10] = "testing";
char (*p)[10];
p = &buffer;
The parentheses guarantee that p is a pointer to whatever is outside of the parentheses, an array of 10 char.
As long as you point to memory that is contiguous and that is in your address space, you can increment and decrement pointers:
Code:
char buffer[10] = "testing";
char *p;
p = buffer;
p++; /* p now points to &buffer[1] */
p--; /* p now points back at &buffer[0] */
You'll often see somebody dereference and increment or decrement with the same expression:
Code:
printf ( "%c\n", *p++ ); /* Prints 't', p points to &buffer[1] */
printf ( "%c\n", *p-- ); /* Prints 'e', p points to &buffer[0] */
You can force the increment to be performed first by using prefix notation:
Code:
printf ( "%c\n", *++p ); /* Prints 'e', p points to &buffer[1] */
printf ( "%c\n", *--p ); /* Prints 't', p points to &buffer[0] */
There, that should be enough setup.
>So you point to the next location right?
Yes.
>Or are you saying i'm changing the actual value at that location?
No, the pointer and the value being pointed to are different.
>why though?
*p++ and *(p++) are equivalent. The parentheses don't do anything meaningful because the postfix increment still works the same way: It copies the current value, increments the pointer, then gives the copy to the rest of the expression to work with. Either way you'll be working with p and incrementing to p + 1. This isn't why your code didn't work.
>however this code seems to be indentical and it works
No, it does the same thing. It writes a word into str and returns a null character because a reference to the beginning of the string was not saved or calculated. Run the function like this and you'll see:
Code:
char buffer[BUFSIZ];
printf ( "%s\n", getword ( buffer ) );
printf ( "%s\n", buffer );
It will print nothing on the first line, then the first word you typed on the second.
>when you increment *p++ isn't that incrementing buffer as well?
No, they are two different pointers that just happen to point to the same address. When you increment p, buffer still points to the same location that it did before you incremented p. p and buffer are different objects even though the address they point to is the same.
>it always goes to the biginning of that block of memory right?
How do you define the beginning of a block? It's solely dependent on the logic of your program, so pointers cannot magically move to the beginning of a block unless you explicitly tell them to.