C
Updated: May 21, 2026Categories: Languages
Printed from:
C Programming Cheatsheet
Language Overview
- Low-level, compiled, procedural programming language
- Developed by Dennis Ritchie at Bell Labs in 1972
- Foundation for many modern programming languages
- Provides direct access to system hardware and memory
- Used for systems programming, embedded systems, and performance-critical applications
- Current standard: C23 (ISO/IEC 9899:2024), succeeding C17/C18 and C11
Basic Syntax
C
123456789#include <stdio.h> // Standard input/output header
// Basic program structure
int main(void) {
// Program logic goes here
printf("Hello, World!\n");
return 0; // Return 0 implicit in main since C99, but explicit is clearer
}
Data Types
Primitive Types
C
12345678910111213141516171819202122232425262728293031// Integer Types
short // At least 16-bit integer
int // At least 16-bit, typically 32-bit
long // At least 32-bit integer
long long // At least 64-bit integer (C99+)
// Fixed-width integers (C99+, <stdint.h>)
int8_t, int16_t, int32_t, int64_t
uint8_t, uint16_t, uint32_t, uint64_t
// Floating Point Types
float // Single-precision floating point
double // Double-precision floating point
long double // Extended precision floating point
// Optional IEEE 754 interchange/extended types (C23, <stdfloat.h>)
_Float16, _Float32, _Float64, _Float128, _Decimal32, _Decimal64, _Decimal128
// Character Types
char // 8-bit character (signedness implementation-defined)
signed char // Signed character
unsigned char // Unsigned character
char8_t // UTF-8 code unit (C23; was just unsigned char prior)
char16_t // UTF-16 code unit (C11+, <uchar.h>)
char32_t // UTF-32 code unit (C11+, <uchar.h>)
// Boolean
// C99/C11: _Bool (with bool/true/false macros via <stdbool.h>)
// C23: bool, true, false are now keywords - no header needed
bool flag = true;
Derived Types
C
1234567891011121314151617181920212223242526// Pointers
int *ptr; // Pointer to integer
char *str; // Pointer to character (string)
// nullptr (C23) - typed null pointer constant
int *p = nullptr; // Preferred over NULL in C23
// Arrays
int arr[10]; // Fixed-size integer array
char name[50]; // Character array (string)
int vla[n]; // Variable-length array (C99; optional since C11, C23)
// Structures
struct Person {
char name[50];
int age;
float height;
};
// Unions
union Data {
int i;
float f;
char str[20];
};
Variables and Constants
C
123456789101112131415161718// Variable Declaration
int age = 30; // Initialized variable
const float PI = 3.14f; // Constant value
// Type Qualifiers
volatile int sensor; // Can change unexpectedly
static int count = 0; // Retains value between function calls
extern int global; // Declares variable defined elsewhere
_Atomic int counter; // Atomic access (C11+, <stdatomic.h>)
restrict // Pointer aliasing hint (C99+)
// constexpr (C23) - compile-time constant of object type
constexpr int MAX = 100;
// Type inference (C23)
auto x = 42; // Deduced as int
typeof(x) y = x; // typeof is now standard (C23)
Operators
Arithmetic Operators
C
1234567int a = 10, b = 5;
int sum = a + b; // Addition
int diff = a - b; // Subtraction
int prod = a * b; // Multiplication
int quot = a / b; // Division
int mod = a % b; // Modulus
Comparison Operators
C
1234567a == b; // Equal to
a != b; // Not equal to
a > b; // Greater than
a < b; // Less than
a >= b; // Greater than or equal to
a <= b; // Less than or equal to
Logical Operators
C
12345int x = 1, y = 0;
x && y; // Logical AND
x || y; // Logical OR
!x; // Logical NOT
Bitwise Operators
C
12345678910a & b; // Bitwise AND
a | b; // Bitwise OR
a ^ b; // Bitwise XOR
~a; // Bitwise NOT
a << 2; // Left shift
a >> 2; // Right shift (arithmetic on signed types since C23)
// Binary literals (C23)
unsigned mask = 0b1010'1100; // Digit separators with ' (C23)
Bit-manipulation utilities (C23, <stdbit.h>)
C
123456stdc_leading_zeros(x); stdc_trailing_zeros(x); stdc_count_ones(x); stdc_bit_width(x); stdc_bit_ceil(x);
Control Structures
Conditional Statements
C
1234567891011121314151617181920212223242526// If-Else
if (condition) {
// Code if true
} else if (another_condition) {
// Alternative condition
} else {
// Default case
}
// Ternary Operator
int result = (x > y) ? x : y; // Conditional assignment
// Selection with initializer (NOT in C; this is a C++ feature - avoid)
// Switch with labeled fallthrough attribute (C23)
switch (n) {
case 1:
do_one();
[[fallthrough]]; // Suppresses fallthrough warnings (C23)
case 2:
do_two();
break;
default:
break;
}
Loops
C
12345678910111213141516171819// For Loop
for (int i = 0; i < 10; i++) {
// Repeated code
}
// While Loop
while (condition) {
// Repeated code
}
// Do-While Loop
do {
// Always executes at least once
} while (condition);
// Break and Continue
break; // Exit loop
continue; // Skip current iteration
Functions
C
12345678910111213141516171819202122232425262728293031323334// Function Declaration
int add(int a, int b) {
return a + b;
}
// Empty parameter list now means "no parameters" (C23)
// Previously (...) was different from (void); now () == (void)
int get_value(); // C23: takes no arguments (same as (void))
// Function Pointer
int (*operation)(int, int);
// Variadic Functions
#include <stdarg.h>
// C23: count parameter before ... is no longer required
int sum_numbers(int count, ...) {
va_list args;
va_start(args, count); // C23 also allows va_start(args) with no second arg
int sum = 0;
for (int i = 0; i < count; i++) {
sum += va_arg(args, int);
}
va_end(args);
return sum;
}
// Standard attributes (C23)
[[nodiscard]] int compute(void);
[[deprecated("use new_api instead")]] void old_api(void);
[[maybe_unused]] static int debug_id = 0;
[[noreturn]] void fatal(const char *msg);
Memory Management
C
12345678910111213141516171819202122232425#include <stdlib.h>
// Dynamic Memory Allocation
int *arr = malloc(10 * sizeof *arr); // Allocate memory
if (arr == nullptr) {
// Handle allocation failure
}
// Resizing Memory (always use a temp pointer to avoid leaks)
int *tmp = realloc(arr, 20 * sizeof *arr);
if (tmp) arr = tmp;
// Freeing Memory
free(arr);
arr = nullptr; // Optional defensive practice
// Calloc for Zero-Initialized Memory
int *zeroed_arr = calloc(10, sizeof *zeroed_arr);
// Aligned allocation (C11+)
void *p = aligned_alloc(64, 1024); // size must be multiple of alignment
free(p);
// Note: gets() was removed in C11. Use fgets() instead.
Preprocessor Directives
C
12345678910111213141516171819202122232425#include <stdio.h> // Include standard library
#define MAX_SIZE 100 // Constant definition
#define SQUARE(x) ((x) * (x)) // Macro function
// C23 additions
#embed "data.bin" // Embed binary resource at compile time
#warning "deprecated path"
#elifdef DEBUG // == #elif defined(DEBUG)
#elifndef RELEASE // == #elif !defined(RELEASE)
// __VA_OPT__ (C23) — emit tokens only if variadic args present
#define LOG(fmt, ...) printf(fmt __VA_OPT__(,) __VA_ARGS__)
#ifdef DEBUG
printf("Debug mode\n");
#endif
#ifndef HEADER_H
#define HEADER_H
// Header file contents
#endif
// Standard predefined macros
__STDC_VERSION__ // 202311L for C23, 201710L for C17, 201112L for C11
File I/O
C
1234567891011121314FILE *file = fopen("example.txt", "r"); // Open file
if (file == nullptr) {
// Handle file open error
return 1;
}
char buffer[100];
if (fgets(buffer, sizeof buffer, file)) { // Read line
// process buffer
}
fprintf(file, "Writing to file\n"); // Write to file (must be opened for write)
fclose(file); // Close file
Error Handling
C
12345678#include <errno.h>
#include <string.h>
if (some_function() == -1) {
// strerror_r / strerror_s are preferred in threaded code
fprintf(stderr, "Error: %s\n", strerror(errno));
}
Structures and Unions
C
123456789101112131415161718192021222324252627// Structure
struct Student {
char name[50];
int age;
float gpa;
};
// Designated initializers (C99+)
struct Student s = { .name = "Ada", .age = 36, .gpa = 4.0f };
// Compound literals (C99+)
print_point((struct Point){ .x = 1, .y = 2 });
// Typedef for easier type definition
typedef struct {
int x, y;
} Point;
// C23: typedef may be redeclared with the same definition
// Union
union Data {
int i;
float f;
char str[20];
};
Enumerations
C
1234567891011121314enum Days {
MONDAY, // 0
TUESDAY, // 1
WEDNESDAY, // 2
// ...
};
// Enum with fixed underlying type (C23)
enum Color : unsigned char {
RED = 0xFF,
GREEN = 0x7F,
BLUE = 0x3F
};
Threads and Atomics (C11+)
C
1234567891011121314151617#include <threads.h>
#include <stdatomic.h>
_Atomic int counter = 0;
int worker(void *arg) {
atomic_fetch_add(&counter, 1);
return 0;
}
thrd_t t;
thrd_create(&t, worker, nullptr);
thrd_join(t, nullptr);
// thread_local storage (keyword in C23; _Thread_local in C11)
thread_local int tls_value;
Best Practices
- Always initialize variables (or use designated initializers)
- Use
constfor values that won't change; considerconstexpr(C23) for compile-time constants - Check return values of
malloc,calloc,realloc,fopen, etc. - Close files and free dynamically allocated memory; pair every
mallocwith afree - Prefer
sizeof *ptroversizeof(type)in allocations to stay type-safe - Use
nullptr(C23) orNULLinstead of0for pointers - Use meaningful variable and function names
- Minimize global variables; prefer
staticfor file-scope state - Enable warnings:
-Wall -Wextra -Wpedantic -Wshadow -Wconversion - Use standard attributes (
[[nodiscard]],[[fallthrough]]) to express intent - Avoid removed/unsafe APIs (
gets, K&R-style function declarations)
Build and Compile
Bash
12345678910111213141516# Compile with gcc / clang
gcc -std=c23 -o program program.c # GCC 14+ supports -std=c23
clang -std=c23 -o program program.c # Clang 18+ supports -std=c23
# For broader portability:
gcc -std=c17 -o program program.c
# Compile with strict warnings
gcc -std=c23 -Wall -Wextra -Wpedantic -o program program.c
# Debug build
gcc -std=c23 -g -O0 -o program program.c
# Sanitizers (GCC/Clang)
gcc -fsanitize=address,undefined -g program.c -o program
gcc -fsanitize=thread -g program.c -o program
Testing Approaches
- Unit testing with frameworks like Unity, Check, cmocka, Criterion, or µnit
- Valgrind and AddressSanitizer for memory error detection
- UndefinedBehaviorSanitizer (UBSan) for catching UB at runtime
- ThreadSanitizer (TSan) for data races
- Static analysis: clang-tidy, cppcheck, Coverity, PVS-Studio, GCC
-fanalyzer - Fuzzing: libFuzzer, AFL++, honggfuzz
Performance Considerations
- Minimize dynamic memory allocation in hot paths; reuse buffers
- Use stack memory when sizes are bounded and known
- Optimize loops and avoid redundant computations; let the compiler vectorize
- Use appropriate data types (fixed-width when size matters)
- Consider compiler optimization flags:
-O2,-O3,-flto,-march=native - Use
restrictto indicate non-aliasing pointers - Profile before optimizing (
perf,gprof, Callgrind)
Resources for Further Learning
- "The C Programming Language" by Kernighan and Ritchie
- "C Programming: A Modern Approach" by K. N. King
- "Modern C" by Jens Gustedt (free PDF; covers C17/C23 idioms)
- "Effective C" by Robert C. Seacord
- ISO/IEC 9899:2024 (C23 standard); latest public draft N3220
- cppreference.com (C reference), open-std.org/JTC1/SC22/WG14 (WG14 papers)
Continue Learning
Discover more cheatsheets to boost your productivity