# Class 16: Functions I

Sections 4.1-4.3 and 5.1 of Problem Solving with C++

Lecture

## Motivating Example

Sometimes there is a particular chunk of code that appears over and over again in a program. For example, if we're writing a program to compute gcd's, we'd ask the user twice to enter in a positive number. This program illustrates how we'd have to do it. Now, there are plenty of nice functions in standard libraries, like `sqrt` and `cos` that do all sorts of nice things for us. If only there were a function `getposint` that would get a positive integer from the user and return it to our program, we could rewrite our program as:

 `int main()``{``  int a = getposint(), b = getposint();``  ``  // Compute gcd``  while(b != 0)``  {``    int r = a % b;``    a = b;``    b = r;``  }`` ``  // Write out gcd``  cout << "The gcd is " << a << endl;`` ``  return 0;``}`` `` `

This is a tremendous improvement! Unfortunately, such a function is not a part of any of the standard libraries. Therefore, it's up to us to make it!

Projectile Height Example:  In this program, a function is used to compute a projectile's height given an initial velocity and launch angle.  The launch angle is specified in degrees.  Notice that the chore of converting degrees to radians is relegated to the function.

## Prototypes

You should have noticed when looking at documentation for the `cmath` library that they give a description of the function like:

`double cos(double x); `

This is called a prototype. It tells you (and it tells the compiler) that `cos` takes an object of type `double` (that's the `x`) and returns or evaluates to an object of type `double`. It doesn't tell you how or what it's doing, but it does tell you that something like

`cos("Go Navy")`

is not going to make sense, since `"Go Navy"` has type `string`, not type `double`. Similarly, something like

`if (cos(3*z) && k < 0)`

isn't going to make sense, since the && operator expects an object of type `bool` and the `cos``(3*z)` evaluates to an object of type `double`. When you define functions of your own, you need to define a prototype as well. It must be defined outside of the `main` block, and it must appear before you ever use the function. Now, in the `getposint` function we'd envisioned earlier, there's nothing that the function takes as input from the program, and it should evaluate to or return the positive integer it's read in from the user, so the right prototype would be:

`int getposint();`

## Function Definitions

In addition to giving the function prototype, you have to provide a function definition, which is what tells the computer what the function is supposed to do. The function's definition can appear anywhere after the prototype. You repeat the prototype (without the ';') and then give a block of code that comprises the function. Just as the `return` statement in main leaves the program, a `return` statement in your function body leaves the function. Instead of `return`ing 0 however, we'll return whatever value the function's supposed to give. So our `getPosInt` function will have the following definition:

`int getPosInt()`
`{`
`  int k;`
`  cout << "Enter a positive integer: ";`
`  cin >> k;`
`  while(k <= 0)`
`  {`
`    cout << "I said *positive*, try again: ";`
`    cin >> k;`
`  }`
` `
`  return k;`
`}`

The function definition also has to appear outside of the `main` block. This program gives a complete picture of how to rewrite our GCD calculator to make use of a `getposint` function.

## Scope and Functions

There's some room for confusion with functions when the same name pops up in different places. For example, consider this program:

 `int f();`` ``int main()``{``  int a, b;``  a = 0;``  b = f();``  cout << "a = " << a << endl;`` ``  return 0;``}`` `` ` `int f()``{``  int a = 2;``  return -1;``}`` `` `

What gets printed out? On the one hand, I'd say "0", since `a` just got assigned that value. On the other hand, the function `f` is called in between, and there I see `a` being given the value 2. So which is it? The answer is that "0" gets printed out. It all goes back to scope. The `a` in `main` does not exist outside of `main`, and likewise the `a` in the function `f` does not exist outside of `f`. These variables are two different objects that happen to have the same name. Since they are in different scopes, however, there is no confusion or conflict. We say that variables like this are local to the functions in which they are defined, i.e. they don't exist outside of the functions in which they are defined.

## Functions with an argument

More interesting are functions which take an argument, i.e. some kind of input object. For example, we may often be in the situation of having to compute something like the factorial of a number. Especially if this crops up more than once in a program, it'd be really nice to have a function like the `pow` or `sqrt` functions from `cmath` to do the factorial for us. First, we need a prototype that specifies that our function (we'll call it `factorial`) takes an integer value and returns an integer value:

`int factorial(int);`

From this point on in our program we can use the `factorial` function. However, somewhere along the way we'll actually have to define the function --- something like this:

`int factorial(int x)`
`{`
`  int f = 1;`
`  while (x > 0)`
`  {`
`    f = f*x;`
`    x--;`
`  }`
`  return f;`
`}`

Notice that here we give a name to the `int` value that gets passed into the function, so that we can reference it within the body of the function definition. Values that get passed in to a function in C++ are called function arguments. It's important to note that the arguments are passed by value, meaning that you get a copy of the value of the variable `function` is called with, not the variable itself. So, for example, if our `main` function looked like

`main()`
`{`
`  int y = 4;`
`  cout << factorial(y) << endl;`
`  cout << y << endl;`
` `
`  return 0;`
`}`

The result would be 24 followed by 4. Although the argument `x` in the function definition does get modified, the variable `y` does not, because `y`'s value (i.e. 4) got passed to `factorial`, not the variable `y` itself. So pass by value means that a copy of the object appearing in the function call is what gets passed along to the function, not the object itself.

Remember also that scoping rules show us that any variable named `x` or `f` in `main` have no relation to the `x` and `f` in the `factorial` function. To reiterate, pass-by-value means that you get a copy of the argument. By analogy, calling the "haircut function" with argument "MIDN Jones" would 1) cause a clone to be made of MIDN Jones, 2) cause the clone's hair to get cut, and 3) cause the clone to get destroyed after the haircut. Thus, when MIDN Jones showed up in class the next day, his hair would still be shaggy.

## Functions that return nothing

Sometimes we're interested in functions that return nothing at all. These functions are called for their side effects. This is an issue for our prototype, however, since we need to specify something for return type. In this case, we use `void` in place of a return type. Here's a Navy-Centric example.  Note that void just means that no value is returned as the result of the function call

`void printGreetings();`
` `
`int main()`
`{`
`  printGreetings();`
` `
`  return 0;`
`}`
` `
`void printGreetings()`
`{`
`  cout << "G R E E T I N G S !" << endl << endl;`
`  cout << "We are Navy, hear us roar" << endl`
`       << "Watch the game a while and you’ll see us score." << end;`
`}`
`    `

This function is only used for the side effect of writing something on the screen, not for any value it would return (motivational content aside).

## Problems

1.     Marathon Times

2.     Date Calculator

3.     Approximating e