Fun With Functions


TOPICS:

  1. Why use functions ?
  2. When should I use a function ?
  3. What is a "function prototype" ?
  4. What is a "function declaration" ?
  5. What is a "function definition" ?
  6. What's a "function call" ?
  7. What's a formal parameter ?
  8. What are actual parameters ?
  9. What's a return type ?
  10. What does it mean to send a variable by value ?
  11. What does it mean to send a variable by reference ?
  12. What's a good indication I should be using a function ?


Why use functions ?

Functions are Good.

You've been using functions all along: printf() and scanf() are functions. So is main().

For Example:
When you order your dinner at a restaurant. You tell the waiter your order and he brings you your food when it's ready. The waiter is just like a function. You don't care (not too much) how he gets the order to the chef, how the chef prepares the meal, and how the waiter brings your food back to your table (walks? runs? brings just the appetizer, brings all the food on one giant tray). You just care that you get your food.

In Essence,

And that's the general idea behind using functions.

Use a function whenever you have a sub-task to perform. Hand your variables to the function -- get back the end result of that task and continue the bigger task at hand.

You can also call functions inside other functions.

Our restaurant example has sub-routine functions of it's own:
The waiter tells the chef your order and then gets the final prepared dishes back to take to you. The waiter doesn't handle telling the salad chef to make the salad, or how to do it. The chef does.

The C Standard Libraries provide lots of functions for you to use -- Investigate them and use them. Why reinvent the wheel?

Back to the Topic Index


When should I use functions ?

You can use a function anywhere you want. Your whole main function can be composed of a single function. That function can call another one. All the way down... ML works this way.

You've been using functions all along without knowing it: both scanf() and printf() are functions.

Functions are used anywhere you want code to be repeated. You should never repeat code in your program. If you find yourself writing the same code more than once, you should define a function to handle that part of your program for you. Then each time you want that code to be called, you call your function instead.

Back to the Topic Index


What is a "function prototype" ?

This is the "Function Declaration" of Chapter 9 in our textbook.

When you include functions in your programs, you need to include both the "function declaration" (or "prototype") and the "function definition".

The function prototype list appears above main and lists the functions that you'll be using inside main.

A function prototype tells the compiler the type of data returned by the function, the number of parameters the function expects, the types of each of these parameters and the order to expect them.

That's all you need for the prototype description.

For example:
Say we have a function that we're going to call "char_to_int" that is supposed to take a character as a parameter and return an int value.

The definition is:

You don't need to specify the variable name of the parameter. Just it's type.

You don't need to write the code that tells how you're going to change the char into an int. You just need to specify the return type.

Functions, Function Headers and Function Definitions, REQUIRE COMMENTS.

Back to the Topic Index


What is a "function declaration" ?

This is another way of saying "function prototype".

Back to the Topic Index


What is a "function definition" ?

When you use functions in your programs, you need to include both the function prototypes and the function definitions.

The function definition must match the prototype you declared at the top for your program:

For example:
Say we declared a function called char_to_int" that takes a character as a parameter and returns an int value.

Our definition would have been:

So the function declaration should be:

The definition of your function is the actual code that should be called when your function is called.

Back to the Topic Index


What's a "function call" ?

You call the function whenever you want the function to execute in your program. If you want to print something to the screen, you call printf, and it prints whatever you put between the parentheses. And your program prints it at the point in the execution where the call (the printf statement) appears.

The printf statement is the "call" to the printf function.

Function Calls can happen inside main or any other function.

Knowing what we know about printf, let's try an example:
Say we write a function called "hello" that takes no parameters, and will print "hello" to the screen. We don't need our function to return any information, so it's return type is void.

Function.. Example Code
Prototype void hello( void );
Call
int main () {
hello();
return 0;
}
Definition
void hello( void ){
printf("Hello\n");
}

What happens when you make a program (Don't forget your to include stdio.h at the top!) out of these three pieces? You see the word "hello" printed on your screen. Your hello function calls the printf function. And your function is called by main.

Try it for yourself. Make the sample programs and see what happens.

What happens if our function requires parameters?

Make a function that takes two integers, and returns the max of the two.

Function.... Sample Code
Prototype int max( int, int );
Call
int main () {
int x = 52;
int y = 312;
int z;
z = max( x, y );
printf("The max of %d and %d is %d\n", x, y, z );
return 0;
}
Function
Definition
int max( int a, int b ){
if( a > b ) return a;
else return b;
}

What happens? Your program prints:

The max of 52 and 312 is 312.

What happens if we replace:

printf("The max of %d and %d is %d\n", x, y, z );
with
printf("The max of %d and %d is %d\n", x, y, max(x,y) );

We get the same result. A function can go any place that it's return value is expected. Our max function returns an integer. Our printf statement expects an integer in position three ("%d"). The call to the max function can appear where the z appears in the previous statement.

Try it for yourself. Make more sample programs and see how it works.

Back to the Topic Index


What's a formal parameter ?

Formal parameters are used in the function definition. They're symbolic variable names that appear only in the function's definition code.

From our example in the question about calling functions our sample function definition is:

Function
Definition
int max( int a, int b ){
if( a > b ) return a;
else return b;
}

"a" and "b" as variable names are used inside the max function to describe the action of the function. Inside the function, the two parameters are named "a" and "b". You use "a" and "b" to refer to the two parameters -- any two -- that get sent IN to your function.

"a" and "b" are the symbolic names for the parameters you actually send to the function in the function call.

See an example to see how it works.

What happens in our example? The output will be:

So, Did a == x? And, Did b == y? Our output shows that they did.

Try the example yourself to see how it works.

Remember, formal parameters are symbolic names. These are the names you use to refer to the parameters that actually got sent to the function. If you change "int x" to "int Cornelius", and name your variable "Cornelius" instead of "x", then in the function, "a" will get the same value that "Cornelius" had when it was sent in the function call. Inside the function, you don't refer to "Cornelius" (how could you possibly keep track of all the possibilities for variable names by building functions?), you always refer to the symbolic name "a". Printf and scanf don't care what you name your variables, and they still get the job done.

Formal parameters determine whether a variable is sent to a function by value or by reference.

Back to the Topic Index


What are actual parameters ?

The Actual parameters are exactly that. These are the parameters you use when you actually make the function call.

You don't care what the formal parameters are when you make the function call. You just send the actual variables you want to send to the function.

From our example in the question about calling functions our sample function prototype and code are:

Function
Prototype
int max( int, int ){
Call
int main (){
int x = 52;
int y = 312;
int z;
z = max( x, y );
printf("The max of %d and %d is %d\n", x, y, z );
return 0;
}

You're calling the max function from main. And you want to know the max of the two variables -- x and y -- that you're using in main.

When we were talking about the function definition, we only cared about the symbolic formal parameter names. We didn't care variables were used in the call to our function.

We know that printf and scanf don't care what variables get sent to them. You can send "x" as easily as "y" as easily as "DrZaius".

int x;
int y;
int DrZaius;
scanf("%d %d %d", &x, &y, &DrZaius );
printf("%d %d %d", x, y, DrZaius );;

Printf and scanf work just fine with whatever variable name you give it. You don't care what the internals of printf look like, just so long as the job gets done.

When you make a function call, you send the variables that you actually want to go into that function. You send x, y and DrZaius. These are the ACUTAL variables you care about. They are the Actual Parameters.

Try an example yourself to see how it works.

Now try example #2 and see what happens if we reverse the order that our actual parameters get sent to the function.

Back to the Topic Index


What's a return type ?

The return type of a function is the type of the value the function returns.

In the example we used in the question about calling functions, we made a function called max that returned the largest of two integers. Since we were returning an integer (the largest integer of two other integers), our return type is "int". We could make the same function with a different return type. We could use float We could even use char.

Some examples of different prototypes for different types:

All the items in bold are the return types for the different functions.

If we don't want to return a value at all. Say we're just making a function to group a bunch of printf statements, then our return type is "void".

There are some restrictions on what you can use as for a return type, but it doesn't affect what you're doing now and I'll get into that later. For now, you can return any of the types we know, EXCEPT an array.

One thing to note: If you don't specify a return type for your function, the compiler assumes your return type is int and it will complain -- giving you strange errors because you haven't returned an int from your function. If you don't want to return a value from your function be sure to specify void as your function's return type.

For this class, you'll get marked off if you don't use void to specify (1) a void return type, or (2) no parameters.

Think of "main":

Main has a return type: it's "int". That's why at the end of main you always include your return statement (0 is an int). Main has no parameters -- actually a void parameter list. The parameters of main are listed between the parentheses "()". There's nothing there. Parameter list is assumed to be void. However, for this class you must specify a void parameter list: "( void )".

A void parameter list:

Back to the Topic Index


What does it mean to send a variable by value ?

This is the only way parameters are truly passed in C. To pass a variable by reference you have to do a little monkeying.

When you say a parameter is "passed by value", you're refering to what gets transfered from the actual parameter to the formal definition parameter. When you say "by value", you mean that the "VALUE" of the actual parameter gets transferred to the function's formal parameter.

Function
Prototype
int max( int, int );
Function
Call
int main () {
int x = 52;
int y = 312;
int z;
z = max( x, y );
printf("The max of %d and %d is %d\n", x, y, z );
return 0;
}
Function
Definition
int max( int a, int b ){
if( a > b ) return a;
else return b;
}

The values stored in x (52) and y (312), get transfered to the formal parameters of the max function. Inside max, 'a' gets the value in x ( a = x = 52 ) and 'b' gets the value in y ( b = y = 312 ). "a" and "b" don't care about the names of x or y, nor do they care where in memory they're located. "a" and "b" only care what the values in 'x' and 'y' are.

The compiler does this work for you. You do not need to worry HOW "a" and "b" get the values of "x" and "y". You just put "x" and "y" in as the actual parameters of the function call, and the compiler will make the link between them and "a" and "b".

ALL you need to know is that the VALUE in the ACTUAL Parameter DOES GET TRANSFERED to the FORMAL Parameter and passed into the function.

Try the sample programs to see for yourself.

Back to the Topic Index


What does it mean to send a variable by reference ?

Variables in C are not Truly passed by reference. At least, not in the same way they are in other programming languages.

In C, when you say a parameter is "passed by reference", you're refering to what sort of relationship you're passing between the function and the calling-variables.

Let's do this in steps. To pass a variable by reference, you pass a reference to it's location in memory. To understand how to "pass a reference" you need to know a little about pointers.

Notice that our prototype and our definition now take pointers to ints and not the ints themselves. We want a pointer to a location in memory because inside our function, we want to be able to change the values of the variables we sent to the function. Notice also, that now in our call to the function, we don't simply send 'x' and 'y', but we use the address operator ('&'), and send the address of x ("&x") and the address of y ("&y") to the function. Notice that 'a' and 'b' in the function definition are NOT ints. They are "pointers to ints".

Function
Prototype
int max_plus( int*, int* );
Function
Call
int main () {
int x = 52;
int y = 312;
int z;
printf("Going to take the max of x = %d and y = %d\n", x, y );
z = max( x, y );
printf("The max of %d and %d is %d\n", x, y, z );
printf("After the call: x = %d, y = %d\n", x, y );
return 0;
}
Function
Definition
int max_plus( int* a, int* b ){
int temp;
if( *a > *b ) temp = *a;
else temp = *b;
*a = 16;
*b = 87;
return temp;
}

What does our output look like?

'x' and 'y' change after the function executes because inside the function, '*a' and '*b' change those values (see the page on pointers if you don't understand why).

This is what is meant by "Passed by Reference". You pass the value of the address of the variable to the function, so you can reach the variable outside the function so if you change it inside the function, it will remain changed outside it.

Try the sample programs to see for yourself.

Back to the Topic Index


What's a good indication I should be using a function ?

A nice rule of thumb is that whenever you have more lines for a function (or main) than fit on one screen, you should be using a function to handle a chunk of the subroutine you're writing.

Back to the Topic Index


Back to the Top of this Page


Back to the Top of this page


[Back to the Index]

graphics images Copyright 1998-2003 Elizabeth Fraley HTML code copyright 1998-2003 Elizabeth Fraley. Permission is given to provide these pages in their original, unaltered form online for educational purposes. They may not be republished or included on a CDROM, disk or other media or with any published work without the express permission of the copyright holder (this includes FAQ books).