Directive | Description |
---|---|
#define |
create a macro |
#undef |
remove a macro |
#include |
Inserts a header file |
#ifdef |
Check if a macro is defined |
#ifndef |
Check if a macro is not defined |
#if |
Check a compile time condition |
#else |
The alternative path for #if directive |
#elif |
Ladder directive, used with #if |
#endif |
Ends conditional directive |
#error |
Prints error message on stderr |
#pragma |
Special compiler directives |
C is a modular language. You can combine smaller files into a larger program using #include directive followed by the header file name. There are two kind of header files: System headers and project local headers.
//system header
#include <stdio.h>
//local header
#include "my_file.h"
The C 90 standard headers list:
<assert.h> <ctype.h> <errno.h> <float.h> <limits.h> |
<locale.h> <math.h> <setjmp.h> <signal.h> <stdarg.h> |
<stddef.h> <stdio.h> <stdlib.h> <string.h> <time.h> |
Headers added since C 90:
<complex.h> <fenv.h> <inttypes.h> |
<iso646.h> <stdbool.h> <stdint.h> |
<tgmath.h> <wchar.h> <wctype.h> |
Project header files:
You can create your own header files and store them with your program files. A good practice is to store in header files: constants, macros, system wide global variables, and function prototypes.
Note: Function prototype is the function signature without its body. Functions can be implemented in other *.c source files that do not have same name as the header file.
Constants: Using #define you can create constants. These constants must use uppercase names.
#include <stdio.h>
#define MY_MESSAGE "Hello!"
int main() {
#ifdef MY_MESSAGE
printf(MY_MESSAGE);
#endif
return 0;
}
Macros: Using #define you can create macros. These are expressions or reusable fragments of code:
#include <stdio.h>
#define AVG(x,y) ((x + y)/2)
int main(void) {
printf("AVG = %d\n", AVG(10, 20)); //integers
printf("AVG = %lf\n", AVG(1, 1.5)); //float
return 0;
}
Note: AVG in previous example looks like a function but is not. It is a "macro" so it uses uppercase letters for identifier. The real difference is that macros are converted into literal expressions before compilation. Since this is not a function call, macro parameters do not have types, they are text literals that are replaced in expressions before compilation.
Warning: There is a danger that macro can produce unexpected results if is not enclosed in extra parentheses. It is a bad practice to overuse macros. It may decrease program readability and maintainability.
This directive stop the compilation and display a message defined after #error:
#error message
This directive do not stop the compilation but display a warning message:
#warning message
This is a conditional compiler directive. It uses a logical expression to make a decision block executed before compilation. The conditional expression can contain normal relation and logic operators in addition it can use operator defined() that take as argument a defined constant or macro.
#include <stdio.h>
#define SUM(x,y) (x + y)
int main(void) {
#if defined(SUM)
printf("SUM = %d\n", SUM(10, 20));
#endif;
return 0;
}
ANSI C defines some useful macros and variables:
__FILE__ => The name of the current file, as a string literal
__LINE__ => Current line of the source file, as a numeric literal
__DATE__ => Current system date, as a string
__TIME__ => Current system time, as a string
Note: Some compilers have special #pragma directives and other operators. For more details about processor directives you must consult the compiler specific documentation. These details are out of scope from my introductory tutorial.
Read next: Memory Management