Note: This is not meant to teach you how everything works under the hood. This is just for understanding the syntax of pointers and for giving good intuition on how to read and write code which utilizes them.
Anyways,
I was going through some old notes and found a bunch of stuff I wrote about pointers and remembered I had an account on here and figured "why not throw something out there", so here ya go.
Terminology
Pointer: A variable which holds the address of another variable.
Reference: Setting a pointer to equal the address of a variable.
De-Reference: Reading or Writing to the value at the address pointed to by a pointer.
Examples
Modifying a variable via pointer
int variable_to_be_changed = 1; | |
// Hold the address of another variable. | |
int *pointer_to_variable; | |
/* Point to the value at the address of variable_to_be_changed | |
('Reference' variable_to_be_changed) */ | |
pointer_to_variable = &variable_to_be_changed; | |
/* Set the value at the address pointer_to_variable is pointing to | |
to be equal to 0: ('De-Reference' pointer_to_variable) */ | |
*pointer_to_variable = 0; | |
printf("%d", variable_to_be_changed); // Prints 0. | |
/* | |
So in essence: | |
* is "point to the value at the address of some variable" | |
& is "address of some variable" | |
With the above in mind: | |
int one = 1; | |
int *ptr = &one; // Point to the value at the address of one. | |
*ptr = 0; // Set the value at the address ptr is pointing to be equal to 0. | |
*/ |
Passing by Reference vs Passing by Value
/* | |
To pass by reference is to pass the address of a variable | |
into a function as an argument, so that the original value | |
of the variable being passed can be read/written to. | |
To pass by value is to pass a copy of the value of a variable | |
into a function, so that the original value of the variable | |
being passed is preserved. | |
*/ | |
int number_to_change = 12345; | |
int number_to_keep = 12345; | |
void pass_by_reference(int *address_of_variable) { | |
*address_of_variable = 54321; // Set the value of the address passed to be 54321 | |
} | |
pass_by_reference(&number_to_change); // Pass the ADDRESS OF number_to_change | |
void pass_by_value(int value_of_variable) { | |
value_of_variable = 54321; // Set the copy of the value_of_variable to be 54321 | |
} | |
pass_by_value(number_to_keep); // Pass the VALUE OF number_to_keep | |
printf("%d\n", number_to_change); // Prints 54321 | |
printf("%d\n", number_to_keep); // Prints 12345 |
Pointers to Pointers
// Think about what a pointer means: | |
int one = 1; | |
int *pointer_to_one; // Store the address of an int/Reference an int | |
pointer_to_one = &one; // Store the address of 'one'/Reference 'one' | |
// So, | |
//Store the address of a pointer to an int/Reference a pointer to an int. | |
int **pointer_to_pointer; | |
// Store the address of 'pointer_to_one'/Reference 'pointer_to_one' | |
pointer_to_pointer = &pointer_to_one; | |
// Therefore, | |
// The address of num, since the value of pointer_to_one is going to be the address of num! | |
printf("%p\n", *pointer_to_pointer); | |
// Prints 1, since the value is going to be what is at the address of 'one' | |
printf("%d\n\n", *pointer_to_one); | |
/* | |
Prints 1, since the value is going to be *(*pointer_to_pointer) which means | |
"Point to the value of what a pointer is pointing to", and since *pointer_to_pointer | |
is the address of num, this would equate to: "Value at the address of num". | |
*/ | |
printf("%d\n", **pointer_to_pointer); |
Pointer Arithmetic
// Suppose you have an array of ints: | |
int array_of_ints[5] = {1, 2, 3, 4, 5}; | |
// Now, you have a pointer, and you want it to point to this array. | |
int *pointer_to_array = &array_of_ints; | |
// Pointer_to_array is only going to be pointing to the first element, 1. | |
printf("%d\n", *pointer_to_array); // Prints 1. | |
// So in order to get to the rest of the elements in the array: | |
for (int i = 0; i < sizeof(array_of_ints) / sizeof(int); i++) { | |
printf("%d\n", *(pointer_to_array+i) ); | |
} | |
/* | |
Which is taking the address currently being pointed to, adding 1 to it to | |
progress it to the next element in the array (since in memory, array elements are | |
side by side), and then printing it. | |
So in essence, what *pointer_to_array+1 means is | |
"Take the address stored in this pointer, and add 1 to it to get to the | |
location in memory to the right of it." | |
Since this is an int pointer, adding 1 to it is going to be pointing to the next | |
address in memory 4 bytes relative to the current position, | |
since ints are (commonly) 4 bytes. | |
*/ |
Quick Note About Multiple Pointers in One Line
// Quick note about pointer declaration: | |
int* pointer, pointer2, pointer3 | |
// IS NOT what you think it is. What this actually means is: | |
int *pointer; | |
int pointer2; | |
int pointer3; | |
/* Only the first one is a pointer. The rest are ints. | |
In order to inline declare multiple pointers, you would do: */ | |
int *pointer1, *pointer2, *pointer3; |
References Used
https://denniskubes.com/2017/01/24/the-5-minute-guide-to-c-pointers/
https://stackoverflow.com/questions/14224831/meaning-of-referencing-and-dereferencing
https://www.studytonight.com/c/pointer-to-pointer.php
https://stackoverflow.com/questions/11598361/why-a-pointer-1-add-4-actually
In Closing
There you go.
This was pretty fun to write up. Maybe I'll do some more little
primers like this. Hopefully someone found it useful, as
this is all admittedly pretty elementary.
Top comments (0)