C Cheatsheet
Preprocessor
Use this C reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
#include
#include <stdio.h> // system/standard header — searches system paths #include "myheader.h" // project header — searches current dir first #include "../lib/util.h" // relative path
The preprocessor replaces #include with the entire content of that file before compilation.
#define — Object-like Macros
#define PI 3.14159265358979 #define MAX_SIZE 1024 #define GREETING "Hello" #define NEWLINE '\n' #define TRUE 1 #define FALSE 0 // Multi-line macro (backslash continues to next line) #define LONG_CONSTANT \ 0xDEADBEEF // Undef a macro #undef MAX_SIZE #define MAX_SIZE 2048 // Macros have no type — use const or enum for type-safe constants const int kMaxSize = 1024; // preferred in modern C
#define — Function-like Macros
#define SQUARE(x) ((x) * (x)) // always parenthesize args and whole expr #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define ABS(x) ((x) < 0 ? -(x) : (x)) #define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) #define CLAMP(v,lo,hi) ((v)<(lo)?(lo):(v)>(hi)?(hi):(v)) #define SWAP(T,a,b) do { T _t=(a); (a)=(b); (b)=_t; } while(0) // Usage int s = SQUARE(3 + 1); // expands to ((3+1)*(3+1)) = 16 (parens matter!) int m = MAX(x++, y); // DANGER: x++ evaluated twice — side-effect bug // do-while(0) wraps multi-statement macros safely #define LOG(msg) do { printf("[LOG] %s\n", msg); } while(0) // Works correctly in if/else without braces: if (cond) LOG("msg"); // expands cleanly
Stringification and Token Pasting
// # — stringify: converts argument to string literal #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) // two-level for macro expansion STRINGIFY(hello) // "hello" STRINGIFY(1 + 2) // "1 + 2" TOSTRING(__LINE__) // the current line number as a string // ## — token pasting: concatenates tokens #define CONCAT(a, b) a ## b #define VAR(n) var_ ## n CONCAT(int, 64_t) // int64_t int VAR(x) = 5; // int var_x = 5; // Practical use: generate struct member names, enum prefixes #define DECLARE_FUNC(name) int func_ ## name(void) DECLARE_FUNC(init); // declares: int func_init(void);
Predefined Macros
| Macro | Value |
|---|---|
__FILE__ | Current source file name (string) |
__LINE__ | Current line number (integer) |
__func__ | Current function name (string, C99+) |
__DATE__ | Compilation date "Mmm dd yyyy" |
__TIME__ | Compilation time "hh:mm:ss" |
__STDC__ | 1 if conforming C implementation |
__STDC_VERSION__ | Standard version: 199901L / 201112L / 201710L / 202311L |
__STDC_HOSTED__ | 1 if hosted environment (vs. freestanding) |
__STDC_NO_VLA__ | 1 if VLAs not supported (C11+) |
__COUNTER__ | Unique integer per expansion (GCC/Clang extension) |
printf("File: %s, Line: %d, Func: %s\n", __FILE__, __LINE__, __func__); // Debug assert with context #define ASSERT(cond) \ do { if (!(cond)) { \ fprintf(stderr, "Assertion failed: %s, %s:%d\n", #cond, __FILE__, __LINE__); \ abort(); \ }} while(0)
Conditional Compilation
#ifdef DEBUG
printf("debug value: %d\n", x);
#endif
#ifndef MYHEADER_H
#define MYHEADER_H
// ... header contents ...
#endif
// #if with expressions (must be integer constant expressions)
#if MAX_SIZE > 512
// large buffer path
#elif MAX_SIZE > 256
// medium buffer path
#else
// small buffer path
#endif
// Test if a macro is defined
#if defined(WIN32) || defined(_WIN64)
#define PLATFORM "Windows"
#elif defined(__linux__)
#define PLATFORM "Linux"
#elif defined(__APPLE__)
#define PLATFORM "macOS"
#else
#define PLATFORM "Unknown"
#endif
// Check C standard version
#if __STDC_VERSION__ >= 201112L
// C11 feature available
#endifInclude Guards
Prevent a header from being included more than once.
// Traditional include guard #ifndef MYMODULE_H #define MYMODULE_H // ... declarations ... #endif /* MYMODULE_H */ // Pragma once (GCC/Clang/MSVC extension — not standard but widely supported) #pragma once // ... declarations ...
#pragma
#pragma once // include guard (non-standard but universal) #pragma GCC optimize("O3") // per-function optimization hint #pragma pack(push, 1) // pack structs to 1-byte alignment struct Wire { uint8_t a; uint32_t b; }; #pragma pack(pop) // restore default packing // Suppress warnings (Clang) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" int unused; #pragma clang diagnostic pop // MSVC #pragma warning(disable : 4996) // disable specific warning
#error and #warning
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L #error "C99 or later required" #endif #ifndef BUFFER_SIZE #warning "BUFFER_SIZE not defined; using default 1024" #define BUFFER_SIZE 1024 #endif // _Static_assert is the standard alternative for compile-time checks _Static_assert(sizeof(int) >= 4, "Need at least 32-bit int");
#line
Override the reported filename and line number (used by code generators).
#line 100 "generated.c" // Subsequent diagnostics report line 100 in generated.c
__has_include (C23, widely available as extension)
#if __has_include(<stdint.h>) #include <stdint.h> #else typedef unsigned int uint32_t; #endif #if __has_include("config.h") #include "config.h" #endif
_Pragma Operator (C99+)
// Equivalent to #pragma but usable in macros #define DISABLE_WARNING _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wunused\"")
Common Macro Patterns
// Compile-time assertion (pre-C11) #define COMPILE_ASSERT(expr) typedef char _ca[(expr) ? 1 : -1] // Unused parameter suppression #define UNUSED(x) ((void)(x)) void callback(int event, void *data) { UNUSED(event); UNUSED(data); } // Container-of (like Linux kernel) #define CONTAINER_OF(ptr, type, member) \ ((type *)((char *)(ptr) - offsetof(type, member))) // Safe minimum/maximum with statement expressions (GCC/Clang) #define SAFE_MAX(a, b) ({ __typeof__(a) _a=(a); __typeof__(b) _b=(b); _a>_b?_a:_b; }) // Bit manipulation macros #define BIT(n) (1u << (n)) #define SET_BIT(v, n) ((v) |= BIT(n)) #define CLR_BIT(v, n) ((v) &= ~BIT(n)) #define TST_BIT(v, n) ((v) & BIT(n)) #define TOG_BIT(v, n) ((v) ^= BIT(n))
Header File Convention
// mymodule.h #ifndef MYMODULE_H #define MYMODULE_H #include <stddef.h> // size_t #include <stdint.h> // uint32_t #ifdef __cplusplus extern "C" { // allow use from C++ code #endif // Public API declarations only — no definitions (except static inline) typedef struct MyObj MyObj; MyObj *myobj_new(int n); void myobj_free(MyObj *obj); int myobj_get(const MyObj *obj, size_t idx); #ifdef __cplusplus } #endif #endif /* MYMODULE_H */