In this tutorial, we are going to learn about C Header Files & Preprocessor Directives.

C Header Files:

Humans and computers communicate using input/output devices.

Programming languages facilitate such communication through I/O operations like reading input from the keyboard, displaying output on screens, writing to files, printers, etc.

C language provides many functions to perform, read, and write operations for the I/O devices. These functions are made available in files (usually written with .h extension) referred to, as header files.

Standard I/O library functions are available in a file named stdio.h (standard input output header file).

C language provides a collection of such header files which form the C standard library. These files are usually available in operating systems like Linux by default.

Programmers can also create their own header files which are usually referred to as user-defined header files.

As mentioned earlier, there is a file called stdio.h among the header files present in C standard library, which contains the most commonly used functions to print data to console and to read (also called scan) data.

In order to use the functions available in the header file stdio.h, the following line has to be used in a program:

#include <stdio.h>

It makes the contents of the header file available to the compiler and the linker during the execution of programs.

Now let’s understand some preprocessor directives,

#include:

The header files are included in a program using the #include directive.

The header files can be included using #include in two ways as follows:

    1. #include <header_file_name.h>: This variant is used to include system header files made available in C standard library. The compiler searches for the named file in the standard list of system directories.
    2. #include “header_file_name.h”: This variant is commonly used to include user-defined header files. The compiler searches for the named files only in the local or project-specific paths.

Given below is the most commonly included header file which contains the standard input/output functions like, printf()scanf(), etc.

#include <stdio.h>

Here, the symbol # is called the preprocessor directive, include is called the command, and stdio.h is the header file.

Note: Some compilers automatically include stdio.h. While using compilers that do not automatically include stdio.h, programmers have to explicitly write the include statement in their programs to avoid compilation errors.

#define:

In programming terminology, a macro is a pattern or a rule which specifies how a certain sequence of text should be replaced.

C allows us to define two types of macros using the preprocessor directive #define as shown below:

  1. #define PI 3.14
  2. #define MIN(a, b) ((a) < (b)? (a) : (b))

The first type of substitution has been discussed while learning about symbolic constant.

The second type can be used to define a rule or a function that works on given arguments.

Given below is the general syntax for declaring macros using #define:

#define macro_name replacement_text
#define macro_name(arg_1, arg_2... arg_n) function_expression

Consider the following example that swaps the values of two variables using #define macro.

#include
#define SWAP(a, b, c){c t; t=a; a=b; b=t;}
int main()
{
 int x=10, y=20;
 SWAP(x, y, int);
 printf("%d %d\n", x, y);
 return 0;
}

Output:

20 10

Here, SWAP(a, b, tempo) is the name of the macro with three arguments that are replaced with the macro body: (tempo = a, a = b, b = temp0).

## in #define:

C provides a special concatenation operator ## which can be used in a #define directive as shown below:

#define CONCAT(X, Y) X##Y

The ## operator concatenates the values in X and Y forming a single sequence.

For example, CONCAT (20, 21) will result in 2021.

#ifdef, #else, #endif:

In C, a programmer can instruct the preprocessor whether or not to include a certain section of the code. This is accomplished using conditional directives.

These are similar to if statements in syntax and usage. However, unlike if statements that are executed during runtime, the conditional directives are executed before compilation by the preprocessor.

These directives are used whenever there is a need to compile a portion of the program conditionally. It is also known as conditional compilation.

The most common conditional directive #ifdef (spelled as if-defined) verifies if a given identifier is defined or not.
The syntax for its usage is :

#ifdef identifier or #if defined (identifier)

The source code following #ifdef will be compiled only if the given identifier is defined either in the code or if it is provided as a compilation option as -Didentifier_name.

The opposite of #ifdef is #ifndef, which is written as

#ifndef identifier or #if !defined (identifier)

Consider the following example:

#if defined (MAX)
    #define MIN 30
#else
    #define MAX 100
    #define MIN 200
#endif

Here, MIN 30 will be defined only if the constant MAX is defined earlier than MIN 30. Else, both MAX and MIN will be defined with values 100 and 200 respectively.

#if, #elif, #endif:

Similar to the if-else-if construct, we have a #if-#elif which is used in creating a chain of #if-else statements that can be used to conditionally compile a portion of code.

The general syntax for #if, #elif, #else, #endif is given below:

#if expression1
    statement_block1;
#elif expression2
    statement_block2;
#elif expression3
    statement_block3;
#else
    statement_block4;
#endif

#undef:

The #undef directive “undefines” a symbolic constant or a macro identifier that has been defined earlier; i.e., it negates the effects of a #define directive that may have appeared earlier in the program.

The #undef directive is used to remove values defined by #define directives so that they can be redefined with new values.

The format of #undef is

#undef symbolic_name

Given below is an example for #undef:

#include <stdio.h>
#define TEMP 20
int main() {
	printf("%d\n", TEMP);
	#ifdef TEMP
		#undef TEMP
		#define TEMP 99
	#else
		#define TEMP 999
	#endif

	printf("%d\n", TEMP);
	return 0;
}

Output:

20
99

Here, the code first prints 20 and then prints99.

REFERENCES:

Happy Learning 🙂