Wrox Press C++ Tutorial
All the examples we have seen so far have been fairly simple programs in just one file, but in general, your C++ programs will consist of multiple files. Two basic kinds of files are involved:
.h (note that some older systems use .hpp).cpp, and will contain your code that will compile to machine instructions - primarily function definitions.
As we have seen, the standard header files for library functions in ANSI C++ (for example, iostream) have no extension. Of course, there may be other kinds of files supporting the environment in which you are programming (defining resources of one kind or another, perhaps) but the .h and .cpp files are the ones that will contain all your C++ code.

The essential difference between a header file and a .cpp file is in how each is used. By convention:
.cpp files contain code that determines what your program does (primarily function definitions) - that is, the logic of your program.h files contain your function declarations (that is, the prototypes, but not the definitions), type definitions and pre-processor directives.h file.cpp must #include any header files that it needs.cpp files, which will incorporate the contents of the #included header files as necessary
Each .cpp file that you compile will produce an object file. The term 'object file' has nothing to do with class objects (we'll meet those in the next chapter). An object file is simply a file that contains the binary output from the compiler; it is often identified with the extension .obj. The object files are combined by the linker into a single executable module, that usually has the extension .exe.
So far, we have used only header files which provide the declarations necessary for using the standard library. Our program examples have been short and simple; consequently, they have not warranted the use of separate header files, which contain our function declarations or constant definitions. In Chapter 7, when we begin to define our own data types, the need for header files will become apparent. A typical practical C++ program will involve a number of header files and .cpp files.
If your program consists of several files, the connection between a function call in one source file, and the function definition in another, is established (or resolved) by the linker. Before the linker acts, the compiler will compile a call to the function - to do this, it extracts the necessary information from the function prototype (which must occur before the function call is made). The compiler doesn't really mind whether the function's definition occurs in the same file, or in another .cpp file - the linker will sort it out.
Variable names are different. If you want to use a name to access a variable from within a function body, and the variable is defined outside the function body, then you must declare the variable using the extern keyword.
Let's see how this works by looking at an example. Suppose we have variables defined as global in a file file1.cpp using the statements:
double pi = 3.14159265;
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
These statements define the variable pi and the array days[], so there cannot be duplicate definitions for the same variables elsewhere. However, we can access these variables from another function in a different source file (or, for that matter, in the same source file), by declaring the variables as external. For example, a function in the file file2.cpp will contain the following statements:
extern double pi; // Variable is defined in another file
extern int primes[]; // Array is defined in another file
These statements do not create the variables - they merely identify that they are defined elsewhere, so the compiler does not expect to find them within the present scope. The variables are used in file2.cpp, but their actual locations are determined by their definitions in file1.cpp. This connection will be established by the linker when the object files are linked together.
Of course, if you declare a name as external, and its corresponding definition is not found, then you will get an error message from the linker and no executable module will be created.
In the above example, you'd probably want to avoid the possibility of these variables being altered. Therefore you might consider making each of them const when you define them in file1.cpp:
const double pi = 3.14159265;
const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
However, declaring them as const will have the effect of making them unavailable in other translation units. You can override this by using the extern keyword when you define them:
extern const double pi = 3.14159265;
extern const int primes[] = {2, 3, 5, 7,
11, 13, 17, 19, 23, 29, 31};
These statements still define the const double and the const char array. The use of the keyword extern here tells the compiler that these variable names should have external linkage, even though they are consts.
Now, when you want to access these in file2.cpp, you must declare them as const, as well as external:
extern const double pi; // Variable is defined in another file
extern const int primes[]; // Array is defined in another file
Within the block in which these declarations appear, the use of the names pi and primes will refer to the constants defined in the other file. Clearly, you can have as many declarations for external variables as you want. Of course, any external variable of a given type can only have one definition in a program.
Global variables can be useful for constant values that you want to share. Indeed, by sharing constant values across all of the program files that need access to them, you can ensure that the same values are being used for the constants throughout your program. However, in general you should be aware of the disadvantages in declaring a variable as global. If your function uses a global variable, then it has an external dependency, which means that it is no longer a nice clean self-contained package of code. This makes for messy program structure, and limits the degree to which your function can be reused in another program.
Global variables are always initialized. If you don't supply an initial value for a global variable, it will be initialized with 0.