Function Prototypes. McGraw-Hill The Complete Reference Fourth Edition
Anuncio
Anuncio
C h a p t e r 6 : F u n c t i o n s
155
The main advantage to recursive functions is that you can use them to create clearer and simpler versions of several algorithms. For example, the Quicksort algorithm is difficult to implement in an iterative way. Also, some problems, especially ones related to artificial intelligence, lend themselves to recursive solutions. Finally, some people seem to think recursively more easily than iteratively.
When writing recursive functions, you must have a conditional statement, such as an if, somewhere to force the function to return without the recursive call being executed. If you don't, the function will never return once you call it. Omitting the conditional statement is a common error when writing recursive functions. Use printf( ) liberally during program development so that you can watch what is going on and abort execution if you see a mistake.
Function Prototypes
In C++ all functions must be declared before they are used. This is normally accomplished using a function prototype. Function prototypes were not part of the original C language.
They were, however, added when C was standardized. While prototypes are not technically required by Standard C, their use is strongly encouraged. Prototypes have always been required by C++. In this book, all examples include full function prototypes.
Prototypes enable both C and C++ to provide stronger type checking, somewhat like that provided by languages such as Pascal. When you use prototypes, the compiler can find and report any illegal type conversions between the type of arguments used to call a function and the type definition of its parameters. The compiler will also catch differences between the number of arguments used to call a function and the number of parameters in the function.
The general form of a function prototype is
type func_name(type parm_name1, type parm_name2,. . ., type parm_nameN);
The use of parameter names is optional. However, they enable the compiler to identify any type mismatches by name when an error occurs, so it is a good idea to include them.
The following program illustrates the value of function prototypes. It produces an error message because it contains an attempt to call sqr_it( ) with an integer argument instead of the integer pointer required. (It is illegal to convert an integer into a pointer.)
/* This program uses a function prototype to enforce strong type checking. */ void sqr_it(int *i); /* prototype */ int main(void)
{
156
C + + : T h e C o m p l e t e R e f e r e n c e int x; x = 10; sqr_it(x); /* type mismatch */
} return 0; void sqr_it(int *i)
{
*i = *i * *i;
}
A function's definition can also serve as its prototype if the definition occurs prior to the function's first use in the program. For example, this is a valid program.
#include <stdio.h>
/* This definition will also serve as a prototype within this program. */ void f(int a, int b)
{ printf("%d ", a % b);
} int main(void)
{ f(10,3);
} return 0;
In this example, since f( ) is defined prior to its use in main( ), no separate prototype is required. While it is possible for a function's definition to serve as its prototype in small programs, it is seldom possible in large ones
⎯especially when several files are used. The programs in this book include a separate prototype for each function because that is the way C/C++ code is normally written in practice.
The only function that does not require a prototype is main( ), since it is the first function called when your program begins.
Because of the need for compatibility with the original version of C, there is a small but important difference between how C and C++ handle the prototyping of
C h a p t e r 6 : F u n c t i o n s
157 a function that has no parameters. In C++, an empty parameter list is simply indicated in the prototype by the absence of any parameters. For example, int f(); /* C++ prototype for a function with no parameters */
However, in C this prototype means something different. For historical reasons, an empty parameter list simply says that no parameter information is given. As far as the compiler is concerned, the function could have several parameters or no parameters. In
C, when a function has no parameters, its prototype uses void inside the parameter list.
For example, here is f( )'s prototype as it would appear in a C program.
float f(void);
This tells the compiler that the function has no parameters, and any call to that function that has parameters is an error. In C++, the use of void inside an empty parameter list is still allowed, but is redundant.
In C++, f( ) and f(void) are equivalent.
Function prototypes help you trap bugs before they occur. In addition, they help verify that your program is working correctly by not allowing functions to be called with mismatched arguments.
One last point: Since early versions of C did not support the full prototype syntax, prototypes are technically optional in C. This is necessary to support pre-prototype
C code. If you are porting older C code to C++, you may need to add full function prototypes before it will compile. Remember: Although prototypes are optional in C, they are required by C++. This means that every function in a C++ program must be fully prototyped.
Standard Library Function Prototypes
Any standard library function used by your program must be prototyped. To accomplish this, you must include the appropriate header for each library function. All necessary headers are provided by the C/C++ compiler. In C, the library headers are (usually) files that use the .H extension. In C++, headers may be either separate files or built into the compiler itself. In either case, a header contains two main elements: any definitions used by the library functions and the prototypes for the library functions. For example,
stdio.h
is included in almost all programs in this part of the book because it contains the prototype for printf( ). The headers for the standard library are described in Part Three.
Descargar
Anuncio