Next: Interfacing to FORTRAN Up: Introduction to C++ Previous: Dynamic Allocation of

Functions and Function Arguments

C/C++ does not distinguish, as FORTRAN does, between functions and subroutines. All routines are functions. If the function returns nothing, we say it returns void. To declare a function to the compiler, we write the return type (the data type that the function returns), followed by the name of the function, followed by the argument list, followed by the statements of the function.

The following declares a function that takes no arguments and returns an integer:


int myFunc()
{
  return 6;
}

The following declares a function that takes an integer argument and returns nothing:


void myFunc2(int i)
{
  int j = 2*i;
  anotherFunc(j);
}

In C++ , arguments to subroutines may be ``passed by value'' or ``passed by reference''. By default, arguments are passed by value. ``Passed by value'' means the argument is copied from the calling routine into a memory area belonging to the called function and the function acts on this local copy; any changes it makes will not be seen in the calling routine. Thus, the following is not effective:


void divideByTwo(int i)
{
  i = i/2;
}

If we invoke this function and pass it a variable,


int j = 6;
divideByTwo(j);

we will find that j is not changed by the function call. The called function is given a new copy of j in its own memory; this copy is divided by two but nothing changes in the calling routine.

Things would be different if we wrote divideByTwo() to have its argument passed by reference. ``Passed by reference'' means the called routine receives the original variable, not a copy, as its argument. This is the scheme FORTRAN uses for passing variables. We tell the C++ compiler to pass an argument by reference by putting an ampersand after the type in the argument list of the function. Thus if we wrote


void divideByTwo(int& i)        // note the ampersand
{
  i = i/2;
}

and invoked it as before, we would find that j had indeed been changed from 6 to 3 by the function.

C++ is a strongly-typed language, which means it tries to never let you use a data type in a place where it does not make sense. To help C++ do this, it requires that the signature of a function (its return type and the types of its argument list) must be declared to the compiler before the function is ever invoked. This is known as ``forward declaration'' of the function. A forward declaration is just like the real function declaration except the argument list is followed by a semicolon instead of a block of commands. So the forward declaration of our divideByTwo() function would look like this:


void divideByTwo(int& i);

or


void divideByTwo(int&);         // not necessary to give names to the arguments

In C++ , a function may be declared to be inline. Declaring a function inline has no effect on the ultimate results of a program but may improve the efficiency. Instead of passing arguments by value and transferring control to a subroutine, the compiler inserts the code to execute the subroutine right at the point it is invoked. If the subroutine is large and invoked many times, declaring it inline will increase the size of the executable.

Inline functions will never be compiled into standalone object modules and linked into an application later. Whenever you are compiling a program that calls an inline function, the compiler must have already seen the definition of the function so it can be inserted. Therefore, inline functions usually live in header files (.h files).

The function is declared to be inline by placing the keyword inline before the return type in the definition.


inline int cmp(int i1, int i2) {return i1 == i2;}



Next: Interfacing to FORTRAN Up: Introduction to C++ Previous: Dynamic Allocation of


walter@
Wed Aug 10 11:53:26 PDT 1994