Folder101   Home Notes Quiz Assigns Info  
Forum Forum
101 Home 101
 
  C++ Level 2

Organizing Code in Functions

Introduction

Call by Value

Call by Reference

Extension Work


  Introduction

You have learn't a little bit about functions previously; how to declare functions, function prototypes and function parameters.

This tutorial looks in more detail at passing arguments to a function. You will see that there are two ways that functions can be passed arguments - by value and by reference.


  Call by Value

Just to refresh your memory, the general form of a function is as follows:-

type_specifier  function_name (parameter list)
   {
       function body
   }

As an example, here is a function that adds two numbers.

int add(int a, int b)
{
   return a + b;
}

In this case the type_specifier is int, which means the function returns an integer type, the function name is add and the parameter list contains the variables a and b.

Now, in general when a function like add is called, values are copied into the parameters of the function. For example, calling add as follows...

add(5, 7);

... copies the value of 5 into the parameter a and the value of 7 into the parameter b.

Or, I could call add as follows...

int x=5, y=7;

add(x, y);

This still copies the value of 5 into the parameter a and the value of 7 into the parameter b. You can imagine x passing a copy of it's value to a and y copying it's value of 7 to b.

Any changes made to a and b inside the add function have no effect on x and y.

Here is another example.

 

#include <iostream.h>
int square(int x);


void main()
{
   int y=10;
   cout << "y squared is " << square(y);

}

int square(int x)
{
   x= x * x;
   return x;
}

Here we have two functions, main and square. Inside main, when the square function is called, the value of y is copied to x. The function square then squares the value of x and returns the result to main. The output should be...

y squared is 100

We must be clear that changing the value of x inside the function square in no way changes the value of y which retains the value of 10 even though the value of x changed to 100.

This method of passing arguments to a function is called call by value.

Here is a final example.

 

#include <iostream.h>
void swap(int a, int b);


void main()
{
   int x = 2, y=3;
   swap(x,y);

   cout << "x is " << x << ", y is " << y << endl;
}

void swap(int a, int b)
{
    int temp = a;
    a =
b;
    b = temp;
    cout << "a is " << a << ", b is " << b;
}

Here we have two functions, main and swap. Inside main, when the swap function is called, the value of x is copied to a and the value of y is copied to b. The function swap then swaps the value of a and b and prints out the result. The output should be...

a is 3, b is 2.
x is 2, y is 3.

Since the function swap was called by value, changing the value of a and b has no effect on x and y.


  Call by Reference

Call by reference is the second way of passing arguments to a function. In this method, the address of an argument is copied to the parameter and not its value. Inside the function, the address may be used to access the original argument used in the call.

This means that changes made inside the function may very well affect the original calling argument.

Let's change the previous swap example so it is called by reference instead of by value.

void swap(int *a, int *b) {
   int temp = *a;
   *a = *b;
   *b = temp;
}

First, you should notice something new. The variables, a and b have the * character in front of them. In C++, the * character in front of a variable usually means the variable is a pointer. Pointers are one of the most difficult things about C and C++ to grasp as a new concept.

A pointer is a variable that doesn't hold a normal value, instead it holds the address of another variable, (address meaning where the other variable is in memory) .

Just so you can get the general idea look carefully at the following code..

int x = 5;
int *y = &x;

On the first line we have a normal integer variable x, set to hold the value 5.

On the second line, the variable y is declared as an integer pointer - the * in front of y means it is going to hold an address value.

It is then set equal to the &x. This does not mean that y is set to the same value as x. It is set to hold an address value, the address of x in memory. The address of x is specified by using the & operator, i.e. &x means the address of x.

This is what I get when I run the following code..

int x = 5;
int *y = &x;
cout << "The value of x is " << x << endl;
cout << "The value of y is " << y << endl;

The value 0x0012FF7C is the address of x in memory. This memory location actually holds x's value of 5.

Now, to get back to the swap example...

void swap(int *a, int *b) {
   int temp = *a; 
// set temp to the value in the address pointed to by a
   *a = *b;
          // set the value in address a to the value in address b
   *b = temp;    
// set the value in address b to the value held by temp
}

.. both variables a and b are pointer variables, which mean they are going to hold addresses. The function parameters a and b are passed two addresses. The code in the body of the function proceeds to swap the values held at these addresses.

Look at the swap code in full below:-

 

#include <iostream.h>

void main() {
   int x = 2, y=3;
   cout << "The value of x is " << x << " and y is " << y << endl;
   swap(&x, &y);
   cout << "The value of x is " << x << " and y is " << y << endl;
}

void swap(int *a, int *b) {
   int temp = *a;
   *a = *b;
   *b = temp;
}

Here is the output from the code:-

In this example, the variables x and y are initially assigned the values of 2 and 3 respectively. Then swap is called and the addresses of x and y are passed to a and b, (not their values).

Inside the swap function, a and b now point to x and y, so a and b can directly access the values held at x and y's addresses. These values are then swapped - x ends up with y's value of 3 and y ends up with x's value of 2.

In contrast to the swap example where the arguments are passed by value, in this case because of the call by reference, the values of x and y can be changed outside main, from directly within the swap function.

A final word. Learning about pointers and addresses and passing values by reference can be challenging and is the focus of the next C++ level 3. These aspects of C++ can be the extremely frustrating to learn but are well worth it because they bring to your programming a new level of power and are one of C++'s most important features.


  Extension Work

Carry out the following exercises:-

  1. Now start step10 of the practice assignment 3

That's it!