IAE Academy

The whole Programming in C formula sheet, to print

17 formulas in 3 topics, each with when to use it. Each is explained in the topic notes.

C fundamentals: types, operators, expressions and control flow

Read the notes

N-BIT INTEGER RANGES

Holds for any fixed-width integer type once its width in bits and its signedness are known. Use it to check whether a constant fits the type it is stored in.

STORING AN OUT-OF-RANGE VALUE V IN A SIGNED N-BIT TYPE

The standard leaves this conversion implementation-defined. On the two's complement machines these notes assume, the result is the value above. For example, 200 stored in a signed 8-bit char gives . An unsigned -bit type always stores , and that case is defined by the standard.

TWO'S COMPLEMENT NEGATION AND UNSIGNED WRAPAROUND

Here is the bitwise complement. Arithmetic done in unsigned int (or a wider unsigned type) never overflows in the undefined-behaviour sense: it is defined to wrap modulo . Signed overflow, such as INT_MAX + 1, is undefined behaviour. Converting an out-of-range value to a signed type is implementation-defined (see the storing rule in the previous section).

INTEGER DIVISION IDENTITY IN C

Holds for C integer operands when is representable. Truncation toward zero means that the sign of a % b follows the sign of a. Division or % by zero is undefined behaviour.

Pointers, arrays and strings in C

Read the notes

1-D ARRAY INDEXING / POINTER ARITHMETIC

For any array a with element type T. The same value is the address a + i. C arrays always start at index 0, and memory is byte-addressable.

2-D ROW-MAJOR ADDRESS (C ARRAYS)

The array is declared T a[R][C]. C is the number of COLUMNS (the row length), i is the row index and j is the column index, both starting at 0. The number of rows R does not appear.

3-D ROW-MAJOR ADDRESS

The array is declared T a[X][Y][Z], with all indices starting at 0. The first dimension X does not appear.

GENERAL ROW-MAJOR ADDRESS WITH ARBITRARY INDEX BOUNDS

Use this for a language-neutral array A[l1..u1][l2..u2] with element size w bytes, where Base is the address of A[l1][l2]. For column-major storage, swap the roles of the two indices: Base + ((j − l2)(u1 − l1 + 1) + (i − l1)) × w. For C arrays, l1 = l2 = 0 and this reduces to the formula above.

STORAGE FOR `CHAR T[] = "...";` (SIZE LEFT OUT)

n is the number of characters in the literal, which contains no embedded '\0'. The +1 is the terminator. So char t[] = "GATE"; gives sizeof(t) = 5 while strlen(t) = 4. If a size is written, the array has that size: char t[10] = "GATE"; has sizeof(t) = 10, with the unused bytes set to '\0'. char t[4] = "GATE"; is legal C but stores NO terminator.

MEMBER OFFSET (ALIGNMENT RULE)

Apply it member by member, in declaration order. 'End of previous member' is that member's offset plus its size, and it is 0 for the first member. align(m) is the alignment of m's type, equal to its size under the convention above.

STRUCT TOTAL SIZE (WITH TRAILING PADDING)

E is the end offset of the last member (its offset plus its size). A_max is the largest alignment among all members.

UNION SIZE

S_max is the size of the largest member and A_max is the largest alignment among all members.

Recursion: tracing recursive programs

Read the notes

CALL COUNT: SINGLE (LINEAR) RECURSION

For a function that makes exactly one recursive call, on , and stops at n == 0 without a further call (for example, a factorial with base case n == 0). counts the initial call and the base-case call. If the base case is at n == 1 instead (with ), the count is . Always check where the base case fires.

CALL COUNT: HALVING RECURSION

For a function that makes one recursive call on n / 2 (integer division) and stops at n == 0, like bin above. The calls that print or do work (those with ) number , which is the number of bits of . The extra call is the base case n == 0.

CALL COUNT: NAIVE FIBONACCI (TWO CALLS, ON N-1 AND N-2)

For a function with base cases n == 0 and n == 1 that makes no further calls, and otherwise calls itself on and . The counts the current call. is the standard Fibonacci sequence . Of the calls, are base-case calls (leaves) and make further calls. The count grows as , where .

UNROLLING SINGLE RECURSION ON N-1

Holds when each non-base call does a constant amount of work and makes exactly one recursive call on , and the base case at costs . Substitute repeatedly: , then put .

TWO RECURSIVE CALLS ON N-1 (TOWER OF HANOI MOVES)

Unrolling gives ; put . The same shape counts calls when the base case is n == 0 and is itself counted: .