In this article we will discuss how to define, declare and call C functions. Before writing of large and complex programs, one should remember that our program should be readable, understandable, easily debugged and easily modified. Therefore the idea is to break a large problem into subproblems that can be handled more easily. If the subproblem is still a bit complex, it can be further divided it into smaller subproblems. This process continues until each subproblem can not be further divided. For example – in a magical matrixes problem, one module could read data items into matrix, one could display these data items, one could provides the result of two matrices, other may add diagonal elements of a matrix, and so on. These subproblems are referred to as modules. 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. C is basically a collection of functions in which main() is an essential function. The C functions you have used so far, such as printf and scanf, are built into the C libraries. However, in C you can also write our own functions to organize and simplify large and complex programs. This article describes how to define, declare and call C functions. 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: { /* : 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; }
Functions In C Breaking Down Problems
main()
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:
- Every function must have a name.
- 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.
- 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.
- 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
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.
Function Calls
A function is called in much the same way it is declared. Any function is called through a function call. A function call is an expression that transfers the control and actual arguments, if any, to a function. The syntax of a typical function call is:
func-name (list-of-actual-arguments);
Here the func-name is the name of the function to be called and the list-of-actual-arguments contains a list of the actual arguments (separated by commas) passed to the function. If the function takes no argument, the list-of-actual-arguments can be empty. The first argument in the list is always correspond to the first formal parameter of the function, the second one corresponds to the second formal parameter and so on through the list.
After the execution of the function call, the control is transferred to the first statement in the function. The control is returned back from the called function to the caller when the called function encounters a return statement. If no return statement is executed, the control is returned back after the execution of the last statement of the called function. In such cases, the return value is undefined.
One main point to note here is that when the called function uses the copies of the actual arguments, any change it makes to the formal arguments do not affect the values of the variables from which the copies may have been made.