Functions

  1. What are functions and why do we have have them?


    Functions are sub-programs within your larger program. They solve particular tasks and can be called (executed) from other functions. The function main() that we have been using so far is just one example of a function.

    Functions make programs more understandable by allowing the programmer to break complex tasks into smaller, simpler ones. They also reduce the overall amount of code because every time the task needs to be done, the same function can be called.

  2. How do we use functions?

    We will start by using functions that are already written, in particular, functions from the libraries provided with C++. These functions implement many commonly-needed tasks.

    For any function there are four things we need to know in order to use it (the first two are pretty obvious):

    For an example, we will use the math library. The math library provides the following functions, among others:
    function nameargument typereturn typedescription
    ceildoubledoubleceil(x) returns the smallest integer >= x
    cosdoubledoublecos(x) returns the cosine of x in radians
    fabsdoubledoublefabs(x) returns the absolute value of x
    floordoubledoublefloor(x) returns the largest integer <= x
    pow2 doublesdoublepow(x,y) returns x to the yth power
    sindoubledoublesin(x) returns the sine of x in radians
    sqrtdoubledoublesqrt(x) returns the square root of x

    Notice that functions can have more than one argument. Although all the examples above use only doubles as arguments and return types, any class/type is a value type for an argument, and they can be mixed.

    To use these functions you must first alert the compiler that they exist. In the case of library functions (and later, functions from other modules that you write) this is done by using a header file. Then, as long as you use the correct types, you can use a function just like any other expression (value). The following program uses the math library to give several examples of using functions. Notice we can assign their values to variables, use them as values in expressions, and use them as values to other function calls.

    #include <iostream.h>
    #include <math.h>  // definitions of the math functions
    void main()
    {
      int n, factor, remains, stoppingpoint;
    
      cout << "A square factor of a number is a value that is a factor of " 
           << endl 
           << " the number and whose square is also a factor of the number."
           << endl 
           << "This program finds the square factors of an integer." <<endl;
    
      cout << "Give an integer\n";
      cin >> n;
    
      stoppingpoint = int(ceil(sqrt(n)));
      for (factor =2; factor <= stoppingpoint; ++factor)
        {
          if (n % factor == 0)
    	{
    	  if (n % int(pow(factor,2)) == 0)
    	    {
    	      cout << factor << " is  a factor of " << n 
    		   << " and it is a square number " << endl;
    	    }
    	  else cout << factor << " is a factor of " << n
    		    << " but it is not a square factor " << endl;
    	} // factor is a factor of n
        } // testing all possible factors of n
    }
    
    

  3. Writing function prototypes

    Function prototypes are used to describe the name, arguments and return value of a function. They are placed before you use the function, and alert the compiler to the meaning of the function name it later sees.

    In many cases, as in the math example above, the prototypes are placed inside a .h file which is then included into the .C file. In cases where the function definitions (the body of the function code) are in the same file as the use of the function, the prototype can be placed at the top of the file, after the header files but before the main function.

    function prototypes have the following form:
    return_type function_name(types_of_arguments);
    For example, the prototype of the sqrt function would be:
    double sqrt(double);
    Notice we do not need to give a name for the argument, just its type.

    The prototype allows the compiler to make sure you are correctly calling the function, by comparing the types of the arguments you send with the types of the arguments in the prototype.

  4. User defined functions: non-void Functions


    The first functions we will write are those that return a value back to the user, like the ones we saw in the math library example above.

    As an example, we will write a function that has an integer argument n and returns the sum of the values between 1 and n.

      
    #include <iostream.h>
    
    int Sum(int); //the prototype for sum -- it receives an integer and returns one
    
    void main()
    {
       int n;
       cout << "Give an integer\n";
       cin >> n;
       cout << "The sum of 1 to " << n << " is " << Sum(n) << endl;
    }
    
    // Now, the definition of Sum
    
    // the function header is almost the same as the function prototype,
    // except that we now give a name to the argument we receive
    // We call the names in the function header the "formal parameters;"
    // the actual arguments we send are called the "actual parameters" --
    // the variable n in the main program is an actual parameter.
    
    int Sum(int lastvalue) 
    {
    
      // the function body is pretty much the same style as the
      // main function's body, but we also use the parameter as a variable
      int count, totalsofar= 0;
      for (count = 1; count <= lastvalue; ++count)
        {
          totalsofar += count;
        }
      
      // we leave the function by returning a value
      return totalsofar;
    }
    

    Practice

    1. Modify the above function and program so the user enters a beginning value and an ending value and Sum gives the sum of the integers between the beginning and ending values.
    2. Write a function that computes the sum 1 + 1/2 + ... + 1/lastvalue. Notice the function is given an integer and returns a double.

  5. User defined functions: void Functions


    void functions are analogous to Pascal's procedures. They are functions that do not return a value. The quickest example of a void function is the main() function you have been writing for all of your programs.

    Like main(), functions may have no arguments, or they may have arguments like non-void functions. Oftentimes a non-void function is used when we want several results returned from the function. For example, suppose we want both the sum and the average of the values between 1 and n. A non-void function returns only one value. The program below shows how to write a void function that uses reference parameters to return more than one value.

    #include <iostream.h>
    
    // the prototype for SumAverage -- it receives an integer indicating
    // how many values it is to sum and also a "reference" to an integer,
    // and a "reference" to a double.
    // A reference parameter is one whose actual parameter *must* be a 
    // variable of that type.
    void  SumAverage(int, int &, double &);
    
    void main()
    {
       int n, sum;
       double average;
       cout << "Give an integer\n";
       cin >> n;
    
       // void functions do not return a value, so they are a statement
       // by themselves
       SumAverage(n, sum, average);
       cout << "The sum of 1 to " << n << " is " << sum << endl
    	<< "The average is " << average << endl;
    }
    
    void SumAverage(int lastvalue, int &total, double &average) 
    {
    
      int count;
      total = 0;
    
      for (count = 1; count <= lastvalue; ++count)
        {
          // reference parameters refer to the variable passed as an argument
          // so this reference to total modifies the variable sum that was
          // passed in from main()
          total += count; 
        }
      average = double(total) / lastvalue;
    }
      

    Practice

    Write a void function called Swap that is given two variables (reference parameters) and swaps their values. For example, on input of 4 and 17, the following main program should produce a result of
    4 17
    17 4
    
    void main()
    {
      int a, b;
      cout << " Give two integers \n";
      cin >> a >> b;
      cout << a << '\t' << b << endl;
      Swap(a,b); // you write this!
      cout << a << '\t' << b << endl;
    }
    

Back to the main Day 3 page.