With regards to Stephen's earlier post asking about some pointers on pointers in a revision lecture, I thought it would be an interesting exercise to explain how things work by doing some unusual things in C.
I'm going to try and help by providing a couple of facts about C/C++ in line with the revision topics Stephen suggested in the hope that people will read them, understand them, and go "hey, that's quite cool" (Even if you don't admit it).
An array is just a pointer to the first item in that array. The type that the array is defined as tells the compiler what the 'stride' is between items.
Let's just prove this a second with some scary code!
Read that, and work out what the output is going to be based on the above information. I'll give you a second of text here and warn you I'm about to write the answer.
Ok, I made it a bit obvious, the above code will output 'A' to the console. If you're confused, then read on while I explain, then look at the example again until you understand.
Remember what I said above, that an array is just a pointer to the first item in that array.
char cake[10]; is just char* pCake = new char[10]; with the added bonus of having the data placed on the stack where it will be cleaned up automatically when it goes out of scope!
So:
Achieves effectively the same as:
(Of course, attempting to delete the stack based 'cake' will result in a memory violation, and forgetting to delete the heap based 'pCake' will result in a memory leak).
Now, because these are effectively the same, with the exception of re-assignment or deletion, whatever you can do to one of them, you can do to the other!
Consider the two functions outlined below:
Again, these are exactly the same. Personally I would never use Function Declaration Two, because I like honesty - and Function Declaration One is saying "Look, I want a pointer" - and because arrays ARE just pointers, you can always use that pointer as if you would an ordinary array!!!
So, assume we have a method body for Function Declaration One, and a program which uses it:
Note how the 'Array' and the 'Pointer' are interchangeable.
I've rambled on now, but with the above knowledge in tow, the first code sample shown becomes very obvious.
We've defined an array of characters, which as we know is just a pointer.
char cake[10];
We then declare a pointer, and assign it the value of cake + 5
char* pCake = cake + 5;
Think about what we've actually done there. Cake is just a pointer, and we've added 5 strides (a char is only one byte in size, so that's 5 bytes if you're really that interested!) to that pointer. A functionally equivelant bit of code would look like:
char* pCake = &cake[5];
That of course, is a bit of a long way around. Using those square brackets is just a shortcut to 'dereference' the pointer.
cake[5] is exactly the same as doing *(cake + 5)
So, pCake is just a pointer to the middle of the original array! You could quite easily write:
int valueOne = *(pCake-5);
Although you'd be mad to do so.
The rest is history of course. Because pCake[0] is dereferencing a pointer to the middle of cake ( or cake[5] to you and me ), we get the value from that location.
Open up a compiler, and play with the above code until you understand what I'm going on about. If you can get your head around this post, and these concepts, then you'll find that pointers aren't as scary as they seem. ;)
I'll make a post about dereferencing pointers to complex types (classes) later today when I have time.
