Functions

Don’t write the same code twice.

  1. Define and call a function.
    Secret Agent Man: lyrics and audio.
    1. function1.C has all its code in the main function.
    2. function2.C has one function named chorus, in addition to the main function.
      The empty parentheses () means that we are not attempting to carry any information from the main function down to the chorus function.
      The void means that we are not attempting to carry any information back from the chorus function back up to the main function.
  2. Colored versions. The code that belongs down in the function (and the expressions that call the function) is in orange.
    1. function1.html
    2. function2.html

Factorials

The product of all the integers from 1 to n is called n factorial, and is written n! with an exclamation point. Here are two examples:

3! = 1 × 2 × 3 = 6        
4! = 1 × 2 × 3 × 4 = 24

One use of a factorial is to tell us how many orders n objects can be arranged in. n objects can be arranged in n! different orders. For example, the three objects a, b, c can be arranged in 6 different orders, and the four objects a, b, c, d can be arranged in 24 different orders:

  1. a, b, c
  2. a, c, b
  3. b, a, c
  4. b, c, a
  5. c, a, b
  6. c, b, a
  1. a, b, c, d
  2. a, b, d, c
  3. a, c, b, d
  4. a, c, d, b
  5. a, d, b, c
  6. a, d, c, b
  7. b, a, c, d
  8. b, a, d, c
  9. b, c, a, d
  10. b, c, d, a
  11. b, d, a, c
  12. b, d, c, a
  13. c, a, b, d
  14. c, a, d, b
  15. c, b, a, d
  16. c, b, d, a
  17. c, d, a, b
  18. c, d, b, a
  19. d, a, b, c
  20. d, a, c, b
  21. d, b, a, c
  22. d, b, c, a
  23. d, c, a, b
  24. d, c, b, a

Scope and allocation

  1. automatic.C: create a variable f within the {curly braces} of a function body.

Scope

In the above program, we created the variable f within the {curly braces} of the factorial function. When we create a variable within any pair of {curly braces}, we can mention the name of the variable only within those curly braces. We therefore say that the variable has local scope. In the above program, for example, the variable f could not be mentioned in the main function.

Allocation

In the above program, we created the variable f within the {curly braces} of the factorial function. When we create a variable within any pair of {curly braces} as the computer executes the program, the variable stays alive only until the computer reaches the closing curly brace }; at that point the variable dies. (Here’s what “death” means: when a variable dies, it stops holding a value.) We therefore say that the variable is automatically allocated. In the above program, for example, the variable f dies as we return form the factorial function to the main function.

If the computer executes the code within the {curly braces} a second time, then the variables created within the braces are reincarnated. In the following excerpt, for example, a variable named j is born holding the value 2. After it dies, another variable named j is born holding the value 4. The two j’s are two different variables, living at different times and holding different values. They just happen to have the same name and data type.

	for (int i {1}; i <= 2; ++i) {   //The loop iterates 2 times.
		int j {2 * i};
		cout << j << "\n";
	}

Arguments and return value

  1. argument.C: pass an argument to a function.
    A formal argument vs. an actual argument.
    A function should begin by checking the values of its actual arguments.
  2. A function with more than one argument.
    1. graphpaper1.C: pass four arguments from the main function to the graphPaper function.
    2. graphpaper2.C: the main function calls the graphPaper function, which calls the line function. Error checking omitted for brevity.
  3. retval.C
    Exercise. In the main function of retval.C, call the factorial function 13 times to output the following table of factorials.
            for (int i {0}; i <= 12; ++i) {
                    cout << setw(2) << i << " " << setw(9) << factorial(i) << "\n";
            }
    
    and remember to #include <iomanip> for setw.
     0         1
     1         1
     2         2
     3         6
     4        24
     5       120
     6       720
     7      5040
     8     40320
     9    362880
    10   3628800
    11  39916800
    12 479001600
    
  4. pi.C: a function named pi that returns an approximation of the value of π. The argument n of the function specifies how much work the function should do; more work gives a better approximation. We saw this algorithm in the old pi.C; now it is neatly packaged here. The main function concentrates on formatting the nice output table; the pi function concentrates on the numerical computation.

Use functions to make the code more localized.

  1. A function that returns true if a year is leap.
    1. leap1.C: write all the code in the function.
    2. leap2.C: make a separate function named is_leap.
  2. Colored versions.
    1. leap1.html
    2. leap2.html
  3. A stack of strings: last hired, first fired.
    1. stack1.C: a simplified version of the stack.C we saw earlier, with all the code written in the main function.
    2. stack2.C: separate functions to push and pop the stack. The contents of the stack are held in variables of global scope and static allocation. These variables live as long as the program is running.
  4. Colored versions.
    1. stack1.html
    2. stack2.html

Combine local scope with static allocation.

  1. Statically allocated variables. Count how many times a function has been called.
    1. static1.C: the function has amnesia every time we return from it.
    2. static2.C: introduce a static variable to avoid amnesia.

References: two ways of talking about the same value

  1. reference1.C: a reference (r) to a variable (j).
    Using the reference, we can read and write the value of the variable.
  2. reference2.C: demonstrate pass-by-value vs. pass-by-reference.
    Using the reference, a function can read and write the value of a variable passed as an argument to a function.
  3. referencedate.C: Using three reference arguments, a function can return three answers. Also, more examples of static variables inside a function.
    Exercise.
    In referencedate.C, make the last argument of the function travel optional. Change the function declaration at the top of the program to
    void travel(int& month, int& day, int& year, int distance = 1);
    
    Then change the statement that calls this function to
    	travel(month, day, year);   //distance defaults to 1
    
    Only trailing arguments can be made optional.

Recursion: another way of looping

  1. recursion1.C: output the ints from 1 to 10 inclusive with a for loop.
  2. recursion2.C: output the ints from 1 to 10 inclusive without any loop at all.
    Note that no variable changes its value: we never use = or ++ at all.
  3. recursion3.C: let the user specify the end point as well as the starting point.
  4. The four steps in doing recursion:
    1. Create a separate function to do the work, instead of doing the work in the main function.
    2. In this separate function, do only one part of the job, not the entire job.
    3. Do the rest of the job by calling the same function, passing it an argument that shows that part of the job has already been accomplished.
    4. Write an if statement that prevents the function from calling itself if the job is already done.
  5. factorial1.C: output the product of the ints from 1 to 10 inclusive with a for loop.
  6. factorial2.C: output the product of the ints from 1 to 10 inclusive without any loop at all.
  7. maze.C: find a path through a maze by using recursion.
    Exercise.
    To output the path with a red background color on the screen of storm.cis.fordham.edu, change
    				cout << a[row][col];
    
    in maze.C to
    				if (a[row][col] == '.') {
    					cout << "\033[48;5;9m.\033[0m"; //red background
    				} else {
    					cout << a[row][col];
    				}
    
    These crazy binary codes are the xterm-256color control codes. For example, 48 for background, 38 for foreground; 9 for red, 10 for green, etc.
    Or instead of editing the C++ program, simply pipe the output of the program through the “stream editor” sed and have it look for every period (.):
    jsmith@storm:~$ ./a.out | sed $'s/\./\033[48;5;9m.\033[0m/g'
    

    Exercise.
    Find the shortest path from 'B' to 'E', not just any path. Have the function f return the length of the path (or numeric_limits<int>::max() if there is no path), not just true or false. Give the function an additional argument, a bool named retract, that will cause the function to erase the path it found (i.e., change the periods back to blanks). Then have the for loop in f select the shortest path of the four possibilities, not just any path that if finds.