Section 11.4. Multimodule Programs


[Page 404 (continued)]

11.4. Multimodule Programs

The trouble with the way that I built the reverse program is that the reverse function cannot easily be used in other programs. For example, let's say that I wanted to write a function that returns 1 if a string is a palindrome, and 0 if it is not. A palindrome is a string that reads the same forward and backward; for example, "noon" is a palindrome, and "nono" is not. I could use the reverse function to implement my palindrome function. One way to do this is to cut-and-paste reverse () into the palindrome program file, but this is a poor technique for at least three reasons:

  • Performing a cut-and-paste operation is tedious.

  • If we came up with a better piece of code for performing a reverse operation, we'd have to replace every copy of the old version with the new version, which is a maintenance nightmare.

  • Each copy of reverse () uses up disk space.

As I'm sure you realize, there's a better way to share functions.

11.4.1. Reusable Functions

A better strategy for sharing reverse () is to remove reverse () from the reverse program, compile it separately, and then link the resultant object module into whichever programs wish to use it. This technique avoids all three of the problems listed in the previous section and allows the function to be used in many different programs. Functions with this property are called reusable.

11.4.2. Preparing a Reusable Function

To prepare a reusable function, create a source code module that contains the source code of the function, together with a header file that contains the function's prototype. Then compile it into an object module by using the -c option of gcc. An object module contains machine code together with symbol-table information that allows it to be combined with other object modules when an executable file is being created. Here is a listing of our new filesfirst, "reverse.h":


[Page 405]

1  /* REVERSE.H */ 2 3  int reverse (); /* Declare but do not define this function */ 


Here is a listing of the new "reverse.c":

1  /* REVERSE.C */ 2 3  #include <stdio.h> 4  #include "reverse.h" 5 6  /****************************************************************/ 7 8  reverse (before, after) 9 10  char *before; /* A pointer to the original string */ 11  char *after; /* A pointer to the reversed string */ 12 13  { 14    int i; 15    int j; 16    int len; 17 18    len = strlen (before); 19 20    for (j = len - 1, i = 0; j >= 0; j--, i++) /* Reverse loop */ 21      after[i] = before[j]; 22 23    after[len] = 0; /* terminate reversed string */ 24  } 


Here's a listing of a main program that uses reverse ():

1  /* MAIN1.C */ 2 3  #include <stdio.h> 4  #include "reverse.h" /* Contains the prototype of reverse () */ 5 6  /****************************************************************/ 7 8  main () 9 10  { 11    char str [100]; 12 13    reverse ("cat", str); /* Invoke external function */ 14    printf ("reverse (\"cat\") = %s\n", str); 
[Page 406]
15 reverse ("noon", str); /* Invoke external function */ 16 printf ("reverse (\"noon\") = %s\n", str); 17 }


11.4.3. Separately Compiling and Linking Modules

To compile each source code file separately, use the -c option of gcc. This creates a separate object module for each source code file, each with a ".o" suffix:

$ gcc -c reverse.c     ...compile reverse.c to reverse.o. $ gcc -c main1.c       ...compile main1.c to main1.o. $ ls -lG reverse.o main1.o -rw-r--r--  1 ables      311 Jan  5 18:08 main1.o -rw-r--r--  1 ables      181 Jan  5 18:08 reverse.o $ _ 


Alternatively, you can place all of the source code files on one line:

$ gcc -c reverse.c main1.c      ...compile each .c file to .o file. $ _ 


To link them all together into an executable called "main1", list the names of all the object modules after the gcc command:

$ gcc reverse.o main1.o -o main1   ...link object modules. $ ls -lG main1                     ...examine the executable. -rwxr-xr-x  1 ables    24576 Jan  5 18:25 main1* $ ./main1                          ...run the executable. reverse ("cat") = tac reverse ("noon") = noon $ _ 


In UNIX environments, one often used the stand-alone linking loader (ld) to link separate modules. gcc can do this job, and it includes many default library references that would be painful to have to manually determine and add to your command line. You can see the work gcc does by adding the -v option to the command line to generate verbose output.

11.4.4. Reusing the Reverse Function

Now that you've seen how the original reverse program may be built out of a couple of modules, let's use the reverse module again to build the palindrome program. Here's the header and source code listing of the palindrome functionfirst, "palindrome.h":

1  /* PALINDROME.H */ 2 3  int palindrome (); /* Declare but do not define */ 



[Page 407]

Here is our file "palindrome.c":

1  /* PALINDROME.C */ 2 3  #include "palindrome.h" 4  #include "reverse.h" 5  #include <string.h> 6 7  /****************************************************************/ 8 9  int palindrome (str) 10 11  char *str; 12 13  { 14    char reversedStr [100]; 15    reverse (str, reversedStr); /* Reverse original */ 16    return (strcmp (str, reversedStr) == 0); /* Compare the two */ 17  } 


Here's the source code of the program "main2.c" that tests the palindrome function ():

1  /* MAIN2.C */ 2 3  #include <stdio.h> 4  #include "palindrome.h" 5 6  /****************************************************************/ 7 8  main () 9 10  { 11    printf ("palindrome (\"cat\") = %d\n", palindrome ("cat")); 12    printf ("palindrome (\"noon\") = %d\n", palindrome ("noon")); 13  } 


The way to combine the "reverse", "palindrome", and "main2" modules is as before: compile the object modules and then link them. We don't have to recompile "reverse.c", as it hasn't changed since the "reverse.o" object file was created.

$ gcc -c palindrome.c     ...compile palindrome.c to palindrome.o. $ gcc -c main2.c         ...compile main2.c to main2.o. $ gcc reverse.o palindrome.o main2.o -o main2    ...link them. $ ls -lG reverse.o palindrome.o main2.o main2 -rwxr-xr-x  1 ables       24576 Jan  5 19:09 main2* -rw-r--r--  1 ables         306 Jan  5 19:00 main2.o 
[Page 408]
-rw-r--r-- 1 ables 189 Jan 5 18:59 palindrome.o -rw-r--r-- 1 ables 181 Jan 5 18:08 reverse.o $ ./main2 ...run the program. palindrome ("cat") = 0 palindrome ("noon") = 1 $ _





Linux for Programmers and Users
Linux for Programmers and Users
ISBN: 0131857487
EAN: 2147483647
Year: 2007
Pages: 339

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