Explore References
References provide a means to indirectly access a variable - creating a variable that is an alias that can be used to refer to another variable or value in memory.
Why is this useful?
This isn’t useful if you think about the code within a single function or procedure, but it becomes very useful when you think about using it within parameters or more complex data structures. For the moment, let’s explore how we can use these with parameters to create procedures that update data for us.
Account database
For this example, lets walk through creating a simple account database. This database can keep track of usernames and their associated system role.
The first step, as always, should be to think about the entities we will need within this program. We can start in this case with users and roles. Have a think about how you would represent these, and the coding structures you would use for this.
Make sure your user has at least a username, password, and permission level. Have roles: no access, user, admin, and super-user.
Once you have a plan, have a go at creating this in a new project file. We can make use of the utilities we created earlier to make it easier to read and write values via the terminal.
-
For this I modelled a user using a struct, and the permissions using an enumeration.
Struct user_data Fields username
: A string representing the user’s usernamepassword
: A string representing the user’s passwordrole
: The level of access they haveWe can use an enum to model the role levels.
Enum role_level Values NO_ACCESS
,USER
,ADMIN
,SUPER_USER
You should be able to code these yourself by now, but if you get stuck you can have a look at the code below.
Here is what I created for the role level and user data. Notice we have to declare the role level before the user data.
Create functions to support types
Along with the data types, we will need to create some functions and procedures to work with these. For this example, all we should need are the following:
- A
read_role
function to read a role from the user and return it to the caller. to_string
function to convert a role level to a string value.print_user
procedure to output the details of a user. Showing their username and role.
You can then test this with something like the following main
. Make sure to adjust the struct name and enum values if you used different things in your version.
-
This is a partial solution - if you can’t create your own see if you can extend this to match the full features described for this program.
Use references to update a user
Now that we have the main building blocks in place, we can add an update_user
procedure. Update user can be passed a user by reference, allowing it to update the user data by accessing it via a reference. This reference is an alias of the argument passed to it. When you read or write to this variable, you are indirectly accessing the data in the variable that was passed to this as the argument.
Procedure | update user |
Parameters | user : The user data to update - passed as a reference to a user data value |
Description | Allow the user to update the username, password, or role of the user data passed in |
Have a go at implementing this. For the moment, have this print out the user’s details and then update their username. Test this using the following main, and you should see that the changes you make in update_user
are actually made to the user
variable in main. How? The parameter is a reference (alias) of the argument passed to it. So when you read or change this value, you are actually reading or changing the value in main
.
When you have this basic version working, have a go at extending how update_user
works. Inside update user, you could print out the user data then ask the user which value they want to update. Based on what they select, you then get the computer to read in a new value from the user and update the appropriate field in the user. This could loop until the user chooses to exit.
-
This is a partial solution - if you can’t create your own see if you can extend this to match the full features described for this program.
The ability to use pass by reference can really help you break up your code. You can now create procedures where you pass in a reference to the data that needs to be changed, which was something that is not possible without references (or pointers).