C Cheat Sheet
Types and format specifiers, strings, pointers, malloc and free, structs, files, the preprocessor and bit tricks on one page.
Updated
Program structure#
#include <stdio.h> /* printf, scanf, fgets, FILE */
#include <stdlib.h> /* malloc, free, exit, strtol */
#include <string.h> /* strlen, strcpy, strcmp */
int main(void) {
printf("Hello, C!\n");
return 0; /* 0 = success */
}gcc -std=c17 -Wall -Wextra -g main.c -o app
./appTypes and format specifiers#
const double GST = 0.18; /* read-only variable */
#define MAX_USERS 100 /* preprocessor constant */
enum Color { RED, GREEN, BLUE }; /* 0, 1, 2 */
int x = (int)3.99; /* cast: 3 (truncates) */
double avg = (double)7 / 2; /* 3.5, not 3 */Operators#
Input and output#
int age;
if (scanf("%d", &age) != 1) { /* bad input */ }
char line[100];
if (fgets(line, sizeof line, stdin) != NULL) {
line[strcspn(line, "\n")] = '\0'; /* strip newline */
}
printf("%-10s|%5d|%8.2f\n", "name", 42, 3.14159);
fprintf(stderr, "error: %s\n", "message");Control flow#
if (x > 0) { ... } else if (x < 0) { ... } else { ... }
switch (choice) {
case 1: start(); break;
case 2: stop(); break;
default: help();
}
for (int i = 0; i < n; i++) { ... }
while (cond) { ... }
do { ... } while (cond); /* runs at least once */
break; /* leave loop or switch */
continue; /* next iteration */Functions#
int square(int n); /* prototype (declaration) */
int square(int n) { return n * n; } /* definition */
void log_msg(const char *msg); /* returns nothing */
int count(void); /* takes no arguments */
void swap(int *a, int *b) { /* change caller's variables */
int t = *a; *a = *b; *b = t;
}
swap(&x, &y);
static int helper(void); /* private to this file */
int next_id(void) { static int id = 0; return ++id; } /* keeps value */Arrays and strings#
int a[5] = {1, 2, 3}; /* rest are 0 */
size_t n = sizeof a / sizeof a[0]; /* 5: only on real arrays */
int grid[3][4]; /* grid[row][col] */
char s[] = "hello"; /* 6 bytes, ends in '\0' */
const char *lit = "read-only"; /* string literal */
strlen(s) /* 5 */
strcpy(dst, src) /* copy (dst must be big enough) */
strcat(dst, src) /* append */
strcmp(a, b) == 0 /* equal? never use == */
strchr(s, 'l') /* pointer to first 'l' or NULL */
strstr(s, "ll") /* pointer to substring or NULL */
snprintf(buf, sizeof buf, "%s-%d", s, 7) /* safe formatting */
strtol(text, &end, 10) /* parse an integer with checking */Pointers#
int x = 10;
int *p = &x; /* p holds x's address */
*p = 20; /* x is now 20 */
int *q = NULL; /* points to nothing: check before use */
p + 1 /* next element (scaled by sizeof *p) */
a[i] == *(a + i) /* indexing is pointer arithmetic */
int **pp = &p; /* pointer to pointer */
const int *r; /* can't change *r */
int *const k = &x; /* can't change k */
int (*op)(int, int) = add; /* function pointer */Dynamic memory#
int *v = malloc(n * sizeof *v); /* uninitialised */
if (v == NULL) { /* handle out of memory */ }
int *z = calloc(n, sizeof *z); /* zeroed */
int *tmp = realloc(v, 2 * n * sizeof *v);
if (tmp != NULL) v = tmp; /* never v = realloc(v, ...) */
free(v);
v = NULL; /* avoid dangling pointer */Structs, unions and typedef#
typedef struct {
int id;
char name[32];
double balance;
} Account;
Account a = { .id = 1, .name = "Asha", .balance = 500.0 };
a.balance += 100; /* member of a struct */
Account *pa = &a;
pa->balance -= 50; /* member through a pointer */
typedef struct Node { int value; struct Node *next; } Node;
union Value { int i; double d; }; /* members share memory */Files#
FILE *f = fopen("data.txt", "r"); /* "w" erases, "a" appends, "rb"/"wb" binary */
if (f == NULL) { perror("data.txt"); return 1; }
char line[256];
while (fgets(line, sizeof line, f) != NULL) { ... }
fprintf(out, "%d,%s\n", id, name);
fread(buf, sizeof buf[0], count, f);
fwrite(buf, sizeof buf[0], count, f);
fclose(f);Preprocessor#
#include <stdio.h> /* system header */
#include "mylib.h" /* your header */
#define SQUARE(x) ((x) * (x)) /* parenthesise everything */
#ifndef MYLIB_H /* include guard */
#define MYLIB_H
/* declarations */
#endif
#ifdef DEBUG
printf("debug: %d\n", value);
#endifBit manipulation#
x |= 1u << n; /* set bit n */
x &= ~(1u << n); /* clear bit n */
x ^= 1u << n; /* toggle bit n */
(x >> n) & 1u /* test bit n */
x & (x - 1) /* clear lowest set bit */Avoid undefined behavior#
- Never read or write outside an array; loops use
i < n. - Never overflow a signed integer; check limits first.
- Never dereference
NULL, freed or uninitialised pointers. - Never modify a variable twice in one expression (
i = i++). - Compile with
-Wall -Wextra, and test with-fsanitize=address,undefinedwhere available.
Want the full explanations? Go to the Learn C course →