So you want to understand pointers? Well buckle in ... Here we go.
In short, Pointers are just memory addresses. What does that mean for the unintiated? Well to understand that you first need to understand memory in the abstract sense. Memory is just a big array. Each byte in memory has its own index/address. For example there might be a byte somewhere in memory at say address 16 (or 0x10 in hex). To access it in C (this assumes no virtual memory and our program is running at ring 0, more on that later) we need to do:
char* pointer = 16; // Or 0x10
Hint for unintiated: char is the character type in C. It is usually defined as the same size of a byte on most architectures so we can use it in place of a byte type because that dosen't really exist in pure C89.
This stores the index of the byte in a variable called pointer. The pointer points to a char as denoted by the type and it is a pointer because we put a * at the end of the type. We now have a reference to our byte. So what can we do with it. Well we can dereference it! Like so:
*pointer = 64; // Here we are setting the byte pointer points to as the value 64 printf("%d\n", *pointer); // We can read it as well! Lets print it out
You can dereference a pointer by putting a * in front of it. Since the type of pointer is char* when we put the * in front it loses its * and becomes type char. Since it was pointing at the byte at address 16 and *pointer now becomes the byte at address 16. We can now just treat it as a regular old byte and do whatever we want to it. In the example above we just set the value of the byte to 64 and print it out. The program will print out 64.
Of course this is a simplified example. We cannot just access arbitary memory locations because OS hasn't given us permission to. So you won't really be setting random addresses as pointers. Let's get a pointer to a memory location that we actually have access to:
#include <stdio.h> int main() { int some_int = 12; int* pointer = &some_int; *pointer = 24; printf("%d\n", some_int); }
Unlike the old code, You can actually run this program! Try pasting it into a file andcompiling it. Play around with it as much as you want.
Here we create a integer on the stack and set its initial value to 12. When we want to get the address of the integer we can put a '&' in front of it. After grabbing the address we store it in our pointer convieniently named pointer. When we set *pointer to 24 what we are really doing is setting some_int to 24. When we print it out we will get 24 and not 12!
Ok, but why is this ever useful?
In the above example we can easily just access some_int directly. What if some_int wasn't in scope?