Parameter Passing in C++


This example focuses on parameter passing. For more information on the top-down approach to analysis and design, review the web page entitled An Example of Writing a C++ Program Using Multiple Functions.

There are five ways in which functions are used in C++, depending on how they pass (exchange) data with other functions.

  1. A function can simply perform steps, but exchange no data with its parent function. For more information on this type of function, see the web page entitled An Example of Writing a C++ Program Using Multiple Functions.
  2. A function can receive data from its parent when called and perform steps with that data, but return none back to its parent.
  3. A function can receive no data from its parent when called and yet still return some. This type of function performs steps with data that it generates or requests from a user. When complete, it returns a single value to its parent.
  4. A more complex function might receive data from its parent when called, perform steps with the data, and then return a single value back to the parent when the function terminates.
  5. The most complex method of function usage involve functions that return more than one value back to the parent. This is accomplished in C++ through one of two approaches (both introduced in the page Parameter Passing by Reference)):

You can view a quick reference page (PDF file) containing some examples of the proper C++ syntax to use for perform parameter passing between functions by clicking on the link at the front of this sentence.

The following C++ program illustrates the first four of these types of function usage. A full analysis of the program below can be found on the web page entitled An Example of Documenting a Program Using Parameter Passing. Normally the main function appears last (following all other function declarations) in the source code. This is because every function must be declared before it can be called. You can position the main function near the top of the source code instead by using function prototype statements. These statements allow you to declare just the function identifier ahead of the main function and then define the entire function after the main function. Notice that the function prototype statements end with semicolons; and yet their counterparts in the headers of the full function declarations below do not.

#include <iostream>  // Load the Input/Output STREAM Library
using namespace std; // to define context for cin and cout

#define PI 3.14159   // Declare a constant macro to use in place of 3.14159

/* This program was coded without "function prototype" statements. As such,
   all child functions had to be declared ahead of the main function. */

//  =========================  CHILD FUNCTIONS  ==========================

   /* The following statement defines a function that passes no data. Such
      functions CAN use globaly defined data (although this one did not), and
      they CAN declare their own variables (although this one did not).
      But they cannot use data declared locally in other functions.
      When called, this function is treated like a command (see main below) */

      void DisplayTitle ()
      {
         cout << "Circle Area Calculating Program\n\n";
      }

// ------------------------------------------------------------------------

   /* The following statement defines a function that receives no data when it
      starts, but returns data when it is done. The function declares and uses
      its own local variable R and then returns its value through the function
      name ReadRadius. When called, this function is treated like a piece of
      data, because it returns data. */

      double ReadRadius ()
      {
         double R;  /* Local variable to temporarily hold keyboard input */
         cout << "Enter the radius of the circle: ";  /* Display prompt */
         cin >> R;  /* Scan the keyboard buffer for a long float */
         return R;  /* Pass value in R back to main via the function name */
      }

/* ------------------------------------------------------------------------ */

   /* The following statement defines a function that both receives and
      returns data. The function uses data passed to it from another function
      (main) into the first "formal parameter" named R. The globally declared
      symbolic constant (PI) COULD BE used in this function, but SHOULD be
      formally passed instead into the second "formal parameter" named P. The
      function returns its result through its name CircArea. When called, this
      function is treated like a piece of data, because it returns data. */

      double CircArea (double R, double P)

      {
         double A;  /* Declare a local variable to temporarily hold result */

         A = P * R*R;  /* Calculate the square of the received N  */

         return A;   /* Send A back to the parent via the function label */

      }      /* Parameters R and P and local variable A are abandoned here */

/* ------------------------------------------------------------------------ */

   /* The following statement defines a label for a function that only
      receives data. The function uses data passed to it from another function
      (main) into the "formal parameter" named A. Because it returns no data,
      it contains no return statement. When called, this function is treated
      like a command. */

      void DisplayArea (double A)
      {
         cout << "\nThe area of that circle is " << A << endl;
      }

/*  =====================  MAIN (PARENT) FUNCTION  =======================  */

int main ()

{
   double RADIUS,  /* Radius of a circle - entered by user at the console  */
          AREA;    /* Area of a circle - calculated by function CircArea */

/* The statement below calls a function to display the program's title.
   The main function does not pass any data into this function when it starts,
   so the "actual parameter list" following the function label in parentheses
   is empty (but must be shown). Because this function does not return a
   value, it is called like most other commands by just writing its name. */

   DisplayTitle ();

/* The statement below calls a function to request and return input that was
   read from the keyboard. The main function does not pass any data into this
   function when it starts, so the "actual parameter list" (following the
   function label in parentheses) is empty. Because the function returns a
   value, it is handled like a value and assigned into a variable. */

   RADIUS = ReadRadius ();

/* The statement below calls a function that will receive two items of data
   (the radius and the value of PI) and uses them to calculate the area.
   The main function passed the data into this function when it starts, via
   the "actual parameter list" (following the function label in parentheses).
   Because the function also returns a value, it is handled like a value and
   assigned into a variable. */

   AREA = CircArea (RADIUS, PI);  /* Call a func. to calc. and return AREA */

/* The statement below calls a function that will receive one item of data
   (the area) and then identify and display it. The main function passed the
   area data into this function when it starts, via the actual parameter list
   (following the function label in parentheses).  Because this function does
   not return a value, it is called like most other commands by just writing
   its name. */

   DisplayArea (AREA);     /* Call a function to identify and display AREA */

   return 0;   /* Send error code zero back to the system   */
}

The labels chosen for functions that do not return data are typically verb-like (describing their action), whereas the labels chosen for functions that do return data are typically named after the item of data that they return.

The syntax used to call a function depends on whether the function returns a value through its label. The DisplayTitle and the DisplayArea functions in the example above do not return values through their labels, so the statements in main that call those functions treat their names as verbs (commands starting the statements). On the otherhand, the functions ReadRadius and CircArea do return values through their labels, so the statements in main that call those functions must treat their names as data objects, having an action (assignment in this case) performed upon them.

Actual Parameters vs. Formal Parameters

Notice in the example source code above that the labels used for data in the main function do not have to be identical to those used for the same values in the child functions. As long as the items listed in the calling statement (known as the actual parameters) match up properly with the identifiers in the headers of the child function declarations (known as the formal parameters), the parameters will pass properly. This matching issue is referred to as the parameter correspondence. The actual parameters (following the function identifier in the calling statement) must correspond to formal parameters (following the function identifier in the declaration) in the following ways.

PATH: Instructional Server> COP 2000> Examples>