Welcome to Program Structure!

Welcome to this study guide on Program Structure for CCEA AS Level Digital Technology (Unit AS 1: Approaches to Systems Development). Have you ever tried building a giant LEGO castle without the instruction booklet? It would probably end up messy, unstable, and almost impossible to fix if you made a mistake near the base. Writing computer programs is exactly the same!

In this chapter, you will learn how software developers break massive, complicated problems into smaller, manageable chunks. We will explore structured design, the magic of subroutines, how data moves between different parts of a program, and why good structure saves time, money, and headaches. Don't worry if some of the terminology looks daunting at first — we will break down every single idea step by step with everyday analogies!


1. Top-Down Design and Modular Programming

What is Decomposition?

When software engineers face a huge software system (like a banking app or a video game), they do not just sit down and start writing thousands of lines of code in one long block. Instead, they use a technique called top-down design (also known as stepwise refinement or decomposition).

Decomposition means breaking down a complex problem into smaller, simpler, and more manageable sub-tasks. Each sub-task can then be broken down even further until each individual piece is simple enough to be programmed easily.

Everyday Analogy: Think about organizing a school music festival. You wouldn't just write "Do Festival" on your to-do list. You would decompose it into: 1. Book the venue, 2. Arrange sound equipment, 3. Sell tickets, and 4. Organize performers. Then you could break "Sell tickets" down into online sales, paper tickets, and cash handling.

What is Modular Programming?

Once a problem has been broken down, the individual sub-tasks are written as independent self-contained units of code called modules (or subroutines). This overall approach is called modular programming.

Structure Charts (Hierarchy Diagrams):
Software designers use structure charts to visually represent the top-down design. The main program sits at the very top, and lines branch downwards to show which modules are called by other modules.

Key Advantages of a Modular Approach

Why do we bother splitting programs into modules? Here are the major benefits:

Work can be divided among a team: Different programmers can work on different modules at the exact same time, speeding up development.
Easier testing and debugging: Each module can be tested and verified on its own (unit testing) before being joined with the rest of the system.
Code reusability: A module written for one task (e.g., validating an email address) can be reused multiple times across the same program or even in entirely different software projects.
Easier maintenance: If a bug is found or an update is needed, developers only need to edit and re-test that specific module rather than rewriting the whole program.
Improved readability: Code is neat, well-organized, and easier for new developers to understand.

Key Takeaway: Top-down design breaks big problems into small sub-tasks. Modular programming writes those sub-tasks as independent blocks of code, making software easier to write, test, share, and maintain.


2. Subroutines: Procedures vs Functions

A subroutine is a named, self-contained section of code designed to perform a specific task. Whenever the main program needs that task carried out, it "calls" or invokes the subroutine.

In structured programming, subroutines fall into two main categories: Procedures and Functions. Understanding the difference between them is a classic exam favorite!

What is a Procedure?

A procedure is a subroutine that carries out a sequence of instructions or operations (such as clearing a screen, printing a receipt, or saving data to a file). Crucially, a standard procedure does not return a single value back to the point in the program where it was called.

Example: A procedure called DisplayWelcomeBanner() prints the game logo and instructions onto the screen.

What is a Function?

A function is a subroutine that carries out a task and always returns a single value back to the statement that called it. When a function finishes its work, it replaces the function call with its output value.

Example: A function called CalculateVat(price) takes a price, calculates the \(20\%\) tax, and sends the resulting number back so it can be added to an invoice.

Quick Comparison:
Procedure: Performs an action. Does not have to return a value.
Function: Performs a calculation/action and must return a value to the calling program.

Memory Trick: Think of the letter F in Function standing for Fetches a value!

Key Takeaway: Both are subroutines, but a function always sends a single calculated result back to where it was called, whereas a procedure simply executes its set of instructions.


3. Parameters and Parameter Passing

Subroutines often need extra information from the main program to do their job. For example, a square root function needs to know which number you want to find the square root of!

Parameters vs Arguments

• A parameter is the special variable listed in the subroutine definition (the placeholder).
• An argument is the actual data value passed into that parameter when the subroutine is called.

Example: In Area(length, width), length and width are parameters. When you run Area(10, 5), the numbers \(10\) and \(5\) are the arguments.

How Data is Passed: By Value vs By Reference

There are two fundamental mechanisms for passing data into a subroutine:

1. Passing by Value (ByVal)

When an argument is passed by value, a duplicate copy of the data is made and sent to the subroutine. The subroutine works only with this copy.

• If the subroutine modifies the value inside itself, the original variable in the main program remains completely unchanged.
Everyday Analogy: Imagine you make a photocopy of your homework notes and hand it to a friend. If your friend doodles on their photocopy, your original sheet at home stays clean and untouched.

2. Passing by Reference (ByRef)

When an argument is passed by reference, the computer passes the actual memory address (a pointer) of the original variable, not a copy.

• Any change made to the variable inside the subroutine directly alters the original variable in the main program!
Everyday Analogy: Imagine you share a live link to an editable Google Doc with a friend. If they delete a paragraph or add text, the original document is changed for you as well.

When should each be used?
• Use ByVal when you want to protect your original data from accidental changes.
• Use ByRef when you want the subroutine to update the original data directly, or when passing huge data sets (like a large array) where making a duplicate copy would waste too much computer memory.

Key Takeaway: ByVal passes a safe temporary copy (original is protected). ByRef passes the memory address (original variable can be modified).


4. Scope of Variables: Local vs Global

The scope of a variable defines the parts of a program where that variable can be seen, recognized, and accessed.

Global Variables

A global variable is declared at the very top level of a program, outside of any subroutine. It can be accessed and altered by any module or function anywhere in the program for the entire time the software is running.

Disadvantages of Global Variables:
Unintended Side Effects: A change made in one subroutine might accidentally break another part of the program.
Difficult Debugging: It is very hard to trace which subroutine caused a bug if every subroutine has access to the variable.
Memory Usage: Global variables remain stored in memory from the moment the program starts until it ends.

Local Variables

A local variable is declared inside a specific subroutine. It is created when the subroutine starts running and is automatically destroyed as soon as the subroutine finishes.

Advantages of Local Variables:
Data Protection (Encapsulation): It cannot be accidentally altered by other subroutines.
Memory Efficiency: Memory space is only used while that specific subroutine is executing.
Reuse of Names: You can use the variable name count inside five different procedures without any clash or interference.

Did you know? Good software engineering practice says you should minimize global variables as much as possible and rely on local variables and parameter passing instead!

Key Takeaway: Global variables are accessible everywhere but carry risk. Local variables are private to their own subroutine, making programs safer and more reliable.


5. The Fundamental Control Structures

In structured programming, any program—no matter how simple or complex—can be constructed using just three fundamental control structures:

1. Sequence

Instructions are executed in exact chronological order, one line after the other, from top to bottom, without jumping or skipping.

2. Selection

The program makes a decision based on a condition (Boolean logic: True or False) to determine which branch of code to follow.
IF... THEN... ELSE: Evaluates a condition and takes one of two paths.
CASE / SELECT: Chooses one path from multiple possible options (e.g., selecting option 1, 2, 3, or 4 from a menu).

3. Iteration (Repetition / Loops)

A block of code is repeated multiple times until a specific condition is met.
Definite (Count-Controlled) Iteration: The number of repeats is known in advance (e.g., a FOR loop running \(10\) times).
Indefinite (Condition-Controlled) Iteration: The loop repeats until a condition changes. This includes WHILE... DO (pre-condition: checks before running) and DO... WHILE / REPEAT... UNTIL (post-condition: runs at least once before checking).

Key Takeaway: Sequence (step-by-step), Selection (decision making), and Iteration (looping) are the three pillars of structured program logic.


6. Summary & Quick Revision Checklist

Before heading into your exam or assignment, make sure you can answer these questions with confidence:

Can you explain top-down design and how it leads to modular programming?
Can you list at least three advantages of using subroutines in a team environment?
Can you explain the main difference between a procedure and a function?
Do you know what happens to the original variable when passed ByVal versus ByRef?
Can you contrast local and global variables and explain why local variables are preferred?
Can you name the three basic control structures (Sequence, Selection, Iteration)?

Common Mistake to Avoid: In exam questions, never say "a procedure does not do calculations". Procedures can do calculations; the key difference is that a procedure does not return a single value back to the calling expression like a function does!