Skip to content

Chapter 4 of 7

Functions and Control Flow

C functions consist of a return type, name, and parameter list. A function prototype declares these without a body, allowing the compiler to check call-site argument types and forward-reference functions defined later in the file or in another translation unit. Functions declared void perform actions without producing a value and use a bare return statement, while a non-void function that reaches its closing brace without returning yields undefined behavior if the caller uses the result. Variadic functions, declared with ... like printf, accept a variable number of arguments and use va_list, va_start, va_arg, and va_end from <stdarg.h> to traverse them; default argument promotions convert float to double and small integers to int, so va_arg must use double when extracting floating-point arguments. The restrict qualifier on a pointer tells the compiler that no other pointer aliases the same object, which permits aggressive optimizations but is undefined behavior to violate.

Recursion occurs when a function calls itself, with each call creating a new stack frame holding its own parameters and locals. Every recursive function needs a base case that terminates the calls, otherwise the stack eventually overflows. Iteration through loops uses constant memory and can express anything recursion can, though recursive code is often clearer for tree and graph traversals. Function pointers store the address of a function and are declared like int (*fptr)(int, int), then assigned and called through the pointer; they are commonly used as callbacks, where one function is passed to another to be invoked later, enabling flexible, reusable designs. The inline keyword hints that a function should be expanded at the call site rather than emitted as a separate function, though modern compilers decide freely and a non-inline external definition is still typically provided so the linker can find a callable symbol.

C provides several control-flow constructs. The while loop tests the condition before each iteration and may execute zero times, while do-while tests afterward and always runs at least once. The switch statement dispatches on an integer or enum expression, with cases falling through unless terminated by break and a default branch handling unmatched values. The ternary operator ?: is C's only three-operand operator and returns one of two expressions based on a condition, while the comma operator evaluates its left operand, discards it, and returns the right operand, having the lowest precedence of any operator. The increment forms ++i (prefix) and i++ (postfix) differ in whether they increment before or after returning the value, which matters in expressions like arr[++i] = x versus arr[i++] = x. Operators follow defined precedence and associativity rules, with parentheses the safest way to make intent explicit. Sequence points, introduced by ;, &&, ||, ?:, and ,, define when all side effects of prior evaluations are complete, so expressions like a = i++ + i++ invoke undefined behavior. The goto statement is generally discouraged but is accepted for breaking out of nested loops to a centralized cleanup label. Functions that never return can be marked _Noreturn, allowing the compiler to warn about unreachable code after the call.

All chapters
  1. 1Pointers and Dynamic Memory
  2. 2Data Types, Variables, and User-Defined Aggregates
  3. 3Arrays, Strings, and Memory Operations
  4. 4Functions and Control Flow
  5. 5File I/O and Program Termination
  6. 6The Preprocessor and Macros
  7. 7Compilation, Linking, and Program Structure

Drill it

Reading is not remembering. These come from the C Programming deck:

Q

What is a pointer in C?

A pointer is a variable that stores the memory address of another variable.Declared using the * operator: int *ptr;The address-of operator &amp; retrieves a var...

Q

How do you dereference a pointer?

Dereferencing means accessing the value stored at the address a pointer holds.Use the * operator: int val = *ptr;This retrieves the value at the memory location...

Q

What is a NULL pointer?

A NULL pointer is a pointer that does not point to any valid memory location.Assigned with: int *ptr = NULL;Always check for NULL before dereferencing to avoid...

Q

What does malloc() do in C?

malloc() allocates a block of memory on the heap and returns a pointer to it.Syntax: int *p = (int *)malloc(n * sizeof(int));Returns NULL if allocation fails. M...