This page has been superseded. Visit the new Programming Constructs section for updated sub-pages with worked examples, quizzes, and exercises.

Programming Constructs

IB Syllabus: B2.3 — Programming constructs

Table of Contents

  1. The Three Constructs
  2. Sequence
  3. Selection
    1. if / else if / else
    2. Nested if
    3. Boolean and Relational Operators in Conditions
  4. Iteration (Loops)
    1. for Loop
    2. while Loop
    3. do-while Loop
    4. Nested Loops
    5. Input Validation with a Loop
  5. Functions (Methods)
    1. Anatomy of a Method
    2. Calling a Method
    3. Scope: Local vs Global Variables
    4. Why Modularise?
  6. Prime Numbers — Putting It Together
  7. Quick Check
  8. Trace Exercise
  9. Practice Exercises

The Three Constructs

Every program — no matter how complex — is built from just three fundamental constructs:

Construct What it does
Sequence Instructions execute one after another, in order
Selection A decision is made — different paths are taken based on a condition
Iteration A block of code repeats while a condition holds

Understanding these three constructs before memorising syntax is the goal. Once you see how they map to logical thinking, the Java syntax becomes easier to read and write.


Sequence

Sequence is the default. Lines of code execute from top to bottom, exactly as written.

int a = 5;           // line 1
int b = 3;           // line 2 — runs after line 1
int sum = a + b;     // line 3 — runs after line 2
System.out.println("Sum: " + sum);    // line 4

The order matters. Swapping lines 1 and 3 would cause an error because a is not yet defined.


Before reading: Write in plain English how you would assign a grade to a score of 75 — use “if”, “otherwise if”, “otherwise”. Then check how closely that maps to the Java code below.

Selection

Selection allows a program to make a decision and follow different paths depending on whether a condition is true or false.

if / else if / else

import java.util.Scanner;

public class GradeEvaluator {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter your test score: ");
        int score = input.nextInt();

        if (score >= 90) {
            System.out.println("Grade: 7");
        } else if (score >= 80) {
            System.out.println("Grade: 6");
        } else if (score >= 70) {
            System.out.println("Grade: 5");
        } else if (score >= 60) {
            System.out.println("Grade: 4");
        } else if (score >= 40) {
            System.out.println("Grade: 3");
        } else {
            System.out.println("Below passing");
        }
    }
}

Java evaluates conditions from top to bottom and takes the first branch that is true. Once a branch is taken, the rest are skipped.

Nested if

if (num1 < num2) {
    if (num1 < num3) {
        System.out.println(num1 + " is the smallest.");
    } else {
        System.out.println(num3 + " is the smallest.");
    }
} else if (num2 < num3) {
    System.out.println(num2 + " is the smallest.");
} else {
    System.out.println(num3 + " is the smallest.");
}

Boolean and Relational Operators in Conditions

Operator Meaning Example
&& AND — both conditions must be true age >= 13 && age <= 17
\|\| OR — at least one must be true score < 0 \|\| score > 100
! NOT — reverses the boolean !isValid
== Equal to choice == 1
!= Not equal to input != 0

Use == to compare primitives (int, boolean, char). To compare Strings, use .equals():

if (name.equals("Alice")) { ... }   // ✓ correct
if (name == "Alice") { ... }        // ✗ compares memory addresses, not content

Before reading: How would you print the numbers 1 to 100 without a loop? What would need to change each time, and what would stay the same? Those two questions are the core of every loop.

Iteration (Loops)

Iteration allows a block of code to repeat without writing it multiple times. Java has three loop types. Choosing the right one depends on the situation.

Loop type Best used when
for You know exactly how many times to repeat
while You repeat as long as a condition is true (may not execute at all)
do-while The block must execute at least once before checking

for Loop

// Print numbers 1 to 5
for (int i = 1; i <= 5; i++) {
    System.out.println(i);
}

Structure: for (initialise; condition; update)

  • Initialise: runs once before the loop starts (int i = 1)
  • Condition: checked before each iteration; loop stops when false (i <= 5)
  • Update: runs after each iteration (i++)
// Multiplication table for 7
for (int i = 1; i <= 10; i++) {
    System.out.println("7 × " + i + " = " + (7 * i));
}

while Loop

// Count down from 5
int count = 5;
while (count > 0) {
    System.out.println(count);
    count--;
}
System.out.println("Go!");

The condition is evaluated before each iteration. If it is false from the start, the body never runs.

do-while Loop

// Ask for input until valid
import java.util.Scanner;
Scanner input = new Scanner(System.in);

int number;
do {
    System.out.print("Enter a number between 1 and 10: ");
    number = input.nextInt();
} while (number < 1 || number > 10);

System.out.println("You entered: " + number);

The body runs first, then the condition is checked. This guarantees at least one execution — useful for input validation and menus.

Nested Loops

Loops can be placed inside other loops. The inner loop completes fully for each iteration of the outer loop.

// Print a chessboard-style pattern
int size = 5;
int row = 1;
while (row <= size) {
    int col = 1;
    while (col <= size) {
        if (col == row || col == (size - row + 1)) {
            System.out.print("* ");
        } else {
            System.out.print("  ");
        }
        col++;
    }
    System.out.println();
    row++;
}

When debugging nested loops, trace the outer loop variable and inner loop variable separately in your trace table.

Input Validation with a Loop

A common pattern: keep asking until the user provides valid input.

import java.util.Scanner;

public class GuessingGame {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int secretNum = 7;
        int maxAttempts = 3;
        boolean found = false;

        while (!found && maxAttempts > 0) {
            System.out.print("Guess a number (1–10): ");
            int guess = input.nextInt();

            if (guess == secretNum) {
                System.out.println("Correct!");
                found = true;
            } else if (guess > secretNum) {
                System.out.println("Too high. Try lower.");
            } else {
                System.out.println("Too low. Try higher.");
            }
            maxAttempts--;
        }

        if (!found) {
            System.out.println("Out of attempts. The number was " + secretNum);
        }
    }
}

Think about it: If you need to check whether a number is prime in three different places in your program, how would you avoid writing the same logic three times?

Functions (Methods)

A method is a named, reusable block of code. Instead of writing the same logic multiple times, you define it once and call it wherever needed. This is called modularisation — breaking a large program into smaller, manageable pieces.

Anatomy of a Method

// returnType methodName(parameterType parameterName) {
//     body
//     return value;     ← only if returnType is not void
// }

public static int add(int a, int b) {
    return a + b;
}
Part Meaning
public static Access and scope modifiers (more on these in OOP)
int Return type — what type of value the method sends back
add Method name
int a, int b Parameters — values passed in
return a + b The result sent back to whoever called the method

Use void when a method does not return anything:

public static void printLine(String message) {
    System.out.println("--- " + message + " ---");
}

Calling a Method

public class Calculator {
    public static void main(String[] args) {
        int result = add(5, 3);                    // calls add, stores return value
        System.out.println("Sum: " + result);      // Sum: 8

        printLine("Done");                         // calls void method
    }

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

    public static void printLine(String message) {
        System.out.println("--- " + message + " ---");
    }
}

Try it: What happens if you write a second method and try to use a variable that was declared inside main? Predict whether it will compile, then try it.

Scope: Local vs Global Variables

Scope determines where a variable can be accessed.

public class ScopeDemo {
    static int globalCount = 0;         // class-level — accessible by all methods

    public static void main(String[] args) {
        int localVar = 10;              // local — only exists inside main
        increment();
        System.out.println(globalCount);   // 1
        // System.out.println(localVar);   ← would work here
    }

    public static void increment() {
        globalCount++;
        // System.out.println(localVar);   ← ERROR: localVar not in scope here
    }
}
Type Declared Accessible
Local Inside a method Only within that method
Global (static) Outside methods, at class level By all methods in the class

Prefer local variables whenever possible. Relying too heavily on global variables makes programs harder to understand and debug. Methods should ideally receive the data they need through parameters and return results through return values.

Why Modularise?

  • Readability: calculateDiscount(price, rate) is clearer than 10 lines of arithmetic in the middle of main
  • Reusability: write once, call many times
  • Testing: you can test a single method in isolation
  • Maintainability: change the logic in one place rather than everywhere it appears

Prime Numbers — Putting It Together

public class PrimeNumbers {
    public static void main(String[] args) {
        System.out.println("Prime numbers between 2 and 100:");
        for (int n = 2; n <= 100; n++) {
            if (isPrime(n)) {
                System.out.print(n + " ");
            }
        }
    }

    // Returns true if n is prime, false otherwise
    public static boolean isPrime(int n) {
        for (int divisor = 2; divisor <= n / 2; divisor++) {
            if (n % divisor == 0) {
                return false;   // found a factor — not prime
            }
        }
        return true;            // no factors found — is prime
    }
}

Notice how isPrime does one focused job and main just calls it in a loop. This is modularisation in action.


Quick Check

Q1. Which loop is guaranteed to execute at least once?

Q2. How many times does the body of for (int i = 0; i < 5; i++) execute?

Q3. A local variable declared inside a method can be accessed from:

Q4. What is the final value of total?
int total = 0; for (int i = 1; i <= 3; i++) total += i;

Q5. Which loop is most appropriate when the number of iterations is known in advance?


Trace Exercise

Trace this loop — fill in the value of i and product after each iteration.

int product = 1;
int n = 4;
for (int i = 1; i <= n; i++) {
    product = product * i;
}
Iterationi (at start of body)product after body
1
2
3
4

What is product after the loop ends?

What does this program compute?


Practice Exercises

  1. Write a method isEven(int n) that returns true if n is even. Use it in main to print all even numbers from 1 to 50.
  2. Write a program with a do-while loop that presents a menu (1. Add, 2. Subtract, 3. Quit), reads two numbers, performs the chosen operation, and repeats until the user chooses 3.
  3. Write a method celsiusToFahrenheit(double c) that returns the Fahrenheit equivalent. Call it from a loop that converts 0°C to 100°C in steps of 10.
  4. Trace this loop — complete a trace table for i and total:
    int total = 0;
    for (int i = 1; i <= 5; i++) {
        total = total + i;
    }
    
  5. Challenge: Write a program that prints all prime numbers between two values entered by the user. Use a isPrime method and validate that the lower bound is less than the upper bound.

Back to top

© EduCS.me — A resource hub for IB Computer Science

This site uses Just the Docs, a documentation theme for Jekyll.