Header file
From Wikipedia, the free encyclopedia
In computer programming, especially in the C programming language or C++, a header file or include file is a file that contains one or more declarations, usually in source code form. The intended purpose of these headers is to provide a single point of declaration for identifiers that can be included by any source file that references any of the declared identifiers.
Contents |
[edit] The Problem
Programs are typically broken into pieces in order to make working with them easier. Related function and object definitions are collected into individual source files. Functions and objects defined in a given source file can then be referenced from a second source file by declaring it in the second source file. For example, a function defined in this way in one source file:
int add(int a, int b) { return a + b; }
may be declared (with a function prototype) and then referenced from a second source file in this way:
int add(int, int); int add3(int a, int b, int c) { return add(a, add(b, c)); }
This simple approach to declarations has major problems. Each source file that uses functions or objects defined in a separate source file contains redundant declarations of those functions or objects. If a definition is changed, then each declaration must also be changed in the same way. The compiler has no way to check for consistency between definition and declaration: if a declaration is not updated, or if it is copied incorrectly to start out, then the compiler will not be able to warn the programmer, which leads to undefined behavior.
Header files provide the solution. A header file declares each function, object, and data type that is part of the public interface of a C or C++ module. Each source file that references one of these identifiers then uses a C preprocessor #include
directive to logically include the header file as part of the source file. This reduces the maintenance burden: when a definition is changed, only a single copy of the declaration must be updated (the one in the header file). The header file may also be included in the source file that contains the corresponding definitions, giving the compiler an opportunity to check the declaration and the definition for consistency.
Typically, header files are used to specify only interfaces, with the implementations left in the main code files. They usually consist only of declarations, with definitions (implementations) left to the separate source file, plus documentation. An exception is that the implementations of inline functions are often included in header files, because most C and C++ implementations are not capable of expanding definitions of inline functions that are not present in the preprocessor-expanded translation unit.
Header files are not a panacea: it is still necessary to make largely redundant updates in two places (a source file and a header file) whenever a definition changes. Newer languages (like Java) typically dispense with header files and instead put a little more smarts into the system to see if the changes really have any effect.
When constructing libraries, header files are commonly used to describe the functionality in them, with no need of compiling the library at all, instead it is linked to the resulting object files at the end of the compilation.
Information from C/C++ header files is traditionally brought into other files using the C preprocessor's "#include" directive. To prevent the same header file from being included more than once, an include guard is put around the body of each header file.
[edit] C header file
A C header file is a text file that contains pieces of code written in C programming language syntax, and whose name, by convention, ends with “.h”. A C header file is used inside a program by coding the “#include” preprocessor directive. The syntax for including standard library and implementation-defined header files is:
#include <name.h>
User-defined header files are included with a slightly different syntax:
#include "name.h"
In programs written in C, it is often desirable to separate function declarations, global, static and external variable declarations from the rest of the source code. This provides software developers with three major advantages:
- Organizes the source code into well-defined entities.
- Separates interfaces and implementation of functionality.
- Provides flexibility and better opportunity of reuse.
Header files in C (and C++) are meant exactly for this purpose.
[edit] Examples
Imagine you are writing a program to convert a measurement in miles to kilometers. In order to accomplish this task, you write a function that does the job. Further assume that your implementation of the function is as follows:
programA.c:
#include <stdio.h> const double FACTOR = 1.609344; double cvtMileToKilom( double miles ); int main() { double miles = 0; printf("Enter measurement in Miles:"); scanf("%lf", &miles); printf("%f miles is %f kilometers.\n", miles, cvtMileToKilom( miles ) ); return 0; } double cvtMileToKilom( double miles ) { return FACTOR * miles; }
A few days later you decide to write a program that converts miles to meters. Further assume that you love your previously written code, and you must reuse it for your new project. You have two options. One option is to copy your code and paste it into your new program, like the following:
programB.c
#include <stdio.h> const double FACTOR = 1.609344; double cvtMileToMeter( double miles ); int main(void) { double miles = 0; printf("Enter measurement in Miles:"); scanf("%lf", &miles); printf("%f miles is %f meters.\n", miles, cvtMileToMeter( miles ) ); return 0; } double cvtMileToKilom( double miles ) { return FACTOR * miles; } double cvtMileToMeter( double miles ) { return cvtMileToKilom( miles ) * 1000; }
A better option is to separate your function declaration for cvtMileToKilom from its implementation. Suppose in your first project you structured your program as follows:
programA.h
#ifndef INCLUSION_GUARD_PROGRAM_A_H #define INCLUSION_GUARD_PROGRAM_A_H #define FACTOR 1.609344 double cvtMileToKilom( double miles ); #endif // INCLUSION_GUARD_PROGRAM_A_H
Note, the use of the inclusion guard (in this case the INCLUSION_GUARD_PROGRAM_A_H) prevents multiple inclusion of the same header file.
programA.c
#include "programA.h" double cvtMileToKilom( double miles ) { return FACTOR * miles; }
This way all you need to do for your new project is to include your header file in the new program and compile all of your .c files:
programB.c
#include <stdio.h> #include "programA.h" double cvtMileToMeter( double miles ); int main() { double miles = 0; printf("Enter measurement in Miles:"); scanf("%lf", &miles); printf("%f miles is %f meters.\n", miles, cvtMileToMeter( miles ) ); return 0; } double cvtMileToMeter( double miles ) { return cvtMileToKilom( miles ) * 1000; }
The beauty of this method is that you don’t have to remember how you implemented cvtMileToKilom. All you need to be able to do is to use it, and the #include “programA.h” statement is all you need to access your previous work. No need for copy pasting! This is the basic example of software reuse.
Please note that the code segments provided above are in no way the best way to do the projects. Nor are they examples of good C programming style. Rather they attempt to illustrate the use of header files. There is still a lot of room for improvement. For instance, you could put the function definitions of cvtMiletoMeter and cvtMiletoKilom in a single .c file, for example “conversion.c”. Also put the prototypes of these two functions in one .h file, for example “conversion.h”. This way, you can add more and more functions that convert from one unit to another. Every time you want to do another conversion, you can use your library and the functions available in it.
The idea of header files is not limited to C. For example, interfaces in Java are analogous to C header files.