## Part 4. Functions

You'll use functions everywhere in C. They are a handy way to make your code simpler and easier to read. Functions also make difficult problems easier to tackle by breaking the big problem into smaller chunks.

Throughout this video series, we've seen `main`

as a function, but we haven't yet learned how to define your own functions. But now we're ready!

You define a function the same way you define the `main`

function: indicate its type, then name the function followed by parentheses. And you put your function statements inside curly braces. End your function with a `return`

to pass a final value back to the calling program. For example, a trivial "Hello world" function would look like this:

```
int
hello()
{
puts("Hello world");
return 0;
}
```

Having written that function, you can call it in your program the same way you would call the other standard C functions we've used: just list its name.

```
#include <stdio.h>
int
hello()
{
puts("Hello world");
return 0;
}
int
main()
{
hello();
return 0;
}
```

You can write the function the same way you would write the `main`

function. Define any variables you need at the start of your function. A neat feature with functions is that any variable name you use in a function is separate from variables you use in other functions, or even the `main`

function. Variables are *local in scope*, which means that if you define a variable as part of a function, it's only part of that function. You can even give a variable in a function the same name that you used in the `main`

function.

Here's a simple example, where we call a function named `loophello`

from a `for`

loop. The iteration variable `iter`

is used in both `main`

and the `loophello`

function:

```
#include <stdio.h>
int
loophello()
{
int iter;
/* print Hello three times */
for (iter = 1; iter <= 3; iter = iter + 1) {
printf("%d - Hello!\n", iter);
}
return 0;
}
int
main()
{
int iter;
/* loop three times */
for (iter = 1; iter <= 3; iter = iter + 1) {
printf("Loop %d\n", iter);
loophello();
}
return 0;
}
```

Sample output from this program:

```
Loop 1
1 - Hello!
2 - Hello!
3 - Hello!
Loop 2
1 - Hello!
2 - Hello!
3 - Hello!
Loop 3
1 - Hello!
2 - Hello!
3 - Hello!
```

Pass values to a function using *arguments*. You define them in the parentheses of your function definition. For example, this sample function will add 1 to the integer that's passed to it, and print that number to the screen before returning.

```
int
addone(int i)
{
int n;
/* add one to the number and print it */
n = i + 1;
printf("n is %d\n", n);
/* return the value of i+1 */
return n;
}
```

Variables defined this way also have another feature: they don't keep their values between calls to the function. If you call the `addone`

function multiple times with the same argument, `addone`

will always print the same value.

```
#include <stdio.h>
int
addone(int i)
{
int n;
/* add one to the number and print it */
n = i + 1;
printf("n is %d\n", n);
/* return the value of i+1 */
return n;
}
int
main()
{
addone(1);
addone(1);
addone(1);
return 0;
}
```

If you compile this program and run it, you'll see that it always prints the same value of `n`

. That's because `n`

is always one more than the value of the argument that was passed to it, and we always called `addone`

with 1.

```
n is 2
n is 2
n is 2
```

If you need to pass additional values to your function, the easiest way is to add more arguments to your function. Separate each variable definition in your function declaration with a comma. For example, here is a simple function that prints a sequence of numbers between two `start`

and `stop`

numbers:

```
#include <stdio.h>
int
sequence(int start, int stop)
{
int iter;
/* print a list of numbers from 'start' to 'stop' */
for (iter = start; iter <= stop; iter = iter + 1) {
printf("%d ", iter);
}
printf("\n");
return 0;
}
int
main()
{
int i;
/* print five sequences of ten numbers, starting at 1, 2, 3, 4, 5 */
for (i = 1; i <= 5; i = i + 1) {
sequence(i, i + 10);
}
return 0;
}
```

If you compile and run this sample program, you will see this list of numbers:

```
1 2 3 4 5 6 7 8 9 10 11
2 3 4 5 6 7 8 9 10 11 12
3 4 5 6 7 8 9 10 11 12 13
4 5 6 7 8 9 10 11 12 13 14
5 6 7 8 9 10 11 12 13 14 15
```

In the sample programs I've shown so far, I've been careful to write the functions *before* the first time they are called in the `main`

function. Doing so means the compiler "knows" about the function and how you should call it by the time it is actually used in the program.

But this is not always possible. And sometimes, you may find it more convenient to write your `main`

function first in the file, then write the functions that `main`

needs to call. When you do this, you need to tell the compiler how each function is called. To do this, you need to write a *function declaration*, which is just a one-line definition of your function and the variables it uses as parameters. Here's the same program from above, written with the `main`

function first, then the `sequence`

function. When you write your programs this way, put the function declarations after the `#include`

statements and before the `main`

function:

```
#include <stdio.h>
int sequence(int start, int stop);
int
main()
{
int i;
/* print five sequences of ten numbers, starting at 1, 2, 3, 4, 5 */
for (i = 1; i <= 5; i = i + 1) {
sequence(i, i + 10);
}
return 0;
}
int
sequence(int start, int stop)
{
int iter;
/* print a list of numbers from 'start' to 'stop' */
for (iter = start; iter <= stop; iter = iter + 1) {
printf("%d ", iter);
}
printf("\n");
return 0;
}
```

Technically, the function declaration does not need to use the same variable names as the function itself. We could just as easily written `int sequence(int a, int b);`

for the declaration and that would have worked fine. However, it's a good idea to use the same variable names, so you (the programmer) don't get confused when you look at the code again later.

### Functions help tackle large problems

Functions allow you to tackle a large problem and make it more manageable by breaking it up into chunks. Each "chunk" is a function that has specific functionality.

Functions also help make your code easier to read. For example, do you remember the "even" program that asked the user for a value, then printed whether or not that number was even or odd? The `if`

test used a modulo (`%`

) operator to test if the number was even. We can improve on the "is it even?" program by using a function to test if a number is even.

The `is_even`

function does the same modulo calculation, and returns the value of the test. The `if`

statement in the `main`

function uses this value to test if the number is even:

```
#include <stdio.h>
int
is_even(int i)
{
/* print a message so we know we made it into the function */
puts("[is_even]"); /* debugging */
/* test if the number i is even; return True if it is */
return (i % 2 == 0);
}
int
main()
{
int num;
do {
puts("Enter a number: (0 to quit)");
scanf("%d", &num);
if (is_even(num)) {
printf("%d is even\n", num);
}
else {
printf("%d is odd\n", num);
}
} while (num != 0);
return 0;
}
```

You can call a function anywhere in your program—even inside other functions. But be careful about a function calling itself. This is called *recursion* and is allowed in C. When using a recursive function, it's important that the function break down the problem by one "step," and that the function should have a defined "stopping point."

Knowing when to stop is critical. Otherwise, your program will loop forever.

Here's an example of a recursive function. The Fibonocci Sequence is defined in mathematics as an iteration, where each iteration is the sum of the two iterations before it. And the "Fibonacci" of 0 and 1 are defined as and 1, respectively. (You cannot have negative values in the Fibonacci sequence.)

```
#include <stdio.h>
int
fib(int i)
{
/*
Fibonacci sequence
fib(0) = 0;
fib(1) = 1;
fib(n) = fib(n-1) + fib(n-2);
for any n greater than or equal to zero
... but really for any n >= 2
*/
switch (i) {
case 0:
return 0;
break;
case 1:
return 1;
break;
default:
return (fib(i - 1) + fib(i - 2));
}
}
int
main()
{
int n;
int result;
puts("Enter number to start Fibonacci sequence:");
scanf("%d", &n);
if (fib >= 0) {
result = fib(n);
printf("fib(%d) = %d\n", n, result);
}
else {
puts("error! Number must be 0 or greater");
}
return 0;
}
```

### Standard C library of functions

Now that we've learned about functions and how to write your own functions, let's go back to examine the functions that we've been using from the standard C libray. These are all defined in that `stdio.h`

that we keep using at the start of our programs:

- puts("string")
- Prints a string to the user
- printf("%d, %d, %d, …", a, b, c, …)
- Prints a formatted string, using a format string with
`%`

placeholders to define values - scanf("%d …", &var …)
- Scans (reads) a value from the user, using a format to define what kind of value to read

The `stdio.h`

is actually called a *header file* or *include file* and contains a bunch of definitions for functions that control input and output. The "io" in the name stands for "input" and "output." The "std" in the name is an abbreviation for "standard" because these are part of the *standard C library* of functions.

There are lots of other useful functions in the standard C library. A few others that you will find immediately useful are:

- getchar()
- Get a single character from the user. This is a better way to read a character than
`scanf`

. This actually returns an`int`

value, but you can treat it like a`char`

character value. - putchar(int ch)
- Put a single character back to the user, usually to the screen unless the user has redirected the output of the program to a file (at the command line, when they run the program). The character is stored in an
`int`

value but you can think of it as just a single character.

And a few other standard C library functions from the `stdlib.h`

header file, which you might find useful now:

- rand()
- Returns a random
`int`

somewhere between 0 and a very large number, defined by`RAND_MAX`

(which is`#define`

'd elsewhere in the`stdlib.h`

file). - srand(int seed)
- Sets the "seed" value of the random number generator. Use this before calling the
`random()`

function. - exit(int status)
- Exits the program with a status code. This is similar to calling
`return status;`

in your`main`

function, but you can call`exit`

anywhere in your program—even in other functions. If things go really wrong in a function, you can end the program with`exit`

. But try to write your programs so only`main`

is the function that exits the program, using`return`

. - abs(int num)
- Returns the absolute value of a number. If you give
`abs`

a negative number, the function will return the positive value of it.

If your program relies on mathematical functions, especially trigonometry, you might be interested in these useful standard C library functions that are defined in the `math.h`

header file. These all return `double`

values, which we learned in Part 2. Introduction to C programming are double-precision floating point values:

- sin(double x)

sinh(double x)

asin(double x) - The sine and hyperbolic sine of a radian angle
*x*. Also the arc sine of*x*, in radians. - cos(double x)

cosh(double x)

acos(double x) - The cosine and hyperbolic cosine of a radian angle
*x*. Also the arc cosine of*x*, in radians. - tan(double x)

tanh(double x)

atan(double x) - The tangent and hyperbolic tangent of a radian angle
*x*. Also the arc tangent of*x*, in radians. - atan2(double y, double x)
- Another way to calculate the arc tangent. Returns the arc tangent in radians of
*y/x*and places the result in the correct quadrant. - pow(double x, double y)
- The value of
*x*raised to the power of*y*. For example,`pow(2.0, 3.0)`

is the same as 2³ ("two cubed") and`pow(4.0, -1.0)`

is the same as ¼ ("one-quarter"). - sqrt(double x)
- The square root of
*x*. This is basically the same as calling`pow(x, 0.5)`

because any value raised to ½ is the square root. Be careful about square roots of negative numbers. - exp(double x)
- The value of ℯ raised to the power of
*x*, where ℯ is the mathematical constant 2.718281… This is basically the same as calling`pow(2.718281, x)`

- log(double x)
- The natural logarithm function, using ℯ. For example,
`x = exp(3.0)`

followed by`log(x)`

will return`3.0`

. - log10(double x)
- The base-10 logarithm function.

If you are using `math.h`

functions with the GCC compiler, you will need to compile with `-lm`

at the end of your command line. This will link (`-l`

) the math library, called `libm`

somewhere on your system. For example, using IA-16 GCC on DOS:

```
I16GCC -Wall -o MYMATH.EXE MYMATH.C -lm
```

..and GCC on Linux:

```
gcc -Wall -o mymath mymath.c -lm
```

Other C compilers may not require this extra step, and may recognize that it needs to link the math library automatically. I mention it because I'm using the GCC compiler in my videos. If in doubt, check the manual for your compiler.

### PRACTICE

Now that you've learned about the basics of writing C functions, let's practice that with a few exercises:

#### Practice program 1.

Write a program that calculates the factorial of a number, using a function `int fact(int n)`

. The factorial (𝓃!) of a non-negative integer 𝓃 is defined as the product (multiplication) of that number times all the numbers down to 1. The factorial of zero (0!) is 1, and the factorial of one (1!) is also 1. For example, the factorial of five (5!) is 5×4×3×2×1.

#### Practice program 2.

Write a program that calculates the factorial of a number, using a *recursive* function `int fact(int n)`

. This recursive function should calculate `fact(n)`

for any non-negative `n`

as `n * fact(n-1)`

, where `fact(0)`

is 1.

*For each practice program 1 and 2, what should you return for the factorial of a negative number?*

#### Practice program 3.

In Part 3. Flow control, we wrote a simple version of the FreeDOS PAUSE command, using `scanf`

to read input from the user, one character at a time. Re-write the FreeDOS PAUSE command without using `scanf`

. Display a prompt "Press Enter to continue…" and call the `getchar`

function until you find a newline (`\n`

) character.