Pointers
C provides an extremely nice way to access memory via pointer variables. The declaration looks like the following
void *var;
The asterisk before the variable denotes that it’s a pointer variable. A pointer variable stores address of some memory location, typically a variable or a newly allocated memory area.
We know how to declare arrays, let’s take a look at how we can use pointers to traverse the array. We’ll be using a character array and a pointer to a character to traverse the array.
int main() {
char str[] = "Hello World";
char *str2 = str;
while (*str2 != '\0')
printf("%c", *str2++);
return 0;
}
In the above code, we’ve created a character array and then assigned a pointer to it’s base address. The while condition checks the value at the address contained in pointer variable for being null.
Pointers and References
C++ allows us to have references which work mostly like pointers however there’s a very basic and subtle difference. Pointers are first class variables that is they have their own memory location where an address can be stored, while references don’t have their own memory location.
Thus references can’t be uninitialised pointers can be since they are first class variables. This is shown in the table below
Syntax | Description |
---|---|
void *ptr = NULL; | Valid since ptr will have it's own memory location. |
int &ref; | Invalid since references aren't allocated separate memory location. It's just another name for an already existing variable. |
Generic Pointers
A pointer always points to some type at a location. However sometimes it’s necessary to write code where the pointer variable required is generic, i.e any type. This is achieved by creating a void pointer.
Sizeof a pointer variable
The pointer variable is always fixed in size and it’s size is machine’s word size. The machine’s word size is denoted by the data type long. This fact is very important since it helps us creating data types that references themselves. For example, while the following piece of code is correct
struct linked_list { struct linked_list *next; void *data; };
struct linked_list { struct linked_list next; void *data; };
Pointer Arithmetic
Pointers like other variables can be used for some arithmetic operations however not all arithmetic operations are valid for pointers. For example the following table shows what all arithmetic are possible
Syntax | Description |
---|---|
ptr + constant | Addition of a constant to a pointer. |
ptr - constant | Subtraction of a constant from a pointer variable. |
ptr + non_pointer_variable | Addition of a non-pointer variable to a pointer |
ptr - non_ptr_variable | Subtraction of non-pointer variable from a pointer. |
ptr1 - ptr2 | Subtraction of 2 pointers. |
All other arithmetic operations like division / multiplication involving pointer variables isn’t allowed.
Addition/Subtraction involving pointers
When a value is decremented or incremented from a pointer variable the pointer is incremented or decremented by the size of type of value the pointer points to. For example
Syntax | Description |
---|---|
char *ptr = 0x1234; | Moves ptr to location 0x1235 |
short *ptr = 0x1234; | Moves ptr to location 0x1236, since adding 1 moves to the next of the type pointed to by ptr. |
int *ptr = 0x1234; | Moves ptr to 0x1238, i.e next int which is 4 bytes away from initial location. |
int *ptr = 0x1234; | This is invalid since the type of pointers being decremented must be pointing to same type. |
Reading pointer declarations
The general rule of reading pointer declarations is to start from the pointer variable and then move to right and then move to left building up the declaration. We’ll start with simpler ones
Syntax | Description |
---|---|
int *ptr; | Start from the variable, move to right. We find a delimiter so move to left. We see a * thus it becomes ptr is a pointer we continue moving to left and find int, thus ptr is a pointer to int |
char *ptr[]; | Start with ptr and move to right, we see [], so ptr is an array Next move to left and we find a *, it becomes ptr is an array of pointers we continue moving left and find char thus, ptr is an array of pointers to char |
char (*ptr[])(); | From previous example, we see that ptr is an array of pointers however, we've to stop whenever we see a paranthesis. The parenthesis to the right denotes function therefore, ptr is an array of pointers to function then we move left and see char ptr is an array of pointers to function returning char |
| ptr is a pointer to const character. That is the pointer can be changed but the value it points to can't. |
| Again using the same rule, ptr is a constant pointer to a character That is to the value can change but the pointer variable can't be changed i.e. it always points to fixed variable. |
Pointer Tricks
Syntax | Description |
---|---|
*ptr++ | Give the value first then increment pointer. |
*++ptr | Increment the pointer first then give the value from the new location. |
(*ptr)++ | Increment the value pointed to by ptr. The pointer itself isn't incremented. |