A .h file is a header file that holds declarations — the names and shapes of functions and data that other code files will use
When a programmer writes code in C or C++, they often split their work across multiple files. A .h file (short for "header") is the file that tells other code files what tools are available to use. Think of it like a table of contents: it lists what exists and what it does, without showing all the detailed instructions inside.
The actual work — the code that makes those tools do something — lives in a separate .cpp or .c file. The .h file just says "this function exists, it takes these inputs, and it returns this output." When another file needs to use that function, it reads the .h file first to understand what it can ask for.
Without .h files, a programmer would have to copy and paste function descriptions into every single file that needed them. With .h files, the description lives in one place, and every other file can reference it.
Key Takeaways
- A .h file declares functions and data structures without writing out all their internal code, so other files know what tools are available.
- The actual working code lives in a .cpp or .c file; the .h file is just the interface or instruction manual for using it.
- When you write #include "filename.h" at the top of a file, you are telling the compiler to read that header and use its declarations.
- Header files prevent duplicate code and make it easier for multiple programmers to work on the same project without stepping on each other's work.
- Most programming projects have dozens or hundreds of .h files, each describing a different piece of the system.
How a .h file connects to a .cpp file
A .h file and its matching .cpp file work as a pair. The .h file is the public face — it shows what the code can do. The .cpp file is the backstage area — it contains all the actual instructions.
For example, imagine a file called calculator.h. It might contain:
int add(int a, int b); int subtract(int a, int b);
This tells any other file: "There is a function called add that takes two whole numbers and gives back a whole number. There is also a function called subtract that does the same thing." But it does not say how those functions work.
The matching file calculator.cpp contains the actual code:
int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; }
When the compiler builds the program, it reads the .h file to understand what is available, then reads the .cpp file to see how it actually works. If another file needs to add two numbers, it includes the .h file and calls the add function — it does not need to know or care what is inside calculator.cpp.
Why programmers use #include to read header files
At the very top of most code files, you will see lines like #include "myfile.h" or #include <stdio.h>. This is how a programmer tells the compiler "go read that header file and bring its declarations into this file."
The angle brackets < > mean "this is a standard library header that came with the compiler." The quotation marks " " mean "this is a header file I wrote or my project wrote." The compiler treats them slightly differently — it looks for standard headers in a system folder, and for project headers in the current folder or a folder the programmer specified.
Without the #include line, the compiler would not know that a function exists, and it would refuse to compile the code. The #include is how you say "I am using code from somewhere else, so read the instructions first."
What goes inside a .h file
A .h file contains declarations — the names, inputs, and outputs of functions and data structures, but not the working code. It also often contains definitions of straightforward data structures that multiple files need to understand.
For example, a .h file might declare that a data structure called Person has a name, an age, and an address. Every file that works with people needs to know this structure exists and what it contains. Rather than describe it in every file, the .h file describes it once, and every other file reads that description.
A .h file typically does not contain the full code for functions — that lives in the .cpp file. If a .h file contained all the working code, you would have to copy it into every file that used it, which would make the program larger and slower to compile.
Header guards prevent the same code from being read twice
Sometimes a .h file gets included multiple times by accident. If file A includes file B, and file B includes file C, and file A also includes file C directly, then file C gets read twice. This can cause errors because the compiler sees the same declarations twice and gets confused.
To prevent this, programmers use header guards — special lines at the top and bottom of a .h file that say "only read this file once per compilation." A typical header guard looks like:
#ifndef CALCULATOR_H #define CALCULATOR_H [declarations go here] #endif
The first time the compiler reads this file, it sees #ifndef CALCULATOR_H (which means "if CALCULATOR_H is not defined"), and it is not, so it continues. It then defines CALCULATOR_H with #define. The second time the same file is included, the compiler sees that CALCULATOR_H is already defined, so it skips the whole thing and moves on. This prevents duplicate declarations.
How .h files organize large projects
In a small program, you might have one .h file and one .cpp file. In a real project — a web browser, a video game, a database — there are hundreds or thousands of files. The .h files act as a map: they tell you what each piece of the system does without forcing you to read all the code.
A large project might have a folder structure like this: a .h file for graphics, a .h file for sound, a .h file for user input, a .h file for game logic. Each .h file describes one piece. A programmer working on graphics only needs to read the graphics .h file to understand what functions are available; they do not need to understand the sound code at all.
This separation also makes it possible for multiple programmers to work on the same project. One person can write the graphics code, another can write the sound code, and they only need to agree on what the .h files say. As long as each person's .cpp file matches their .h file, the whole project fits together.
The difference between .h files and .cpp files in practice
A .h file is a contract: it promises that certain functions exist and behave a certain way. A .cpp file is the fulfillment of that contract: it actually makes those functions work. If you change the .cpp file but keep the .h file the same, other files do not need to change — they still see the same interface.
This is powerful because it means you can improve the code inside a .cpp file without breaking anything that depends on it. You can make it faster, fix a bug, or rewrite it completely — as long as the .h file stays the same, everything else still works.
If you change the .h file — for example, by adding a new function or changing what inputs a function takes — then every file that includes that .h file needs to be recompiled. This is why programmers are careful about changing .h files: a small change can force a large recompilation.
Frequently Asked Questions
Do I need a .h file for every .cpp file?
Not always. Small programs or internal helper files sometimes skip the .h file. But if other files need to use code from a .cpp file, that .cpp file should have a matching .h file so other files know what is available. Most real projects have a .h file for every .cpp file that other code depends on.
What happens if I include a .h file that does not match its .cpp file?
The compiler will not catch this when ready — it only reads the .h file to understand what should exist. When it tries to link the files together at the end, it will fail because the .cpp file does not actually contain what the .h file promised. This is called a linker error, and it means the .h and .cpp files are out of sync.
Can a .h file include another .h file?
Yes, and this is common. If one piece of code needs to use another piece, its .h file will include the other .h file. As long as you use header guards, the compiler will not get confused by multiple includes.
Why not just put everything in one file?
You can, but it becomes a problem as the project grows. A single file with thousands of lines of code is hard to navigate, slow to compile, and difficult for multiple programmers to work on. Splitting into .h and .cpp files lets you organize code by what it does and compile only the parts that changed.
Is a .h file the same thing as a library?
A library is a collection of .h and .cpp files packaged together for reuse. A .h file is just one file. You might use a library by including its .h files, but a single .h file is not a library by itself.