Header Files: (.h) Declarations of functions, types shared by multiple sources, implemented somewhere else
// Guard condition
#ifndef THIS_HEADER_H
#define THIS_HEADER_H
// Define types
typedef struct(char *color) Cat;
// Define functions
void catsay(Cat *cat);
// Define varaibles (Setting values for variables in headers would fail on linking)
extern const int CONSTANT;
extern int array[];
#endif // THIS_HEADER_H
// Visible in all sources during linking, might produce a variable conflict
int x = 0;
// Static in global scope: Make variable visible in only the current file
static int y = 0;
void function() {
// Static in local scope: Make variable preserve value through multiple function calls
static int z = 0;
z++;
}
Target: Contain dependencies and recipe
Dependency: Specify another target to compile before this target
Recipe: The command to produce a specific target
# Variables
CFLAGS = -Wall -Werror -g -std=gnu99
# Targets
# target: dependencies
# recipe
friendme: friendme.o friends.o
gcc $(CFLAGS) -o friendme friendme.o friends.o
friendme.o: friendme.c friends.h
gcc $(CFLAGS) -c friendme.c
friends.o: friends.c friends.h
gcc $(CFLAGS) -c friends.c
# Wildcards
%.o: %.c friend.h
gcc $(CFLAGS) -c $< -o $@
# Pseudo-target
.PHONY: clean
clean:
rm friendme *.o
Make only re-compile changed file
Define in compiler: gcc -D MACRO=1 ...
// Always wrap macros in parenthesis, don't add semicolon
#define CONSTANT (32)
#define FUNCTION(arg1, arg2) (arg1 + arg2)
#ifdef __APPLE__
// do something
#elif defined(__gnu_linux__)
// do something else
#else
#endif
// Multi-line functions: Use a do-while wrapper to ensure the macro is used as a statement
#define MULTILINE(arg) \\
do { \\
printf(arg); \\
} while (0)