C Cheatsheet

View saved

C rewards precision: types, memory, and undefined behavior matter. This sheet collects the patterns you reach for most often while learning.

Pair it with the C tutorials for install steps, longer explanations, and safer habits around pointers and allocation.

Compile & run

gcc one-liner

Compile a source file to an executable, then run it. -Wall enables useful warnings.

gcc -Wall -o hello hello.c
./hello

main

Program entry point. Return 0 for success. argc/argv receive command-line arguments.

#include <stdio.h>

int main(void) {
  printf("Hello\n");
  return 0;
}

Headers

#include pulls declarations. Angle brackets for system headers; quotes for your own.

#include <stdio.h>
#include <stdlib.h>
#include "util.h"

Makefile sketch

Automate compile rules. make rebuilds only what changed when dependencies are listed.

CC=gcc
CFLAGS=-Wall -g

hello: hello.c
	$(CC) $(CFLAGS) -o hello hello.c

printf / scanf

Formatted output and input. Always check scanf's return value in real programs.

int n;
printf("n = ");
if (scanf("%d", &n) == 1) {
  printf("got %d\n", n);
}

Types & operators

Basic types

int, long, short, char, float, double, and _Bool (or bool with ). Sizes are platform-dependent.

int count = 3;
double pi = 3.14;
char letter = 'A';
_Bool ok = 1;

sizeof

Yields the size in bytes of a type or expression. Result has type size_t.

#include <stdio.h>
printf("%zu\n", sizeof(int));
printf("%zu\n", sizeof(double));

Arithmetic & assignment

+ - * / % plus compound assignment. Integer division truncates toward zero.

int a = 10;
a += 2;
int q = a / 4;  /* 3 */

Comparison & logic

Relational operators yield 0 or 1. && and || short-circuit; ! negates.

int x = 5;
if (x > 0 && x < 10) {
  /* ... */
}

Casts

Explicit conversion between types. Prefer casts that widen; narrowing can lose data.

double d = 9.7;
int n = (int)d;  /* 9 */

Control flow

if / else

Branch on a nonzero condition. Zero is false; any other value is true.

int score = 85;
if (score >= 90) {
  puts("A");
} else if (score >= 80) {
  puts("B");
} else {
  puts("C");
}

switch

Jump among integer/enum case labels. Use break unless you intentionally fall through.

int day = 2;
switch (day) {
  case 1: puts("Mon"); break;
  case 2: puts("Tue"); break;
  default: puts("Other"); break;
}

for / while

for is common for counted loops; while for condition-driven loops.

for (int i = 0; i < 3; i++) {
  printf("%d\n", i);
}
int n = 3;
while (n > 0) {
  printf("%d\n", n--);
}

break / continue

break exits the nearest loop or switch; continue starts the next loop iteration.

for (int i = 0; i < 10; i++) {
  if (i % 2) continue;
  if (i > 6) break;
  printf("%d\n", i);
}

Functions & arrays

Function definition

Return type, name, and parameters. Prototypes in headers let callers see the signature first.

int add(int a, int b) {
  return a + b;
}

int main(void) {
  return add(2, 3) == 5 ? 0 : 1;
}

Pass by value

Arguments are copied. To modify the caller's variable, pass a pointer.

void bump(int *p) {
  (*p)++;
}

int x = 1;
bump(&x);  /* x is 2 */

Arrays

Contiguous elements of one type. Name decays to a pointer to the first element in most expressions.

int nums[3] = {3, 1, 4};
printf("%d\n", nums[0]);
nums[1] = 2;

Array length habit

C arrays do not store length. Pass a count alongside the pointer, or use a sentinel.

void print_ints(const int *a, size_t n) {
  for (size_t i = 0; i < n; i++) {
    printf("%d\n", a[i]);
  }
}

2D arrays

Array of arrays. Contiguous row-major layout; pass dimensions carefully to functions.

int grid[2][3] = {{1, 2, 3}, {4, 5, 6}};
printf("%d\n", grid[1][0]);  /* 4 */

Pointers & memory

& and *

& takes an address; * dereferences a pointer. Pointer type must match the object pointed to.

int x = 10;
int *p = &x;
printf("%d\n", *p);
*p = 20;  /* x is 20 */

NULL

Null pointer constant. Check pointers from allocation or optional results before dereferencing.

int *p = NULL;
if (p == NULL) {
  puts("no object");
}

malloc / free

Allocate heap memory and release it. Always free what you malloc; set pointers to NULL after free if reused.

#include <stdlib.h>

int *a = malloc(3 * sizeof *a);
if (!a) return 1;
a[0] = 1;
free(a);
a = NULL;

Pointer arithmetic

p + 1 advances by one element of *p's type, not one byte. Prefer array indexing for clarity.

int nums[] = {10, 20, 30};
int *p = nums;
printf("%d\n", *(p + 1));  /* 20 */

Undefined behavior (reminder)

Out-of-bounds access, use-after-free, and signed overflow are undefined—compilers assume they never happen.

/* Avoid: */
/* int a[2]; a[2] = 1; */
/* free(p); *p = 1; */

Strings & structs

C strings

char arrays ending in '\0'. Use string.h helpers; never forget space for the terminator.

#include <stdio.h>
#include <string.h>

char name[16] = "Ada";
printf("%zu\n", strlen(name));

strcpy / snprintf

Prefer bounded copies. snprintf writes at most size-1 chars and always null-terminates when size > 0.

char buf[8];
snprintf(buf, sizeof buf, "%s", "hello");

struct

Groups related fields under one type. Access members with . or -> via a pointer.

struct Point {
  int x;
  int y;
};

struct Point p = {3, 4};
struct Point *q = &p;
printf("%d\n", q->x);

typedef

Creates an alias for a type name, often for structs or function pointers.

typedef struct {
  int x;
  int y;
} Point;

Point p = {1, 2};

File I/O sketch

fopen / fscanf / fprintf / fclose for text files. Always check fopen for NULL.

#include <stdio.h>

FILE *f = fopen("out.txt", "w");
if (!f) return 1;
fprintf(f, "hi\n");
fclose(f);

Comments

One comment per signed-in account. Comments are saved with this page’s URL.