CLA (C language) cheat sheet
CLA (C language) · Keep the key ideas within reach.
C Essentials 1 (C101): Basics of C Programming
A C program starts execution at main; int main(void) or int main(int argc, char *argv[]) are standard forms. Returning 0 signals success to the host environment.
Preprocessor directives begin with # and are handled before compilation: #include <stdio.h> for standard I/O, #define PI 3.14159 for symbolic constants (no semicolon, no type).
Fundamental types and typical sizes: char (1 byte, at least 8 bits), int (at least 16 bits, usually 32), float (usually 32), double (usually 64). Use sizeof(type) to get exact size.
Integer literals: decimal 42, octal 052, hexadecimal 0x2A. Suffixes: U for unsigned, L for long. Floating literals default to double; append f for float.
printf conversion specifiers: %d int, %u unsigned, %ld long, %f double (printf), %lf double (scanf), %c char, %s string, %x hex, %p pointer. scanf needs addresses: scanf("%d", &x).
Escape sequences: \n newline, \t tab, \ backslash, " double quote, ' single quote, \0 null character, \x41 hex A. Character constants use single quotes: 'A'.
Operators and precedence: postfix ++/-- > prefix ++/-- and unary ! ~ + - > multiplicative * / % > additive + - > relational < <= > >= > equality == != > logical && > logical || > assignment =.
Integer division truncates toward zero: 7/2 yields 3, -7/2 yields -3. Modulus % requires integer operands; result has sign of the dividend. Mixing int and double promotes int to double.
Control flow: if/else, switch (integer or char expression; case labels must be constant; break exits; default handles unmatched), while, do-while (body runs at least once), for (init; condition; update).
C Essentials 2 (C102): Intermediate C Programming
Storage duration and scope: auto (default local, lifetime block), static local (lifetime program, initialized once), static global (internal linkage), extern (declaration, external linkage), register (hint, no address-of).
Type qualifiers: const prevents modification through that name; volatile tells compiler the object may change unexpectedly; restrict promises no aliasing (C99).
The comma operator evaluates left then right and yields the right value: x = (a=3, a+2) sets x to 5. Do not confuse with argument-separating commas.
Bitwise operators: & AND, | OR, ^ XOR, ~ NOT, << left shift, >> right shift. Shifting by width or negative count is undefined. Use unsigned types for bit manipulation.
Integer promotions: char and short promote to int in expressions. Usual arithmetic conversions rank long double > double > float > unsigned long > long > unsigned int > int.
Preprocessor: #include "file" searches local directory first; #include searches system paths. #if/#ifdef/#ifndef/#else/#endif for conditional compilation; #undef removes a macro.
Macros are textual substitution: #define SQUARE(x) ((x)*(x)) requires parentheses to avoid precedence bugs. Side effects like SQUARE(i++) evaluate i twice.
String functions from <string.h>: strlen (excludes '\0'), strcpy (unsafe), strncpy (may not null-terminate), strcmp (0 if equal), strcat, strchr, strstr.
Dynamic memory: malloc(size) returns void* or NULL; calloc(n, size) zero-initializes; realloc(ptr, size) resizes; free(ptr) releases. Always check for NULL and free exactly once.
Functions, Arrays, Pointers and Memory Handling
Function prototype declares return type, name, parameter types: int sum(int a, int b); Definition supplies body. In C, empty parentheses () means unspecified parameters; use (void) for none.
Parameters pass by value: the function receives copies. To modify caller data, pass a pointer: void swap(int *a, int *b) { int t=*a; *a=*b; *b=t; }.
Arrays decay to pointers to their first element when passed to functions, so size information is lost; pass length explicitly or use a sentinel. sizeof(arr) inside a function yields pointer size.
Array indexing is pointer arithmetic: a[i] is *(a+i). Valid indices 0..n-1. Out-of-bounds access is undefined behavior; no bounds checking in C.
Pointer declaration: int *p; & gives address-of, * dereferences. A pointer must point to valid storage before dereference. NULL is a null pointer constant; dereferencing NULL is undefined.
Pointer arithmetic scales by pointed-to type: p+1 advances sizeof(*p) bytes. Subtracting two pointers into the same array yields element count (ptrdiff_t).
Multidimensional arrays: int m[3][4]; m is array of 3 arrays of 4 ints. When passing, specify all but first dimension: void f(int m[][4]).
Function pointers: int (*fp)(int,int) = add; call as fp(2,3) or (*fp)(2,3). Arrays of function pointers enable dispatch tables.
Memory regions: stack (automatic locals, grows/shrinks), heap (malloc/free), static/global (program lifetime), code (text). Returning address of local variable is undefined.
Structures, File I/O and Preprocessor
struct defines a composite type: struct Point { int x, y; }; Access members with dot for objects, arrow -> for pointers: p->x equals (*p).x. Use typedef to avoid repeating struct keyword.
Structure layout may include padding for alignment; sizeof(struct) can exceed sum of members. Order members to minimize padding. Use offsetof (stddef.h) to get member offset.
Bit-fields: struct Flags { unsigned a:1; unsigned b:2; }; width in bits; implementation-defined packing and ordering.
Unions overlay members in same storage: union U { int i; float f; }; size is largest member. Reading a member other than last written is type punning (implementation-defined).
File I/O: FILE *fp = fopen("name", "r"); modes r, w, a, r+, w+, a+, add b for binary. Check NULL on failure. fclose(fp) flushes and releases.
Formatted file I/O: fprintf(fp, "%d\n", x), fscanf(fp, "%d", &x). Character I/O: fgetc/fputc, getc/putc. String I/O: fgets(buf, size, fp) reads at most size-1 chars and null-terminates; fputs writes string.
Binary I/O: fread(ptr, size, count, fp) and fwrite(ptr, size, count, fp) return number of items transferred. Use fseek(fp, offset, SEEK_SET/SEEK_CUR/SEEK_END) and ftell(fp) for positioning.
Preprocessor macros: #define MAX(a,b) ((a)>(b)?(a):(b)) - parenthesize parameters and whole expression. Stringize #x turns argument into string literal; token-paste ## concatenates tokens.
Predefined macros: LINE (current line), FILE (source filename), DATE, TIME, STDC. #pragma implementation-defined; #error emits diagnostic; #line changes reported line/file.