Introduction to C Functions
From this article you can take advantage of your computer's repetitive nature by looking at your programs in a new way—as a series of small routines that execute whenever you need them, however many times you require. This article approaches its subject a little differently from previous articles. It concentrates on teaching the need for writing your own functions, which are modules of code that you execute and control from the main() function. So far, all programs in this article have consisted of a single long function called main().
This article stresses the use of structured programming, sometimes called modular programming. C was designed to make it easy to write your programs in several modules instead of as one long program. By breaking the program into several smaller routines (functions), you can isolate problems, write correct programs faster, and produce programs that are easier to maintain.
This article make you understand the following basics:
• The need for functions
• How to trace functions
• How to write functions
• How to call and return from functions
Function Basics
When you approach an application that needs to be programmed, it is best not to sit down at the keyboard and start typing. Rather, you should first think about the program and what it is supposed to do. One of the best ways to attack a program is to start with the overall goal, and then divide this goal into several smaller tasks. You should never lose sight of the overall goal, but you should think also of how individual pieces can fit together to accomplish such a goal.
When you finally do sit down to begin coding the problem, continue to think in terms of those pieces fitting together. Don't approach a program as if it were one giant problem; rather, continue to write those small pieces individually.
This does not mean that you must write separate programs to do everything. You can keep individual pieces of the overall program together—if you know how to write functions. This way, you can use the same functions in many different programs.
C programs are not like QBasic or FORTRAN programs. C was designed to force you to think in a modular, or subroutine-like, functional style. Good C programmers write programs that consist of many small functions, even if their programs execute one or more of these functions only once. But those functions work together to produce a program quicker and easier than if the program had to be written from scratch.
Rather than code one very long program, you should write several smaller routines, called functions. One of those functions must be called main(). The main() function is always the first to execute. It doesn't need to be first in a program, but it usually is.
Breaking Down Problems
If your program does very much, break it into several functions. Each function should do one primary task. For example, if you were writing a C program to get a list of characters from the keyboard, alphabetize them, and then print them to the screen, you could—but shouldn't—write all that into one big main() function, as the following C skeleton (program outline) shows:
main()
{
/*
C code to get a list of characters
C code to alphabetize the characters
C code to print the alphabetized list on the screen
*/
return 0;
}
This skeleton is not a good way to write this program. Even though you could type this program in only a few lines of code, it would be much better to get in the habit of breaking up every program into distinct tasks. You should not use main() to do everything—in fact, you should use main() to do little except call each of the functions that do the work.
A better way to organize this program is to write a separate function for each task the program is supposed to do. This doesn't mean that each function should be only one line long. Rather, it means you should make every function a building block that performs only one distinct task in the program.
The following program outline shows you a better way to write the program just described:
main()
{
getletters(); /* Calls a function to get the numbers */
alphabetize(); /* Calls a function to alphabetize
letters */
printletters(); /* Calls a function to print letters
onscreen */
return 0; /* Return to the operating system */
}
getletters()
{
/* :
C code to get a list of characters
: */
return 0; /* Returns to main() */
}
alphabetize()
{
/* :
C code to alphabetize the characters
: /*
return 0; /* Returns to main() */
}
printletters()
{
/* :
C code to print the alphabetized list on the screen
: */
return 0; /* Returns to main() */
}
The program outline shows you a much better way of writing this program. It is longer to type, but much better organized. The only thing the main() function does is control the other functions by showing in one place the order in which they are called. Each separate function executes its instructions, and then returns to main(), whereupon main() calls the next function until no more functions remain. The main() function then returns control of the computer to the operating system.
The first function called main() is what you previously used to hold the entire program. From this point, in all but the smallest of programs, main() simply controls other functions that do the work.
These listings are not examples of real C programs; instead, they are skeletons, or outlines, of programs. From these outlines, it is easier to develop the actual full program. But before going to the keyboard to write a program such as this, you should know that there will be four distinct sections: a primary function-calling main() function, a keyboard data-entry function, an alphabetizing function, and a printing function.
You should never lose sight of the original programming problem and, with the approach just described, you never do. Look again at the main() calling routine in the preceding program. Notice that you can glance at main() and get a feel for the overall program, without the remaining statements getting in the way. This is a good example of structured, modular programming. A large programming problem has been broken down into distinct, separate modules called functions, and each function performs one primary job in a few C statements.
Considering More Function Basics
Little has been said about naming and writing functions, but you probably understand much of the goals of the previous listing already. C functions generally adhere to the following rules:
1. Every function must have a name.
2. Function names are made up and assigned by the programmer (you!) following the same rules that apply to naming variables; they can contain up to 31 characters, they must begin with a letter, and they can consist of letters, numbers, and the underscore (_) character.
3. All function names have one set of parentheses immediately following them. This helps you (and C) differentiate them from variables. The parentheses might or might not contain something. So far, all such parentheses in this article have been empty.
4. The body of each function, starting immediately after the closing parenthesis of the function name, must be enclosed by braces. This means that a block containing one or more statements makes up the body of each function.
Although the outline shown in the previous listing is a good example of structured code, it can be further improved—and not only by putting the actual C statements inside the program to make it work. You can improve this program also by using the underscore character (_) in the function names. Do you see how get_letters() and print_letters() are much easier to read than are getletters() and printletters()? Then again, if you use uppercase letters, you may prefer to capitalize each word in the function name after the initial once, such as getLetters() and printLetters(). The selection of uppercase and lowercase or the underscore in function and variable names depends solely on the programmer's preference.
The following listing shows you an example of a C function. You can already tell quite a bit about this function. You know, for instance, that it isn't a complete program because it has no main() function. (All programs must have a main() function.) You know also that the function name is calcIt because parentheses follow this name. These parentheses happen to have something in them. You know also that the body of the function is enclosed in a block of braces. Inside that block is a smaller block, the body of a while loop. Finally, you recognize that the return statement is the last line of the function:
calcIt(int n)
{
/* Function to print the square of a number */
int square;
while (square
{ square = n * n;
printf(''The square of %d is %d \n", n, square);
n++; } /* A block within the function */
return 0;
}
Calling and Returning Functions
I think till now You have been reading much about "function calling" and "returning control." in this article. Although you may already understand these phrases from their context, you can probably learn them better through an illustration of what is meant by a function call.
A function call in C is like a detour on a highway. Imagine you are traveling along the "road" of the primary function called main() and then run into a function-calling statement. You must temporarily leave the main() function and go execute the function that was called. After that function finishes (its return statement is reached), program control reverts to main(). In other words, when you finish a detour, you end up back on the "main" route and continue the trip. Control continues as main() calls other functions.
Example
A complete C program, with functions, should make this clear. The following program prints several messages to the screen. Each message printed is determined by the order of the functions. Before worrying too much about what this program does, take a little time to study its structure. You should be able to see three functions defined in the program: main(), nextFun(), and thirdFun(). A fourth function is used also, but it is the built-in C printf() function. The three defined functions appear sequentially, one after the other. The body of each is enclosed in braces, and each has a return statement at its end:
/* FUN1.C
The following program illustrates function calls */
#include
main() /* main() is always the first C function executed */
{
printf(''First function called main() \n");
nextFun(); /* Second function is called here */
thirdFun(); /* This function is called here */
printf("main() is completed \n"); /* All control
returns here */
return 0; /* Control is returned to
the operating system */
} /* This brace concludes main() */
nextFun() /* Second function;
parentheses always required */
{
printf("Inside nextFun() \n"); /* No variables are
defined in the program */
return 0; /* Control is now returned to main() */
}
thirdFun() /* Last function in the program */
{
printf("Inside thirdFun() \n");
return 0; /* Always return from all functions*/
Output
The output of this program follows:
First function called main()
Inside nextFun()
Inside thirdFun()
main() is completed
Figure 1 shows a tracing of this program's execution. Notice that main() controls which of the other functions is called, as well as the order of the calling. Control always returns to the calling function after the called function finishes.
Figure 1: Use this figure to follow this function call trace.
To call a function, simply type its name—including the parentheses—and follow it with a semicolon. Remember that semicolons follow all executable statements in C, and a function call (sometimes called a function invocation) is an executable statement. The execution is the function's code being called. Any function can call any other function. It just happens that main() is the only function that calls other functions in this program.
Now, you can tell that the following statement is a function call:
printTotal();
Because printTotal is not a C command or built-in function name, it must be a variable or a written function's name. Only function names end with the parentheses, so it must be a function call or the start of a function's code. Of the last two possibilities, it must be a call to a function because it ends with a semicolon. If it didn't have a semicolon, it would have to be the start of a function definition.
When you define a function (that is, when you type the function name and its subsequent code inside braces), you never follow the name with a semicolon. Notice in the previous program that main(), nextFun(), and thirdFun() have no semicolons when they appear in the body of the program. A semicolon follows their names only in main(), where these functions are called.
Example
Suppose you are writing a program that does the following. First, it asks users for their departments. Next, if they are in accounting, they should receive the accounting department's report. If they are in engineering, they should receive the engineering department's report. And if they are in marketing, they should receive the marketing department's report.
The skeleton of such a program follows. The code for main() is shown in its entirety, but only a skeleton of the other functions are shown. The switch statement is a perfect function-calling statement for such multiple-choice selections:
/* Skeleton of a departmental report program */
#include
main()
{
int choice;
do
{ printf(''Choose your department from the
following list\n");
printf("\t1. Accounting \n");
printf("\t2. Engineering \n");
printf("\t3. Marketing \n");
printf("What is your choice? ");
scanf(" %d", &choice);
} while ((choice3)); /* Ensure 1, 2,
or 3 */
switch choice
{ case(1): { acctReport(); /* Call accounting function */
break; } /* Don't fall through */
case(2): { engReport(); /* Call engineering function */
break; }
case(3): { mtgReport(); /* Call marketing function */
break; }
}
return 0; /* Program returns to the operating system
when finished */
}
acctReport()
{
/* :
Accounting report code goes here */
: */
return 0;
}
engReport()
{
/* :
Engineering report code goes here */
: */
return 0;
}
mtgReport()
{
/* :
Marketing report code goes here */
: */
return 0;
}
The bodies of switch statements normally contain function calls. You can tell that these case statements execute functions. For instance, acctReport(); (which is the first line of the first case) is not a variable name or a C command. It is the name of a function defined later in the program. If users enter 1 at the menu, the function called acctReport() executes. When it finishes, control returns to the first case body, whose break statement causes the switch statement to end. The main() function returns to DOS (or to your integrated C environment if you are using one) when its return statement executes.