I believe that my series is getting complex with every post being published! This has to be done because we should also be getting more complex and more logical with every topic we discuss.
Today’s topic is References. Before proceeding on, let us discuss few problems with functions. The first one is that we don’t know any methods of getting multiple outputs. The second one is that we don’t make any change in the variable that we pass into the function via parameters.
The following code expresses the second problem with functions:
void multiplyBy2(int variable)
variable *= 2;
int variable = 2;
mulitplyBy2(variable); //This should change the variable's value to 4
cout << variable << endl; //Prints 2, not 4
NOTE: We can have same names for variables having completely isolated scopes. Note that
multiplyBy2 has a parameter called
variable and main function also has a variable called
variable. Sounds confusing!
We have a solution for that and that is, to return that variable in the function and then, put that into any variable or just call that temporary return value directly.
But we expect the method above to change the variable’s value which is not the case here! Why? Well, the point is that when we pass the variable via the parameter of the function, we are actually copying that variable into another completely new variable. This new variable has a very limited scope i.e we can only access it inside the function.
Let us discuss a very simple example of what copying is:
int value1 = 2;
int value2 = value1; //Here, value1 is copied into value2
value2*=2; //value2 is a different variable; it will not effect value1 in any case!
cout << value1 << endl; //Prints 2, not 4
cout << value2 << endl; //Prints 4
The highlighted codes shows what is actually happening in the function,
multiplyBy2() in the example, given above.
How to do it in the way that we want? The answer is right inside the topic of this post: References. There is another way and that one is through Pointers which is way more complex but we will discuss it later on.
What is a reference? Reference is just another name given to the same variable. In our real life, we can have the reference case of a bird called ‘raven’. Raven is a black bird. So, people can refer to ‘raven’ by calling it as ‘black bird’. In a very similar way, variables can have references as well.
//Consider that there is a bird called 'raven'
int raven = 10;
//That 'black_bird' is a reference to 'raven'
int& black_bird = raven;
//Now, what we do with 'black_bird' is actually,
//what we are doing with 'raven' as well and vice versa...
black_bird*=2; //Both gets 20
raven+=5; //Both gets 25
cout << raven << endl; //Prints 25
cout << black_bird << endl; //Prints 25
The highlighted line shows how to make reference to a variable. It is pretty simple; just put ampersand or ‘&’ after the type of the variable that we are going to refer to.
int& is considered a type which we can call as ‘reference to an integer’. Same will be for any type reference as well.
Time to make some change in the
//Notice the ampersand before the variable's name
void multiplyBy2(int& variable)
variable *= 2;
int variable = 2;
mulitplyBy2(variable); //Now, we are not copying, we are referencing!
cout << variable << endl; //This time, it prints 4
Now that, the second problem is solved, the first problem is solved as well. We can have multiple outputs by having more parameters to the function. These parameters are going to be references and whatever is going to be changed with these references, this change is going to happen with the actual variables which are passed as parameters in the function.
//The first two parameters represent inputs
//and the next three represent outputs
void get3TimesDivision( float number1, float number2,
float& division1, float& division2, float& division3 )
division1 = number1 / number2;
division2 = division1 / number2;
division3 = division2 / number2;
//Multiple Outputs using References
float div1 = 0.0f, div2 = 0.0f, div3 = 0.0f;
get3TimesDivision( 8.0f, 2.0f, div1, div2, div3 );
cout << div1 << endl; //Prints 4
cout << div2 << endl; //Prints 2
cout << div3 << endl; //Prints 1
Note the point that where we want to have references, we cannot have constants or temporary values there. In the above case, if the parameters,
number2, are references to
float, we cannot pass 8.0f and 2.0f into the function. We must pass variables of type
float with the respective values, into the function.
That’s all! References are a great way to deal with outputs. Just try to modify all the previous functions that we created together, to have references and not copies. Practice them very well. They are going to be used extensively!