Study guide

10.3 Functions & Recursion

U.S. Air Force Cyber Test CSAT/ICTL

Track your progress as you read

Finished sections get a check mark.

1 Introduction & Exam Overview

1.1 Current Exam Facts 1.2 Cyber AFSCs & Qualification Pipeline 1.3 How to Use This Guide & Study Plan

2 Number Systems & Encoding

2.1 Binary & Decimal Conversion 2.2 Hexadecimal & ASCII 2.3 Bitwise Operations & Two's Complement

3 Computing Architecture

3.1 Memory Hierarchy 3.2 CPU, Components & Data Path 3.3 Core Data Structures

4 Boolean Logic & Storage

4.1 Boolean Algebra & Logic Gates 4.2 Encoding, Files & Storage Concepts

5 Networking Models

5.1 OSI Model 5.2 TCP/IP Model & Encapsulation 5.3 Topologies & Transmission Media

6 Addressing & Subnetting

6.1 IPv4 Addressing 6.2 Subnetting & CIDR 6.3 IPv6 Fundamentals

7 Protocols & Network Services

7.1 TCP, UDP & Well-Known Ports 7.2 DNS & DHCP 7.3 Routing & Switching Basics

8 Cybersecurity Foundations

8.1 CIA Triad & Security Goals 8.2 Threats, Vulnerabilities & Malware 8.3 Social Engineering & Human Factors

9 Defensive Controls

9.1 Access Control & Authentication 9.2 Firewalls, IDS & IPS 9.3 SIEM & Defense in Depth

10 Programming Fundamentals

10.1 Variables, Types & Operators 10.2 Control Flow 10.3 Functions & Recursion

11 Languages & Debugging

11.1 Python Essentials for the Cyber Test 11.2 C++ Basics & Debugging Concepts

12 Operating Systems

12.1 Linux Fundamentals & Commands 12.2 Windows Fundamentals 12.3 Processes, Permissions & File Systems

13 Cryptography

13.1 Symmetric Encryption (AES) 13.2 Asymmetric Crypto & PKI 13.3 Hashing, MACs & Integrity

14 ICTL-Style Logic Reasoning

14.1 Deductive Logic & Syllogisms 14.2 Sequences & Pattern Recognition 14.3 Arrangement & Conditional Puzzles

15 Test Strategy & Mixed Review

15.1 Pacing, Elimination & AF Testing Day 15.2 Mixed Domain Review & Next Steps

10.3 Functions & Recursion

Key Takeaways Explain This Topic AI

A function packages parameters, a body, and an optional return value; calling it transfers control, then resumes after the call with the returned result

The call stack grows with each nested call and shrinks on return — each frame holds its own local variables and return address

Recursion means a function calls itself; every correct recursive design needs a base case that stops and a recursive case that moves toward that base

Missing or unreachable base cases cause infinite recursion / stack overflow; wrong base cases yield wrong answers even if the stack stays finite

Tracing recursion means expanding calls until the base case, then substituting returned values on the way back up the stack

Last updated: July 2026

Functions let you name a reusable chunk of logic. Recursion is the special case where that chunk calls itself. Cyber Test items on this topic are almost always trace-the-calls problems: what does f(3) return, how many times does a body run, or what goes wrong when the base case is missing?

Functions: Inputs, Body, Output

A function (also called a procedure or method in related contexts) has:

  • Piece Role
  • Name How you call it
  • Parameters Placeholders for incoming values
  • Body Statements that run on each call
  • Return value Result handed back to the caller (optional for "void" actions)
  • Language-agnostic: FUNCTION add(a, b)
  • RETURN a + b
  • END FUNCTION

SET s TO add(2, 5) # s becomes 7

Python: def add(a, b):

return a + b

  • s = add(2, 5)
  • C++: int add(int a, int b) {
  • return a + b;
  • }
  • int s = add(2, 5);
  • Parameter Binding

On a call add(2, 5) , parameter a gets 2 and b gets 5 for that invocation . Those names are local : they do not permanently overwrite same-named variables in the caller unless the language uses explicit reference/pointer semantics (advanced for this exam). For aptitude items, assume pass-by-value : the function works on copies; assigning to a parameter inside does not change the caller's variable.

Return Ends the Function

When return executes, the function stops. Statements after an executed return in the same path do not run. Multiple return points (often inside if branches) are normal; the first one hit wins for that call.

Call Stack Intuition

Think of the call stack as a stack of plates. Each function call pushes a frame (locals, parameters, where to resume). Each return pops a frame. FUNCTION main()

  • SET x TO double(3)
  • RETURN x
  • END
  • FUNCTION double(n)
  • RETURN n * 2
  • END
  • main starts → frame: main
  • double(3) called → stack: main | double (n=3)
  • double returns 6 → pop double ; main resumes with x = 6
  • main returns → stack empty

You do not need OS-level detail. You need: deeper call = more frames , return = resume caller with a value .

Nested Calls SET r TO add(double(2), 4)

Order: evaluate double(2) first (returns 4), then add(4, 4) (returns 8). Inner calls complete before the outer call that needs their results.

Recursion: Functions That Call Themselves

Recursion solves a problem by reducing it to a smaller instance of the same problem until a trivial case appears.

Every correct recursive function needs:

  • Base case — condition where you return a known answer without calling yourself again
  • Recursive case — call yourself on a smaller input, then combine the result
  • Classic: Factorial
  • Definition: n! = 1 when n is 0 or 1; otherwise n! = n * (n-1)! . FUNCTION fac(n)
  • IF n <= 1 THEN
  • RETURN 1
  • ELSE
  • RETURN n * fac(n - 1)
  • END IF
  • END FUNCTION
  • Trace fac(4) (expand downward): fac(4) → 4 * fac(3)
  • fac(3) → 3 * fac(2)
  • fac(2) → 2 * fac(1)
  • fac(1) → 1 (base case)
  • Collapse upward: fac(2) = 2 * 1 = 2
  • fac(3) = 3 * 2 = 6
  • fac(4) = 4 * 6 = 24

Call stack at deepest point: frames for fac(4) , fac(3) , fac(2) , fac(1) stacked. After base case, frames pop in reverse order.

Python flavor: def fac(n):

if n <= 1:

  • return 1
  • return n * fac(n - 1)
  • C++ flavor: int fac(int n) {
  • if (n <= 1) return 1;
  • return n * fac(n - 1);
  • }
  • Countdown Trace (Side Effects)
  • Not every recursive example returns a product; some exams ask how many prints occur. FUNCTION boom(n)
  • IF n == 0 THEN
  • PRINT "done"
  • RETURN
  • END IF
  • PRINT n
  • boom(n - 1)
  • END FUNCTION

boom(3)

Output order: 3 , then 2 , then 1 , then done . Prints happen before the recursive call, so they appear descending. If PRINT n were placed after boom(n-1) , you would see done first, then 1 , 2 , 3 on the way back up — placement relative to the recursive call is a frequent trap.

Common Recursion Traps

Trap What happens Fix / recognition

Missing base case Infinite recursion; stack grows until failure Every path must eventually hit a non-recursive return

  • Base case never reached e.g. always call fac(n) instead of fac(n-1) Argument must move toward the base
  • Wrong base value e.g. fac(1) returns 0 Yields wrong numeric answer with finite stack
  • Off-by-one in base n == 0 vs n <= 1 for factorial Check the mathematical definition used in the stem

Confusing with loops Same problem often solvable iteratively Recursion questions want stack/base-case reasoning

  • Broken example (infinite): FUNCTION bad(n)
  • RETURN n * bad(n) # never decreases; no base case
  • END
  • Broken example (finite but wrong): FUNCTION bad_fac(n)

IF n == 0 THEN RETURN 0 # should return 1 for 0!

  • RETURN n * bad_fac(n - 1)
  • END

bad_fac(3) → 3 * 2 * 1 * 0 = 0 . The stack behaved, but the base case lied.

  • Worked Mixed Example: Recursion + Control Flow FUNCTION sum_odd(n)
  • IF n <= 0 THEN
  • RETURN 0
  • END IF
  • IF n % 2 == 0 THEN
  • RETURN sum_odd(n - 1)
  • ELSE
  • RETURN n + sum_odd(n - 1)
  • END IF
  • END FUNCTION

Trace sum_odd(5) :

  • 5 odd → 5 + sum_odd(4)
  • 4 even → sum_odd(3)
  • 3 odd → 3 + sum_odd(2)
  • 2 even → sum_odd(1)
  • 1 odd → 1 + sum_odd(0)
  • 0 base → 0

Collapse: 1+0=1 , then 3+1=4 , then 5+4=9 . So sum_odd(5) = 9 (1+3+5).

This blends modulo checks from operators, branching from control flow, and stack unwinding from recursion — representative of harder Cyber Test programming items.

Connecting Back to Earlier Sections

Variables/types: parameters are local variables; return types matter when mixing ints and bools in conditions.

Operators: recursive cases are often n * f(n-1) or n + f(n-1) ; modulo selects branches.

Control flow: base cases are if s; without them, recursion never stops — the same discipline as loop termination conditions.

Exam Habits

Find the base case first; evaluate it cold.

Expand calls until the base, then substitute returns upward.

Count stack depth only if asked; otherwise focus on returned values or printed order.

Ask whether the recursive argument shrinks toward the base every time.

Watch print/return placement before vs after the recursive call.

With variables, control flow, and functions/recursion in place, you have the language-agnostic core of the programming domain. Language-specific syntax and debugging patterns build on this foundation in the following chapter.