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

MacroValue
__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
#endif

Include 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 */