- C - Home
- C - Overview
- C - Features
- C - History
- C - Standards
- C - Environment Setup
- C - Program Structure
- C - Hello World
- C - Compilation Process
- C - Comments
- C - Basic Syntax
- C - User Input
- C - printf Function
- C - Format Specifiers
- Lexical Elements in C
- C - Tokens
- C - Keywords
- C - Identifiers
- Variables and Constants
- C - Variables
- C - Constants
- C - Const Qualifier
- C - Linkage
- Data Types and Type Conversions
- C - Data Types
- C - Literals
- C - Escape Sequences
- C - Booleans
- C - Integer Promotions
- C - Character Arithmetic
- C - Type Conversion
- C - Type Casting
- Operators in C
- C - Operators
- C - Arithmetic Operators
- C - Unary Operators
- C - Relational Operators
- C - Logical Operators
- C - Bitwise Operators
- C - Assignment Operators
- C - Increment and Decrement Operators
- C - Ternary Operator
- C - sizeof Operator
- C - Operator Precedence
- C - Miscellaneous Operators
- Decision Making & Control Statements
- C - Decision Making
- C - if Statement
- C - if...else Statement
- C - if...else if Ladder
- C - Nested if Statements
- C - Switch Statement
- C - Nested Switch Statements
- C - Switch Case Using Range
- Loops in C
- C - Loops
- C - For Loop
- C - While Loop
- C - Do...while Loop
- C - For Loop vs While Loop
- C - Nested Loop
- C - Infinite Loop
- C - Break Statement
- C - Continue Statement
- C - Goto Statement
- Functions in C
- C - Functions
- C - Function Prototype
- C - Main Function
- C - Function call by Value
- C - Function call by reference
- C - Nested Functions
- C - Variadic Functions
- C - User-Defined Functions
- C - Callback Function
- C - Return Statement
- C - Recursion
- C - Predefined Identifier __func__
- Scope Rules in C
- C - Scope Rules
- C - Static Variables
- C - Global Variables
- Arrays in C
- C - Arrays
- C - Properties of Array
- C - Multi-Dimensional Arrays
- C - Passing Arrays to Function
- C - Return Array from Function
- C - Variable Length Arrays
- C - Dynamic Arrays
- Strings in C
- C - Strings
- C - Array of Strings
- C - Character Arrays
- C - Special Characters
- Pointers in C
- C - Pointers
- C - Initialization of Pointer Arrays
- C - Applications of Pointers
- C - Dereference Pointer
- C - NULL Pointer
- C - void Pointer
- C - Const Pointers & Pointer to Const
- C - Dangling Pointers
- C - Pointer Arithmetics
- C - Pointers and Arrays
- C - Pointer vs Array
- C - Pointer to an Array
- C - Array of Pointers
- C - Pointers vs. Multi-dimensional Arrays
- C - Pointer to Pointer
- C - Chain of Pointers
- C - Character Pointers and Functions
- C - Passing Pointers to Functions
- C - Return Pointer from Functions
- C - Function Pointers
- C - Array of Function Pointers
- C - Pointers to Structures
- C - Near, Far and Huge Pointers
- C - Restrict Keyword
- User-Defined Data Types
- C - Structures
- C - Structures and Functions
- C - Arrays of Structures
- C - Self-Referential Structures
- C - Dot (.) Operator
- C - Lookup Tables
- C - Enumeration (or enum)
- C - Structure Padding and Packing
- C - Nested Structures
- C - Anonymous Structure and Union
- C - Unions
- C - Bit Fields
- C - Typedef
- C - Flexible Array Members in Structures
- C - Structures vs Unions
- Memory Management in C
- C - Memory Layout
- C - Memory Management
- C - Memory Address
- C - Storage Classes
- C - Dynamic Array Resizing
- C - Memory Leaks
- File Handling in C
- C - File Handling
- C - Input & Output
- C - File Operations
- C - Formatted Output
- C - getc, getchar, getch, getche
- Preprocessors in C
- C - Preprocessors
- C - Pragmas
- C - Macros
- C - Working of Preprocessor
- C - Preprocessor Operators
- C - Header Files
- C - Custom Header Files
- Miscellaneous Topics
- C - Error Handling
- C - Variable Arguments
- C - Command Execution
- C - Math Functions
- C - Static Keyword
- C - Random Number Generation
- C - Command Line Arguments
- C Programming Resources
- C - Questions & Answers
- C - Quick Guide
- C - Cheat Sheet
- C - Useful Resources
- C - Discussion
- C - Online Compiler
Custom Header Files in C
Header files in C are files with a .h extension that contain definitions of functions, macros, constants, and data types. C provides standard header files with built-in functions and definitions. Similarly, we can also create our own custom header files.
In this chapter, we will learn how to create and include custom header files in C programs. We will cover the following topics one after the other −
- Custom Header File in C
- Creating a Custom Header File
- Understanding Include Guards
- Alternative: #pragma once
- Contents of a Custom Header File
- Best Practices for Custom Headers
Custom Header File in C
A custom header file is a file that we can create by making a new file with a .h extension and adding function declarations, macros, constants, or structure definitions. By including this header file, we can reuse the code or functions defined in it.
Header files separate declarations from definitions and always have the .h extension. We include them in C source files using the #include directive. For example −
#include "myheader.h"
Here, myheader.h is a custom header file.
Creating a Custom Header File
To create a custom header file in C, we write all the function declarations, macros, and constants that we want to reuse in a separate file with the .h extension. Then, we include this header file in our program using the #include directive.
Now, let's go through the steps to create a custom header file.
Step 1: Create the Header File
Create a file named myheader.h and add the declarations of the functions you want to reuse.
Here's an example of myheader.h file −
// myheader.h #ifndef MYHEADER_H #define MYHEADER_H int add(int a, int b); int subtract(int a, int b); int multiply(int a, int b); #endif
Here, #ifndef, #define, and #endif are header guards. They make sure the file is not included more than once in a program. In this file, we only write function declarations, not the actual code.
Step 2: Create the Source File
Now, create a file named myheader.c to write the actual code (definitions) for the functions declared in the myheader.h header file.
Here's an example of the myheader.c file −
// myheader.c
#include "myheader.h"
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int multiply(int a, int b) {
return a * b;
}
In the above program, we include the "myheader.h" file using #include directive. By including this file, the compiler knows that the functions we are defining match the declarations in the myheader.h header file.
Step 3: Use the Header File in the Main Program
Finally, create the main program file main.c and include the custom header file to use the functions we declared in myheader.h and defined in myheader.c.
Here's an example of our main.c program, where we include the custom header file (myheader.h) and call the add(), subtract(), and multiply() functions just like we call the built-in functions.
// main.c
#include <stdio.h>
#include "myheader.h"
int main() {
int a = 10, b = 5;
printf("Addition: %d\n", add(a, b));
printf("Subtraction: %d\n", subtract(a, b));
printf("Multiplication: %d\n", multiply(a, b));
return 0;
}
Step 4: Compile the Program
Finally, compile both main.c and myheader.c together so the function definitions are linked with their declarations −
gcc main.c myheader.c -o program
Then, run the program using the following command −
./program
The program will run successfully and display the following output −
Addition: 15 Subtraction: 5 Multiplication: 50
Understanding Include Guards
An important point to note about custom headers is the use of include guards. If the same header file is included multiple times in a program, the compiler may throw errors like redefinition of functions or variables. To prevent this, we wrap the header code inside preprocessor directives called #ifndef, #define, and #endif, which ensure the compiler includes the file only once.
Here's the general structure of a header guard −
#ifndef FILENAME_H #define FILENAME_H // declarations #endif
Here's an example with a custom header file −
#ifndef MYHEADER_H #define MYHEADER_H int add(int a, int b); int subtract(int a, int b); #endif
Alternative: #pragma once
Instead of using include guards, we can also write #pragma once at the top of the header file. For Example −
#pragma once int add(int a, int b); int subtract(int a, int b);
It works just like include guards and makes sure the compiler includes the header file only once. Just keep in mind that it is compiler-specific, although most modern compilers support it.
Contents of a Custom Header File
In a custom header file, we can include different kinds of reusable code, such as -
Function Declarations − Declare functions to use them in multiple programs without rewriting.
int add(int a, int b); int subtract(int a, int b);
Macros − Define constants or small code snippets that the compiler replaces wherever needed.
#define MAX 100 #define MIN 0
Constants − Store values that do not change, such as mathematical or fixed program values.
const float PI = 3.14159; const int DAYS_IN_WEEK = 7;
Structure − Group related data together into a single unit.
struct Student {
char name[50];
int age;
};
Unions − Store different types in the same memory location to save memory.
union Data {
int i;
float f;
char str[20];
};
Enumerations − Define named sets of integer constants.
enum Color { RED, GREEN, BLUE };
Avoid putting full function definitions in the header file except for inline functions, because including them in multiple files can cause errors.
Best Practices for Custom Headers
Here are some important points we should take care of while creating custom header files in C −
- Always use include guards or #pragma once to avoid multiple inclusion errors.
- Keep declarations in .h files and the actual code (definitions) in .c files.
- Give meaningful names to your headers so it's easy to know what they contain.
- Don't put too much code in headers. Only write declarations there, unless you are using inline functions.
- Group related functions together in a single header. For example, all math functions can go in mathutils.h.
- Add comments to your headers to explain what each part does.
Conclusion
In this chapter, we learned how to create our own header files in C. Using custom headers helps organize code, improve readability, and make programs easier to manage. They also enable code to be reused across multiple programs, which reduces repetition, saves development time.