Learn to do stuff

Home  » Browse  » Learn to program in C++

 
Learn to program in C++
Posted September 9, 2006. Written by John Zervos, author of the text Byte Into C++ (2002). Tertiary Press: Melbourne.
This article provides a comprehensive yet simple to understand treatment of the C++ language for beginners. The article is divided into a series of separate lessons as follows:

Lesson 1 - Introduction
Lesson 2 - Data types and variables
Lesson 3 - Operators
Lesson 4 - Selection
Lesson 5 - Iteration
Lesson 6 - Functions


 
Lesson 6 - Functions

A function is a stand-alone block of program code that performs a particular task. All C++ programs consist of a main function called main() which is where execution begins. Very small programs may only consist of a main function. However, most programs will include one or more programmer-defined (programmer-written) functions. Functions help make a program easier to conceptualise and debug by breaking it up into stand-alone "modules". In addition, a function can be called as many times as is required, thereby facilitating code minimisation and code reuse.

Any function can call (or invoke) another function. When a function is called, program execution jumps to the starting location of that unction and executes its code. When the function ends, program control is returned to where it left off (the next instruction) in the calling program.

The only real disadvantage associated with functions is the slight overhead (use of additional system resources) required to implement the function. For this reason, some speed-critical applications minimise their use of external function calls.

Writing your own functions

There are three parts to writing and using your own functions: 

1. The function definition - the code for the function.
2. The function prototype - a statement that declares the function to the compiler.
3. The function call - a statement that invokes the function.

Void functions

These are the simplest type of function as there are no parameters (data values) passed between the calling function and the called function (parameter passing is dealt with a little later).

The function definition

Consider the following function definition:

void greeting()
{
   cout << "Welcome!" << endl;
}

All programmer-defined functions must be given a unique identifier (function name) using the same rules as when naming variables. The name of the function above is greeting and like all function names is followed by a pair of parenthesis (curved brackets). The keyword void tells the compiler that this function does not return anything back to the calling function (more about this later).

The operation of this function is quite straight forward. When the function is called, the statement or statements between its braces are executed in the normal way. In this case, the greeting "Welcome!" is displayed on the screen.

Function definitions are normally placed after the closing brace of the main function. In other words, they sit outside of the main function.

The function prototype

Having a function definition alone is not enough to satisfy the compiler. This is because the compiler has no prior knowledge of the identifier greeting. Therefore, the function needs to be declared to the compiler in a similar way in which variables are declared. The declaration statement for a function is called the function prototype.

The syntax for the function prototype is the same as the first line of the function (known as the function header or declarator) but is terminated with a semicolon. The prototype for the function about would be:

void greeting();

The function prototype must be placed before the function is first seen in the source code, which is normally outside of, and above, the main function.

The function call

To access a function you must use a call statement. A basic call statement simply consists of the function's name. The call statement for the function above would be:

greeting();

Notice that the void is not required. This statement would be placed within which ever function was calling the greeting function.

void greeting();

The function prototype must be placed before the function is first seen in the source code, which is normally outside of, and above, the main function.

The complete program

Here's what the complete program might look like:

#include <iostream>
using std::cout;
using std::endl;

void greeting();         // Function prototype

int main()
{
   greeting();           // Function call 

   system("pause");
   return 0;
}
      
void greeting()          // Function definition 
{
   cout << "Welcome!" << endl;
}
 

Passing arguments (parameters) to a function

When a function is called, it is possible to pass data (referred to as arguments or parameters) to the function for processing. You can pass more than one parameter at a time, and the parameters can be of any primitive or user-defined type. The parameter list is placed within the function's brackets. Parameters can be passed to a function by value or by reference. Both methods are outlined below.

Passing arguments by value

When an argument is passed to a function by value, a copy of the original data is made available to the function. Any change to the copy within the function does not affect the original data value. This type of parameter passing is more common in pure C programs. Consider the following function definition:

void square(int y) 
{
   cout << y*y << endl;
}

When the square function is called, a parameter is passed to it by value and is assigned to the variable y. This variable is local to the function and cannot be accessed outside the scope of that function.

The function prototype will be the same as the first line of the function terminated with a semicolon as shown:

void square(int y);

A possible call to the function may look something like this:

int x = 2;
square(x);     // Function call

Here, the parameter x, having the value 2, is passed to the function. Notice that the function call simply consists of the function name with the parameter list in brackets. 

The complete program is shown below:

#include <iostream>
using std::cout;
using std::endl;

void square(int y);         // Function prototype

int main()
{
   int x = 2;
   square(x);              // Function call 

   system("pause");
   return 0;
}
      
void square(int y)          // Function definition 
{
   cout << y*y << endl;
}
 

In this program, an integer variable x is declared and initialised with the value 2. The program then calls the square function and passes it a copy of the parameter's value, 2. In the function, the passed value 2 is assigned to the local variable y, which is then squared and displayed.

Passing arguments by reference

When an argument is passed to a function by reference, a type of pointer to the original data is passed to the function, rather than a copy of the data. This is a more resource efficient way of passing data to a function but it means that the function can modify the original data (which can be both a good thing and a bad thing).

Consider the following function definition:

void square(int& y) 
{
   y = y*y;
}

The reference operator, &, tells the compiler that parameter y will be a reference to the original data passed to the function. In other words, y becomes an alias (another name for) the original data passed to the function. If the value of y is modified, so too will the original data.

When the square function is called, a parameter is passed to it by reference and is assigned to the variable y. This variable is local to the function and cannot be accessed outside the scope of that function, however, it "points to" the original data in the calling function. The statement y = y*y in the function squares the value of y, and so too squares the original data in the calling function.

The function prototype will be the same as the first line of the function terminated with a semicolon as shown:

void square(int& y);

A possible call to the function may look something like this:

int x = 2;
square(x);           // Function call
cout << x << endl;

Here, the parameter x, having the value 2, is passed to the function by reference because of the & operator used in the function header and prototype.  

The complete program is shown below:

#include <iostream>
using std::cout;
using std::endl;

void square(int& y);         // Function prototype

int main()
{
   int x = 2;
   square(x);               // Function call
   cout << x << endl;

   system("pause");
   return 0;
}
      
void square(int& y)          // Function definition 
{
   y = y*y;
}
 

It's also possible to pass parameters to a function by reference for efficiency, but make them "read only" so that they can't be modified by the function. This is done by using the const keyword in the local variable declaration as shown:

void square(const int& y)
{

}

Passing multiple arguments

It's possible to pass multiple arguments to a function of different data types and using a mix of pass by value and pass by reference. An example is shown below:

void details(const int& age, char gender, float& weight)
{

}

Returning by value

A function is able to return a single value on termination. Returning values in this way is popular in C, but with pass-by-reference in C++, this feature is largely redundant. Nevertheless, consider the following function definition:

int getAge()
{
   int age;
   cout << "Please enter your age: ";
   cin >> age;
   return age;
}

In this function, a local integer variable age is declared. The user is prompted for their age and its value assigned to the variable age. The return keyword both terminates the function and passes a copy of age's value back to the calling program. The function is of type int, rather than void, to denote the type of data being returned.

The function prototype will be the same as the first line of the function terminated with a semicolon as shown:

int getAge();

A simple call to the function may look something like this:

getAge();        // Function call

However, this is inadequate because the returned value, in this case the user's entered age, is lost. Therefore, the function call can be used in assignment statement as shown below, so that the returned value is assigned to a variable for later use.

int userAge;
userAge = getAge();        // Function call

Alternatively, you could combine the function call with a cout statement to immediately display the user's entered age as shown below:

cout << getAge();        // Function call

This statement performs the dual role of calling the function and sending its returned value to the output stream.

Functions that return values can also take parameters by value and/or reference.


 

 © 2006 learn2dostuff.com

Disclaimer