Skip to content
Laviyx Learn

Try

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#

C
#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 */
}
Terminal
gcc -std=c17 -Wall -Wextra -g main.c -o app
./app

Types and format specifiers#

TypeExampleprintfscanf
intint n = 42;%d%d
long longlong long big = 9000000000LL;%lld%lld
unsignedunsigned u = 7u;%u%u
doubledouble price = 49.99;%f, %.2f%lf
charchar grade = 'A';%c" %c"
stringchar name[20] = "Asha";%s%19s
size_tsize_t len = strlen(s);%zu%zu
pointerint *p = &n;%p (cast to void *)
C
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#

KindOperators
Arithmetic+ - * / % (integer / truncates)
Comparison== != < > <= >=
Logical&& || ! (short-circuit)
Bitwise& | ^ ~ << >>
Assignment= += -= *= /= %= &= |= <<=
Increment++x x++ --x x--
Other?: sizeof & (address) * (dereference) -> .

Input and output#

C
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#

C
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#

C
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#

C
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#

C
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#

C
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#

C
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#

C
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#

C
#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);
#endif

Bit manipulation#

C
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,undefined where available.

Want the full explanations? Go to the Learn C course →