char str[16];
isn't a pointer, it's an array of 16 characters. A array is a block of contiguous things in memory, a pointer is a variable that contains the address of something else.
Where you might be getting confused is that the name of an array is synonymous with the address of the first element of the array. So you can use the name of an array to initialise or assign to pointers.
So if you have a pointer you can use array style indexing on it, but if you have an array name you CAN'T do pointer style assignment on it. If you do something like:
char str[16];
char *p = str;
str and p refer to the same location in memory. You can then do something like:
p++;
and
p
will now point to the memory location of
str[ 1 ]
. However if you try:
str++;
the compiler will tell you take a walk as you can't modify the value str represents, it's a constant (it's an rvalue in standard speak if you ever try reading it, at least in C90, not sure about C99).
So the differences between array names and pointers are:
- pointers contain addresses
- array names are addresses
- doing a sizeof array_name gives you the number of bytes in the array
- doing a sizeof a pointer returns the number of bytes it takes to hold an address on your system
Now there's another source of confusion. When you pass an array to a function the compiler takes the address of the first element in the array and converts it to a pointer. So when you see a function prototype like:
void test( char b[ 20 ] );
you can read it like:
void test( char *b );
and if you do a sizeof on b within the function it'll come back as 4 or 8 (perhaps 2 on very old or embedded systems) depending on you compiler.
So we can add to the rules a bit:
- pointers contain addresses
- array names are addresses
- doing a sizeof array_name gives you the number of bytes in the array
- doing a sizeof a pointer returns the number of bytes it takes to hold an address on your system
- read all array names passed to functions as pointers within the scope of that function
Cheers,
Ash