Including Files in the C Computer Language
Part 40 of the Complete C Course
Foreword: Including, Files, C, Computer, Language
By: Chrysanthus Date Published: 22 Jun 2024
Joining two Related Files
#include <stdio.h>
#define anInt 44
int it = 66;
int myFn(int inte)
{
return inte;
}
int main(int argc, char *argv[])
{
int ret1 = myFn(anInt);
int ret2 = myFn(it);
printf("%i %i\n", ret1, ret2);
return 0;
}
The output is 44 66. Notice that there are two preprocessing directives in the program: "#include <stdio.h>" and "#define anInt 44". Note that the preprocessing directives do not end with semicolons; as they should not. To compile this file, the user will type at the command prompt:
gcc -o program.exe file.c
and press Enter, where "program.exe" is the name of the binary file (executable), given by the programmer, and "file.c" is the name of the source (text) file, also given by the programmer. The executable file would be run as:
./program.exe
pressing Enter after typing the command.
The program can be split into two halves: The C main() function definition, becomes the bottom half and the rest of the code above becomes the top half. The bottom half is saved with the name, first.c, for first file that has the main() function. The top half is saved as second.c . The only additional code in the first file to enable both files work together, would be
#include "second.c"
So the content of the lower half becomes:
#include "second.c"
int main(int argc, char *argv[])
{
int ret1 = myFn(anInt);
int ret2 = myFn(it);
printf("%i %i\n", ret1, ret2);
return 0;
}
The top half remains unchanged, as follows:
#include <stdio.h>
#define anInt 44
int it = 66;
int myFn(int inte)
{
return inte;
}
When does the programmer use the angle brackets, <> with the #include directive, and when does he/she use the double quotes, "". The angle brackets are used with files that come with the compiler installation. Double quotes, "" are used with user (programmer) created files. The files, first.c and second.c are saved in the same directory (the user's home directory). To compile the files into one program, the user will type at the command prompt,
gcc -o program.exe first.c
The result is the same as with the un-separated file. The #include directive, has included the whole of its argument file, into the position, where it was typed. So, second.c did not have to be quoted in the command line.
Prototype
int myFn(int inte);
int myFn(int inte)
{
return inte;
}
Header File
A header file has prototypes for functions, and not the function definitions themselves. The function definitions are found in the different normal files, or in a library. A function is defined only once. The same function is not defined in different files. The header file may have as well, a few fundamental object declarations, such as for int, and float objects. It typically has function prototypes. It is these header features that link the different source files.
So, a header file has prototypes. It may have a few fundamental object declarations, with or without the associated definitions (initialized values). Today, a header file may also have struct and union declarations, without definitions, because definitions occupy more space. Each definition of a struct or union will be codded only once. The definition will be coded only in one of all the files, or in a library.
Now, in the application with all the files combined, the header is included in each file that needs the body of the function or struct or fundamental initialization; this also concerns the file with the C main() function. There are usually more than one header file; not necessarily all included in all files. So, it is the header files that connect the files in a C application. Avoid including full and related files at the top of one another. Use headers, to combine files.
A header file for the above first.c and second.c files would be:
#define anInt 44
int myFn(int inte);
This file can be created and saved as "head.h". The first.c file would have the content,
#include <stdio.h>
#include "head.h"
int main(int argc, char *argv[])
{
int it = 66;
int ret1 = myFn(anInt);
int ret2 = myFn(it);
printf("%i %i\n", ret1, ret2);
return 0;
}
The reason why "int it = 66;" has been brought into the C main() function, will be explained shortly. The second.c file would have the content,
#include <stdio.h>
#include "head.h"
int myFn(int inte)
{
return inte;
}
Both the first.c and the second.c files include two header files. They do not include full related files. stdio.h is in angle brackets, because it comes with the big C library. The big C library consists of sub (or smaller) libraries, like the stdio and stdlib libraries. The files that form the application, will be compiled as follows:
gcc -o app.exe first.c second.c
The executable file is called app.exe. Although it is finally a long file, see it as a broad file. The two files, first.c and second.c are in the command line. Press Enter after typing. Note that the header files, stdio.h or head.h are not in the command line. This is because they have already been included in the two files. The output, when app.exe is executed (run), will be the same: 44 66. The application (broad program), would be run (executed) at the command line, with:
./app.exe
The reader should test all the above code, as they are related.
The extern Reserved Word
extern int it;
A header file content can be,
#define anInt 44
extern int it;
int myFn(int inte);
extern struct Accountants {char *name; int age; float salary; char *HQ;} employee1;
The extern reserved word, does not allow initialization. Each separate file then has the responsibility to re-declare the same variable, with initialization. The extern struct declaration has just been included above, for completeness of an application example. Its identifier of interest, is employee1, and not Accountants. The content of a first.c file would be:
#include <stdio.h>
#include "head.h"
int it = 66;
int main(int argc, char *argv[])
{
int ret1 = myFn(anInt);
int ret2 = myFn(it);
printf("%i %i\n", ret1, ret2);
return 0;
}
The variable "it", has been re-declared in the file scope of the first.c file. Since the extern reserved word, does not allow initialization, the #define preprocessing directive, still has a place in today's C programming. It is typically used, as constants, today.
Recall: extern is a storage-class specifier. The content of second.c file would become,
#include "head.h"
struct Accountants employee1;
int myFn(int inte)
{
employee1.name = "John Smith";
employee1.age = 30;
employee1.salary = 1234.12;
employee1.HQ = "Msc";
return inte;
}
It is left as an exercise for the reader, to save the new first.c and new second.c; then compile and run.