Structured Programming Style
21.1 Principles
Top-down design: break the problem into steps, each step into SUBs/FUNCTIONs, until each piece is simple.
Single entry, single exit blocks: use IF, SELECT CASE, FOR, DO, and procedures instead of GOTO.
One job per procedure: LoadLevel, DrawBoard, CheckCollision — if you need "and" to describe it, split it.
Local by default: pass parameters and return values; keep DIM SHARED for true program-wide state.
Named constants instead of magic numbers.
Declare everything with OPTION _EXPLICIT.
21.2 Naming and layout conventions
MAX_ENEMIES, SCREEN_W playerX, lives SUBs / FUNCTIONs PascalCase verbs / nouns DrawPlayer, Distance# Enemy, Vec2 isAlive, hasKey 4 spaces per block level
21.3 Refactoring spaghetti code
10 INPUT "N"; N
20 IF N < 0 THEN 10
30 S = 0: I = 1
40 IF I > N THEN 80
50 IF I MOD 3 = 0 OR I MOD 5 = 0 THEN S = S + I
60 I = I + 1
70 GOTO 40
80 PRINT S
90 INPUT "AGAIN (Y/N)"; A$
100 IF A$ = "Y" THEN 10OPTION _EXPLICIT
DIM n AS LONG, again AS STRING
DO
n = ReadNonNegative&("N")
PRINT SumOfMultiples&(n)
INPUT "Again (Y/N)"; again
LOOP WHILE UCASE$(again) = "Y"
END
FUNCTION ReadNonNegative& (prompt AS STRING)
DIM v AS LONG
DO
PRINT prompt;
INPUT v
LOOP WHILE v < 0
ReadNonNegative& = v
END FUNCTION
FUNCTION SumOfMultiples& (limit AS LONG)
DIM i AS LONG, total AS LONG
FOR i = 1 TO limit
IF i MOD 3 = 0 OR i MOD 5 = 0 THEN total = total + i
NEXT
SumOfMultiples& = total
END FUNCTION21.4 When GOTO is acceptable
Modern BASIC rarely needs GOTO. Accepted uses: ON ERROR GOTO handlers (required), and occasionally jumping out of deeply nested loops — though a flag variable or moving the loops into a SUB with EXIT SUB is usually cleaner.
🧪 Part II Exercises
Write FUNCTIONs Celsius!(f!), IsPrime%(n&), and DigitSum%(n&), and a SUB PrintTable that uses them to print a formatted table for n = 1..30.
Demonstrate by-reference vs. by-value passing: write a SUB DoubleIt that doubles its parameter, and call it with DoubleIt x, DoubleIt (x), and CALL DoubleIt((x)).
Write recursive FUNCTIONs for power (Pow#(base#, exp&) using fast exponentiation), sum of digits, and string reversal.
Read an unknown number of integers into a dynamic array with REDIM _PRESERVE (doubling the capacity), then print the mean, median, and mode.
Create a TYPE Student with name, three marks, and average; store 5 students in an array, compute averages, and print a report sorted by average.
Implement Split%, Join$, Trim$, and PadLeft$ string utilities and test them on edge cases (empty strings, delimiters at both ends).
Write a quiz program that loads questions, choices, and answers from DATA statements and reports the score.
Add error handling to a file viewer: handle "File not found", "Path not found", and "Permission denied" with friendly messages.
Build a simple address book that saves contacts to a CSV file with WRITE # and reloads them with INPUT #.
Build a product inventory on a RANDOM-access file: add, view by record number, update stock, and list all records.