Compiling Programs with Two or More Functions

I l @ ve RuBoard

Compiling Programs with Two or More Functions

The simplest approach to using several functions is to place them in the same file. Then just compile that file as you would a single-function file. Other approaches are more system dependent, as the next few sections illustrate .

UNIX

This assumes the UNIX system has the standard UNIX C compiler cc installed. Suppose that file1.c and file2.c are two files containing C functions. Then the following command will compile both files and produce an executable file called a.out :

 cc file1.c file2.c 

In addition, two object files called file1.o and file2.o are produced. If you later change file1.c but not file2.c , you can compile the first and combine it with the object code version of the second file by using this command:

 cc file1.c file2.o 

Linux

This assumes the Linux system has the GNU C compiler gcc installed. Suppose that file1.c and file2.c are two files containing C functions. Then the following command will compile both files and produce an executable file called a.out :

 gcc file1.c file2.c 

In addition, two object files called file1.o and file2.o are produced. If you later change file1.c but not file2.c , you can compile the first and combine it with the object code version of the second file by using this command:

 gcc file1.c file2.o 

DOS Command-Line Compilers

Most DOS command-line compilers work similarly to the UNIX cc command. One difference is that object files wind up with an .obj extension instead of an .o extension. Some compilers produce intermediate files in assembly language or in some other special code instead of object code files.

Windows and Macintosh Compilers

Windows and Macintosh compilers are project-oriented. A project describes the resources a particular program uses. The resources include your source code files. If you've been using one of these compilers, you've probably had to create projects to run one-file programs. For multiple file programs, find the menu command that lets you add a source code file to a project. You should make sure all your source code files (the ones with the .c extension) are listed as part of the project. Be careful, however, not to place your header files (the ones with the .h extension) in a project. The idea is that the project manages which source code files are used, and #include directives in the source code files manage which header files get used.

Using Header Files

If you put main() in one file and your function definitions in a second file, the first file still needs the function prototypes. Rather than type them in each time you use the function file, you can store the function prototypes in a header file. That is what the standard C library does, placing i/o function prototypes in stdio.h and math function prototypes in math.h , for example. You can do the same for your function files.

Also, you will often use the C preprocessor to define constants used in a program. Such definitions hold only for the file containing the #define directives. If you place the functions of a program into separate files, you also have to make the #define directives available to each file. The most direct way is to retype the directives for each file, but this is time-consuming and increases the possibility for error. Also, it poses a maintenance problem: If you revise a #define value, you have to remember to do so for each file. A better solution is to place the #define directives in a header file and then use the #include directive in each source code file.

So it's good programming practice to place function prototypes and defined constants in a header file. Let's examine an example. Suppose you manage a chain of four hotels. Each hotel charges a different room rate, but all the rooms in a given hotel go for the same rate. For people who book multiple nights, the second night goes for 95% of the first night, the third night goes for 95% of the second night, and so on. (Don't worry about the economics of such a policy.) You want a program that enables you to specify the hotel and the number of nights and gives you the total charge. You'd like the program to have a menu that enables you to continue entering data until you choose to quit.

Listings 9.10, 9.11, and 9.12 show what you might come up with. The first listing contains the main() function, which provides the overall organization for the program. The second listing contains the supporting functions, which we assume are kept in a separate file. Finally, Listing 9.12 shows a header file that contains the defined constants and function prototypes for all the program's source files. Recall that in UNIX and DOS environments, the double quotes in the directive #include "hotels.h" indicate that the include file is in the current working directory (typically the directory containing the source code).

Listing 9.10 The usehotel.c control module.
 /* usehotel.c -- room rate program */ /* compile with  Listing 9.11      */ #include <stdio.h> #include "hotel.h" /* defines constants, declares functions */ int main(void) {    int nights;    double hotel;    int code;    while ((code = menu()) != QUIT)    {       switch(code)       {       case 1 : hotel = HOTEL1;                break;       case 2 : hotel = HOTEL2;                break;       case 3 : hotel = HOTEL3;                break;       case 4 : hotel = HOTEL4;                break;       default: hotel = 0.0;                printf("Oops!\n");                break;       }       nights = getnights();       showprice(hotel, nights);    }    return 0; } 
Listing 9.11 The hotel.c function support module.
 /* hotel.c -- hotel management functions */ #include <stdio.h> #include "hotel.h" int menu(void) {    int code, status;    printf("\n%s%s\n", STARS, STARS);    printf("Enter the number of the desired hotel:\n");    printf("1) Fairfield Arms           2) Hotel Olympic\n");    printf("3) Chertworthy Plaza        4) The Stockton\n");    printf("5) quit\n");    printf("%s%s\n", STARS, STARS);    while ((status = scanf("%d", &code)) != 1                (code < 1  code > 5))    {        if (status != 1)           scanf("%*s");        printf("Enter an integer from 1 to 5, please.\n");    }    return code; } int getnights(void) {    int nights;    printf("How many nights are needed? ");    while (scanf("%d", &nights) != 1)    {        scanf("%*s");        printf("Please enter an integer, such as 2.\n");    }    return nights; } void showprice(double hotel, int nights) {    int n;    double total = 0.0;    double factor = 1.0;    for (n = 1; n <= nights; n++, factor *= DISCOUNT)        total += hotel * factor;    printf("The total cost will be $%0.2f.\n", total); } 
Listing 9.12 The hotel.h header file.
 /* hotel.h -- constants and declarations for hotel.c */ #define QUIT       5 #define HOTEL1    50.00 #define HOTEL2    55.00 #define HOTEL3    80.00 #define HOTEL4   100.00 #define DISCOUNT   0.95 #define STARS "**********************************" int menu(void); int getnights(void); void showprice(double, int); 

Here's a sample run:

 ***************************************************************** 1) Fairfield Arms           2) Hotel Olympic 3) Chertworthy Plaza        4) The Stockton 5) quit *****************************************************************  3  How many nights are needed?  1  The total cost will be .00. ***************************************************************** Enter the number of the desired hotel: 1) Fairfield Arms           2) Hotel Olympic 3) Chertworthy Plaza        4) The Stockton 5) quit *****************************************************************  4  How many nights are needed?  3  The total cost will be 5.25. ***************************************************************** Enter the number of the desired hotel: 1) Fairfield Arms           2) Hotel Olympic 3) Chertworthy Plaza        4) The Stockton 5) quit *****************************************************************  5  

Incidentally, the program itself has some interesting features. In particular, the menu() and getnights() functions skip over non-numeric data by testing the return value of scanf() and by using the scanf("%*s") call to skip to the next whitespace. Note how the following excerpt from menu() checks for both non-numeric input and out-of-limits numerical input:

 while ((status = scanf("%d", &code)) != 1         (code < 1  code > 5)) 

This code fragment uses C's guarantee that logical expressions are evaluated from left to right and that evaluation ceases the moment the statement is clearly false. In this instance, the values of code are checked only after it is determined that scanf() succeeded in reading an integer value.

Assigning separate tasks to separate functions encourages this sort of refinement. A first pass at menu() or getnights() might use a simple scanf() without the data verification features that have been added. Then, after the basic version works, you can begin improving each module.

I l @ ve RuBoard


C++ Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 314
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net