Sometimes in programming, things don`t work the way you think they should. This can be frustrating.
However, as tempting as it is (especially when one is relatively inexperienced) to suspect your computer of playing up, this basically never happens.
Take the below example
Functions are so fundamental in programming that any nuances must be firmly grasped before moving on. We might expect the output to be
The value of a is 7
when in fact it is
The value of a is 2
increase are unrelated to
main; what`s happening is something called pass by value.
In many languages (C++ and Java included), functions with primitive arguments (integers, floats, characters, booleans, etc.) pass their arguments by value. This means when the function is called, it copies its arguments.
increase creates two local variables,
b in a part of the computer’s memory called the stack.
main are supplied as arguments to
b) on the stack is assigned the value of
increase then does its work, leaving
a on the stack with a value of
Once all the lines in its body have been executed, its work is done. The stack is popped, i.e. everthing on it relating to
increase is cleared from memory, and is no longer accessible in the program.
At no point have
How can we get our expected output? We could use pass by reference.
In C++, this can be done in two ways. We can add
& to the function’s definiton like so
Now, instead of creating a new variable
a on the stack, the variable entered as the first argument is simply given a second name,
a (here it is a bit silly as both names are
increase modifies the value of
a, it is modifying the actual variable that was entered as the first argument.
The second method is to use something called a pointer.
A pointer is a variable whose value is the address of another variable (every variable you declare has an address, i.e. a number corresponding to a location in the computer’s memory).
The above shows two usages of the asterisk symbol. In the first line of the function definition,
a is a variable of type
i.e. the value of
a is the address of another variable whose value is an integer.
In the second line,
the asterisk symbol is used to say to the computer
apoints to an integer. What I want is not the value of
a(an address), but the value of the integer that it points to.
This is known as dereferencing the pointer.
increase takes this value and increases it by
When we call
main, the first argument is the address of
a, written as
and the value of
a is increased to
Can we use these two methods in any language or are they specific to C++?
In C, we can only use the second method.
In Java, we can use neither as Java does not allow direct access to the computer’s memory. The closest solution in Java is to use a class variable via the keyword
In the last line we could also have written
Doing so is longer but makes more explicit that
a is a class variable rather than a regular attribute.
However, this kind of thing is frowned upon as class variables were not made part of the language to do things like the above.
Java, unlike C++, is designed to accommodate only a single paradigm, that of object-oriented programming. To better respect this paradigm, one should either make
or make use of objects.
This is because in Java, functions with object arguments pass them by reference.
Take the example of arrays, which in Java are considered as objects. If a function has an array as an argument and alters its value, the modification is permanent and is reflected in the rest of the program.
One of the advantages of pass by reference is that computing time and space are not wasted by pointless copying of variables.
If the variable is of a primitive type then this is not an issue. However, if it is, for example, a large array then copying that array can be costly. This is something I discovered when writing Java and C++ solutions to Problem 29 of Project Euler.
The Java solution took around 2 seconds whereas in C++ the implementation of the same solution did not return anything after a minute.
However, once functions had been changed to pass by reference, a solution was returned after 8 seconds (although given that C++ is supposed to be faster than Java, these extra 6 seconds are something of a mystery to me).