Tutorial 14
👉
Pointers
9618 A-Level
A pointer is a reference to a memory address - for example, rather than storing the value of a variable, a pointer would instead store the memory address of that variable or object
They are analogous to and implemented via indirect addressing in assembly - e.g. the register transfer notation [MAR] is pointing to the address stored in the MAR
In pseudocode, we just look at some basic, not particularly realistic examples of using pointers - some low-level languages like C, C++, Rust, Go etc make extensive use of pointers
Other, mid/higher-level languages like Java, Python, VB, C#, PHP, JavaScript etc handle pointers for us automatically - for example, when passing an array or other object as an argument to a module, a pointer to that array/object's memory address is actually passed under the hood, rather than the data itself (an array could have millions of elements - copying and passing that to a module would be slow and would ultimately cause stack overflow errors, hence why a simple integer pointer is passed instead)
The benefits of using pointers include
- Improved performance - as stated above, when passing arrays/objects around, it's quicker/uses less memory to simply pass a pointer reference to that object's location in memory, rather than copying the entire array/object
- Allows direct memory access - we can access specific memory addresses, for example setting a particular flag at a pre-determined memory address (like 0x000000FF) on an embedded device to change its behaviour
- Pointer arithmetic - we can add or subtract specific offsets to points to go to a specific element in an array/buffer
- Creation of dynamic data structures - in most implementations, dynamic (i.e. non-fixed size) data structures like a linked list or binary tree will be stored non-contiguously in memory - we don't know if there will be 1 node in the structure or 1 million, hence we can't pre-allocated the memory for all nodes. The fact that nodes will be scattered throughout memory means we need pointers to point to the next/child nodes etc
- ...etc...
As stated, for A-Level, we only have to look at declaring and doing simple operations with pointers, nothing too complex
Note: pointers are an advanced concept - if you try creating pointers to something crazy objects like a class containing an array of records, the site will almost certainly break. You can contact me if you find any bugs and I will try and fix them
1
Defining & Declaring Pointer Types
To create an instance of a pointer is a two-step process, much like it is for defining and declaring an instance of a record, class, set etc
- first, we have to define a pointer type corresponding to the data type we are pointing to - note how we use the carat ^ to mean "points to" - i.e. this custom IntegerPointer that we define below will point to an INTEGER variable
- then, we should create an instance of that pointer type
2
Referencing a Variable
Pointing a pointer to a variable is called referencing and is achieved with the referencing operator ^ in front of the variable name as seen below
Now, if we update the value of our num variable, when we come to dereference the pointer (go down to next example), it will evaluate to be this new value
3
Dereferencing a Variable
If we try to simply output a pointer like OUTPUT p1 in the example above, the site will give us this error
Can't OUTPUT pointer "p1" that points to num. Use the dereferencing operator p1^ to get the value in the variable the pointer points too
To dereference a pointer (or, in simple terms, get the value stored in that variable/memory address), we place the carat ^ after the variable name that we are dereferencing
Note that since p1 points to num, then when we assign new values to num, dereferencing p1 will also evaluate to the new value, since it's always pointing to the same memory address, even as the value in that memory address changes
Let's see another example of pointing to the first character in a string
...or how to point to a date object
...or how to point to a custom object like an enum
4
Swapping Pointers
We can swap pointers, as shown below, by simply changing the variables they reference
5
Pointer Arithmetic - Arrays
Often, we want to perform arithmetic on pointers - for example, if we have an ASCII string, since we know each character uses 1 byte, we can add 10 to the char pointer to go 10 characters forward - subtracting 5 would of course move 5 characters back
In the example below, we will see how to add to pointers to populate the 3rd value of the Fibonacci sequence - further down the page will be a challenge to populate the entire array using a loop
6
Point to Max Value in Array
Create a program that will loop through an array of integers, then update a pointer to point to maximum value in the array
7
Outputting Pixel Values
Suppose we have an array of 12 integers ([255, 150, 180, 172, 43, 98, 209, 136, 83, 47, 18, 115]), representing 4 rgb pixels - i.e. the first 3 integers represent the rgb values for the 1st pixel, the next 3 values represent the rgb values for the 2nd pixel and so on
Using pointers, create a program that can point to the first value in the array, output the rgb values for that pixel, then update the pointer and move to the next pixel, outputting that, until all pixel values have been output
8
Decipher Message
You have the ciphertext pedcdporeoous - you are told the way to decipher the message is as follows
- Create a start pointer pointing to the beginning of the string and an end pointer pointing to the end
- Concatenate the first character to the plaintext string, followed by the end character
- Then, move each pointer 1 index towards the middle - i.e. increment the start pointer and decrement the end pointer
- Repeat until all characters have been added to the plaintext string
- Output the plaintext string to reveal the encrypted message
9
Fibonacci Sequence
Adapt the code from the Fibonacci array sequence example above to loop through, populate, then output the first 10 numbers in the Fibonacci sequence