Week #6 functions

CS 161: Introduction to Computer Science 1

 

 

 

A Sample Function Declaration

• With C++ can also define your own functions. These functions call be called from your main program or from other functions; a C++ function consists of a grouping of statements to perform a certain task. You can begin execution of a function by calling the function. This means that all of the code necessary to get a task done doesn't have to be in your main program ; you should, in fact, divide your program into a series of major tasks...where each major task is a function, called by the main program.

 

• In programs, we are able to group together statements that perform a distinct task and give the overall action a name. This is accomplished by writing a C++ function. For example,  tasks such as driving a car, or cooking breakfast are every day functions that we use. The exact details of driving a car or cooking are hidden in the actual process, but even though you don't know the details -- just from the statement "driving a car" you know what that involves and what I am talking about. I don't need to have to tell you that first I get out my keys, then unlock the car door, then get inside, then..... We expect the person we are talking to know what we mean, just by using the name of the process.

 

• The same thing applies to functions in C++. A function has a name assigned to it and contains a sequence of statements that you want executed every time you invoke the function from your main program!

 

• Data is passed from one function to another by using arguments (in parens after the function name). When no arguments are used, the function names are followed by: "()". For example, if our main program doesn't expect any arguments....we use the "empty list":

            int main()

 

• The syntax of a function is very much like that of a main program. Instead of saying main(), you have a function header:

            data_type function_name()

            {

                        <local variable definitions>

                        <executable statements>

            }

 

      This is followed by { and any constant/variable definitions (these are called local definitions) used in the function, followed by the executable statements (i.e., body), and terminated by the }.

 

      Notice there is no semicolon after the last }. Notice there is also no semicolon after the name of the function!

 

• The data_type of a function can be int, float, char, or void. void indicates that there is no type associated with a function; this means that the function does not return any value...you are simply calling the function to perform a specific task. You could think of a void function as similar to a Pascal procedure. A function that returns an integer is similar to a Pascal function or a Modula-2 function-procedure.

 

 • A function must always be declared before it can be used; this means that we must put a one-line function declaration at the beginning of our programs which allow all other functions and the main program to access it. The function itself can be defined anywhere within the program. This is called a function prototype.

 

      For style purposes, our functions will first be declared at the beginning of our main program and then defined after the body of our main program (after the...int main() {}).

 

  • When you want to use a function, it needs to be CALLED or INVOKED from your main program or from another function. If you never call a function, it will never be used.

 

• Let's walk thru an example of our automatic teller machine program and call a function to print a sign on message:

 

      void signon(void);                    //function declarations (i.e., function prototype)

      void signoff(void);                    //notice the semicolons!

 

      int main()

      {

           

            char answer, selection;       //variable definitions

           

            //begin the session

            signon();                                            //function call

           

            //do some processing......

            answer = 'Y'; //Initialize the variable answer to make                                          //sure the program is run once

 

            while (answer == 'Y') {

                        cout <<" Enter your selection on the keypad:";

                        cout <<"         1- Withdrawl, 2-Deposit, 3-Balance" <<endl;

                        cin >>selection;

                                    .... code for withdrawl....and deposit....

 

                        if ( selection == '3')

                                                balance();       //calling procedure Balance!

                       

 

                        cout <<"Would you like to continue?" <<endl;

                        cin >>answer;

            }

 

            //terminate the session

            signoff();                                           //function call         

 

            return 0;

      }

 

      void signon(void) {                               //function definition

            cout <<" Welcome to the automatic tell machine " <<endl;

            cout <<" Please enter your password " <<endl;

            cout <<" Press <return> when finished" <<endl;

            return;

      }

 

      void signoff(void) {

            cout <<" Thank you for using our automatic teller system ";

            cout <<endl <<" Please come again!" <<endl;

            return;

      }

 

• Notice that in this example we use a function prototype for our function declarations. They are very similar to the function header except that they must be terminated by a semicolon....just like any other declaration in C++.

 

• Functions are very useful. You might ask, why go through the trouble to write a program that does no more than the original, shorter version? One reason is that functions can be used as prefabricated parts for the easy construction of more complicated programs. Another reason is that a function - once created - can be called any number of times without writing its code again.

 

• As our programs get more complicated, it is really important that you clearly understand the order in which statements are executed. The main program runs first, executing its statements, one after another. Even though the functions are declared before the main program (and may also be defined before the main program), they are not executed until they are called. They can be called as many times as you wish.

 

 

• Summary: WHY USE FUNCTIONS?

 

      1. By giving the task a name, we make it easier to refer to. Code that calls clearly named functions is easier to understand than code in which all tasks are described in the main program. Programs that use functions are easier to design because of the way they "divide and conquer" the whole problem.

 

      2. By having a function perform the task, we can perform the task many times in the same program by simply invoking the function repeatedly. The code for the task need not be reproduced every time we need it.

 

      3. A function can be saved in a library of useful routines and plugged into any program that needs it.

 

      4. Once a function is written and properly tested, we can use the function without any further concern for its validity. We can therefore stop thinking about how the function does something and start thinking of what it does. It becomes an abstract object in itself - to be used and referred to.

 

• In summary, functions enable us to implement our program in logically independent sections n the same way that we develop the solution algorithm.

 

• Each function declaration can contain declarations for its own...this includes constants, variables. These are considered to be LOCAL to the function and can be referenced only within the function in which they are defined.

 

• Remember that functions must be listed in the declaration section of the main program (since the main body is actually executed first). But, just remember that the first statement executed is actually the first statement in the main body, not the first statement in the first procedure defined. It is only when a function is called that "control transfers" to the function that is referenced. After the function is done, control returns to the statement in the main program (or calling function) that follows the function call statement!

 

• Although many functions may be declared in a program, there can actually be only ONE main program.

 

• Unlike Pascal, functions can occur in any order in the source file.

 

• With functions you must first specify the return type, the function name, and then the arguments in parens.  If the function is used by other functions, it must be declared at the beginning of each function that is going to use it. Notice, a function may be declared many times...but only defined once!

 

      In addition, functions can be declared after the preprocessor directives and before the main program. If you do this, you should use the keyword 'extern' preceding the function declaration.  A declaration signifies that the function is 'defined' elsewhere (potentially in another file). 

 

• Let's go thru a simple example...to show how you can have only one  function declaration.

 

// The function print_asterisk is defined elsewhere;

//it can be either in another file or later in this file

extern int print_asterisk(void);   //the keyword extern is optional – it defaults     

 

int main()

{

      int number;               //local variable

 

      if (number = print_asterisk())

                  cout <<" We printed " <<number <<" asterisks \n";

      else

                  cout <<" I am sorry but you tried to print too many!\n";

 

      return 0;

      }

 

      int print_asterisk (void)           // The function is defined here   

      {

            const int maximum = 10;

      int num_asterisk, i;  //local variable

 

      cout <<"How many asterisks would you like?\n";

      cin >>num_asterisk;

 

            if (num_asterisk > maximum)

                        return(0);

            else {

                        for (i=1; i <=num_asterisk; i++)

                                    cout <<"*";

                        cout <<endl;

                        return(num_asterisk);

            }

      }

 

      (side note: what happens if you enter zero? Any ideas on how to fix this?)

 

 

 

• To have a function return a value - you simply say "return expression". The expression may or may not be in parens. Or, if you just want to return without actually returning a value, just say return; (note: return(); is illegal). If you normally reach the end of a function (the function's closing "}"), its just like saying return;  and no value is returned.

 

      In cases where the function is declared to return a value, but a return; is encountered, it is unpredictable what value is actually returned. Therefore, it is highly recommended that return; without an expression be used when a function is declared to be of type void.

 

• Also notice, that the type of a function must be specified in both the function declaration and in the function definition.

 

• For functions that don't return anything, you should preface the declaration with the word "void". When using void, it is illegal to have your return statement(s) try to return a value.

 

Argument Lists

• If we go back to our example of converting Fahrenheit to Celsius program, if we put that in a function, we have a slight problem. Somehow we need to send the Fahrenheit temperature to the function and get back from the function the Celsius temperature.

 

• For example:

     

      void purpose(void);                  //prints the program's purpose

      float calculate(float f);             //converts Fahrenheit to Celsius

int main()

{

 

            float fahr, celsius;

 

            //Show purpose of the program

            purpose();

     

            //Get the temperature in Fahrenheits

            cout <<" Please Enter the Fahrenheit temperature?" <<endl;

            cin >>fahr;

 

            //Convert it to Celsuis

            celsius = calculate(fahr);

 

            //Print the result

            cout <<celsius <<endl;

 

            return 0;

      }

 

 

      void purpose(void)

      {

            //printing the purpose of the program

            cout <<"Converting Fahrenheit to Celsius " <<endl;

      }

 

      float calculate (float f)

      {

            //converting Fahrenheit temps to Celsius temps

            return (5.0/9.0) * (f - 32.0);

      }

 

• Notice that we can have arguments to functions! These must be in the function header for both the function declaration (prototype) and function definition. In this example,  f is a variable...which is a argument because it is defined in the function header.

 

• When you call calculate, you are establishing an association between the main program's fahr variable and the function's f variable; this function does some calculations, and returns a real number which is stored in the calling routines celsius variable.

 

• Notice that variables are declared in a function heading; these are FORMAL ARGUMENTS. They look very much like regular variable declarations.

 

• The arguments in the function call (invokation) are called ACTUAL ARGUMENTS. When the procedure call is executed, the actual arguments are conceptually copied into a storage area local to the called function. If you then alter the value of a formal argument, only the local copy of the argument is altered. The actual argument never gets changed in the calling routine. Later we will learn how to allow for changing argument values.

 

• C++ checks to make sure that the number and type of actual arguments sent into a function when it is invoked match the number and type of the formal arguments defined for the function. The return type for the function is checked to ensure that the value returned by the function is correctly used in an expression or assignment to a variable.

 

• CAUTION: Make sure the type of each actual argument MATCHES that of the formal arguments!

 

Functions calling Functions

• So far we have learned how to call a function from a main program. Well, you may also call a function from within another function.

 

• ONLY RESTRICTION: A function call cannot appear before the function is declared.

 

• Let's modify the program on the board to see how this works:

 

• For example:

     

      void purpose(void);                   //prints the program's purpose

      float calculate(float f);   //converts Fahrenheit to Celsius

int main()

{

 

            float fahr, celsius;

 

            //Show purpose of the program

            purpose();

     

            //Get the temperature in Fahrenheits

            cout <<" Please Enter the Fahrenheit temperature?" <<endl;

            cin >>fahr;

 

            //Convert it to Celsius

            celsius = calculate(fahr);

 

            //Print the result

            //cout <<celsius <<endl;   //commenting this out ... for now

 

            return 0;

      }

 

 

      void purpose(void)

{

            //printing the purpose of the program

            cout <<"Converting Fahrenheit to Celsius " <<endl;

      }

 

      float calculate (float f)

      {

            //converting Fahrenheit temps to Celsius temps *)

            void PrintResult(float num_entered, float result);

 

            float cel;                                                        //local variable

 

            cel = (5.0/9.0) * (f - 32.0);

            PrintResult(f, cel);

            return cel;

      }

 

      void PrintResult(float num_entered, float result)

      {

            // printing the result of the conversion 

            cout <<" You entered: " <<num_entered <<endl;

            cout <<" Which is equal to " <<result <<" Celsius: ";

            cout <<endl;

 

            //notice that if I had changed "result" in this

            //function, it would not have affected the calling

            //function's value of "cel"

      }

 

• Functions can be referenced in expressions in the same way that we referenced predefined functions.

 

• When we deal with FORMAL VALUE ARGUMENTS...the calling actual argument values cannot be modified by the function. This allows us to use these functions, giving literals and constants as arguments without having conflicts. This is the default way of doing things in C++.

 

• With all of this information, let's write a function to sum two numbers:

 

      int sumup(int first, int second);         //function prototype

int main()

      {

 

            int total, number, count;

 

            total = 0;

            for (count = 1; count <= 5; count++) {

                        cout <<" Enter a number to add to the total " <<endl;

                        cin >>number;

                        total = sumup(total, number);      //function call

            }

            cout <<" The result is: " <<total <<endl;

 

            return 0;

      }

 

      int sumup(int first, int second)          //function definition

      {

            return  first + second;

      }