C — Header Files
C — Header Files

C — Header Files

Created on:
Team Size: 1
Tool Used: C/GCC

A header file (.h) declares the interface of your code — function prototypes, types, constants, and macros — so that multiple .c files can share them without duplicating declarations.

Why Header Files

In C, you must declare a function before calling it. When a project grows beyond one file, repeating declarations in every .c is error-prone. A header file centralises them:

project/
├── main.c
├── math_utils.c
└── math_utils.h

math_utils.h declares what math_utils.c provides. main.c includes the header and gains access to those declarations without needing to know the implementation.

What Goes in a Header

Put in .hKeep in .c
Function prototypesFunction bodies
typedef / struct definitionsLocal variables
#define constants and macrosstatic helpers
extern variable declarationsVariable definitions

Never put function bodies or variable definitions in a header — they would be compiled multiple times if the header is included in several files.

A Minimal Header

/* math_utils.h */
#ifndef MATH_UTILS_H
# define MATH_UTILS_H

int add(int a, int b);
int sub(int a, int b);
int clamp(int val, int min, int max);

#endif

The three lines around the content are the include guard — explained below.

Include Guards

If a header is included more than once in the same translation unit (directly or through another header), the compiler would see duplicate declarations and error. An include guard prevents this:

#ifndef MATH_UTILS_H   // if not yet defined...
# define MATH_UTILS_H  // ...define this token...

/* all your declarations */

#endif                 // end of guarded block

On the first inclusion the token is undefined, so the block is processed and the token is defined. On any subsequent inclusion the token already exists, so the entire block is skipped.

The token name is conventionally the filename in uppercase with . replaced by _.

#include — Angle Brackets vs Quotes

#include <stdio.h>    // system / standard library header
#include "my_file.h"  // your own header (searched relative to the source file first)
SyntaxSearch path
<header.h>system include paths (GCC’s standard library locations)
"header.h"current directory first, then system paths

Always use quotes for your own headers and angle brackets for standard library ones.

Sharing Types and Constants

Headers are the right place for types and constants that multiple files need:

/* types.h */
#ifndef TYPES_H
# define TYPES_H

# define BUFFER_SIZE 1024
# define MAX_PLAYERS 4

typedef struct s_player
{
    char    name[64];
    int     score;
    int     lives;
}   t_player;

#endif

Any .c file that includes types.h can use t_player, BUFFER_SIZE, and MAX_PLAYERS.

Linking Headers and Sources

The header declares; the source defines. Both must agree on the signature:

/* math_utils.h */
int add(int a, int b);
/* math_utils.c */
#include "math_utils.h"

int add(int a, int b)
{
    return (a + b);
}
/* main.c */
#include <stdio.h>
#include "math_utils.h"

int main(void)
{
    printf("%d\n", add(3, 4));   // 7
    return (0);
}

Compile all .c files together:

gcc -Wall -Wextra -Werror main.c math_utils.c -o my_program

Or let the Makefile handle it with a pattern rule.

The extern Keyword

To share a variable across files, declare it extern in the header and define it once in exactly one .c file:

/* globals.h */
extern int g_frame_count;
/* globals.c */
#include "globals.h"
int g_frame_count = 0;   // one definition

Any file that includes globals.h can read and write g_frame_count. Global variables should be used sparingly — prefer passing data through function parameters.

Nested Includes

Headers can include other headers. Include guards ensure there is no infinite loop or duplication regardless of the inclusion order.

A common pattern is a single top-level header that bundles everything:

/* my_project.h */
#ifndef MY_PROJECT_H
# define MY_PROJECT_H

# include <stdlib.h>
# include <unistd.h>
# include "types.h"
# include "math_utils.h"

#endif

Then each .c file only needs #include "my_project.h".

Quick Reference

ConceptKey point
.h filedeclarations only — no function bodies
include guard#ifndef / #define / #endif prevents double inclusion
<header.h>system library header
"header.h"your own header
typedef in .hshare a type across multiple files
extern in .hdeclare a variable defined elsewhere
Makefilecompile all .c files together — header is included automatically
© 2026 Samuel Styles