Targeted Study Plan
Based on every lecture, worksheet, and your practice test, here's exactly what to focus on and in what order. The test has a very clear pattern β same 7 question types every time.
The 4 Exam Skills
Q1β2 Β· Arrays + Random Numbers
Declare array, init to 0, store random number in a specific index. Formula is always the same β 3+3 marks every test.
Q3β5 Β· Functions
Prototype, full definition (with input loop), and function call. Always void returning. 3+6+2 = 11 marks.
Q6 Β· Sorting
Manual pass-by-pass sort trace. Test 1 = Bubble, Test 2 = Insertion. Must show each pass. 9 marks.
Q7 Β· Pointer Table
Fill in a table tracking variable/pointer values step-by-step. Must know &, *, NULL. 10 marks.
Study This Sequence
STEP 1 β Nail the Formula Patterns (30 min)
Arrays + random number formula. These are free marks β same pattern every test. Click "Arrays" tab.
STEP 2 β Function Writing (45 min)
Practice writing prototype β definition β call from scratch. Know all 4 types. Click "Functions" tab.
STEP 3 β Sorting Traces (45 min)
Do bubble sort AND insertion sort manually on paper. Don't just read β do it yourself. Click "Sorting" tab.
STEP 4 β Pointer Table Method (60 min)
This is the hardest topic but worth 10 marks. Learn the step-by-step method. Click "Pointers" tab.
STEP 5 β Do both practice tests cold (60 min)
Cover answers, try from scratch, then check. Click "Test Answers" tab.
STEP 6 β Worksheet questions (extra prep)
Worksheet 4, 5, 6, 8 cover everything deeper. Good for lab/practical. Click "Worksheet Answers" tab.
Skip For Now
Based on the test format, these topics are lab/practical only β they likely won't appear in the 36-mark written test:
Recursion Β· Binary Search code Β· 2D array manipulation Β· Dynamic memory allocation Β· Function pointers Β· Pointer arithmetic Β· String functions. Learn these for practicals but don't let them distract from the 4 core test skills above.
Functions β Complete Reference
Prototype β Call β Definition
Every function in C has exactly these three parts. You must know where each goes and what it looks like.
/* 1. PROTOTYPE β goes BEFORE main(), ends with ; */
int ADD(int, int);
int main() {
/* 2. FUNCTION CALL β goes inside main */
int result = ADD(10, 20);
printf("%d", result);
return 0;
}
/* 3. DEFINITION β goes AFTER main, no semicolon */
int ADD(int num1, int num2) {
return num1 + num2;
}
All Function Variations
Type 1 β No return, No parameters (void/void)
void PrintMsg(); // prototype
PrintMsg(); // call
void PrintMsg() { // definition
printf("Hello UTech\n");
}
Type 2 β No return, Has parameters (void/params)
void PrintSum(int, int); // prototype
PrintSum(10, 20); // call
void PrintSum(int a, int b) {
printf("%d\n", a + b);
}
Type 3 β Has return, No parameters (int/void)
int GetValue();
int x = GetValue();
int GetValue() {
return 42;
}
Type 4 β Has return, Has parameters (the most common)
int ADD(int, int);
int result = ADD(10, 20);
int ADD(int num1, int num2) {
return num1 + num2;
}
The Test's Q3/Q4/Q5 Template
This exact structure appears in EVERY practice test. Memorize it:
/* Q3: Prototype */
void FunctionName(int[], int);
/* Q4: Full Definition */
void FunctionName(int ARR[], int SIZE) {
for (int i = 0; i < SIZE; i++) {
printf("Enter value %d: ", i + 1);
scanf("%d", &ARR[i]);
}
}
/* Q5: Call in main */
FunctionName(ARR, 10);
Scope β Local vs Global
Local Variables
Declared inside a function. Only visible in that function. Must be passed as arguments to be used elsewhere.
Global Variables
Declared above main(). Accessible by all functions. Exist for the lifetime of the program.
int globalVar = 100; // global β any function can use
void myFunc() {
int localVar = 5; // local β only visible here
{
int blockVar = 3; // block scope β only in these braces
}
// blockVar is GONE here
}
Recursion
A function that calls itself. Every recursive function needs a base case (stops it) and a recursive case (calls itself with smaller input).
// Count down to 1
int fun(int n) {
if (n == 1) return 1; // BASE CASE
else return 1 + fun(n - 1); // RECURSIVE CASE
}
// fun(3) β 1 + fun(2) β 1 + 1 + fun(1) β 1+1+1 = 3
Arrays β 1D and 2D
Declaration, Initialization, Access
// Declare with size, uninitialized (GARBAGE values β danger!)
int scores[10];
// Declare + initialize ALL to zero (exam answer for Q1)
int scores[10] = {0};
// Declare with explicit values
int scores[5] = {25, 16, 89, 62, 12};
// Size inferred from initializer
int numbers[] = {1, 2, 3, 4, 5}; // size = 5
// Access: ALWAYS 0-indexed
scores[0] // 1st element
scores[6] // 7th element β EXAM TRAP
scores[9] // 10th (last) element of size-10 array
[6], 2nd element = [1]. This trips everyone.Loop Through Array
for (int i = 0; i < SIZE; i++) {
scanf("%d", &arr[i]); // fill from user
printf("%d ", arr[i]); // print
}
Random Numbers
// Generate number from LOW to HIGH inclusive:
variable = rand() % (high - low + 1) + low;
// Required headers:
#include <stdlib.h>
#include <time.h>
// Seed (put in main once, before any rand() call):
srand(time(NULL));
Both test examples worked out
// -12 to 35: range = 35-(-12)+1 = 48, shift = -12
VALUES[6] = rand() % 48 + (-12);
// -30 to 15: range = 15-(-30)+1 = 46, shift = -30
BUFFER[1] = rand() % 46 + (-30);
Worksheet 4 examples
// 2 to 12: range=11, shift=2
printf("%d", 2 + rand() % 11);
// -5 to 5: range=11, shift=-5
printf("%d", -5 + rand() % 11);
// 10 to 25 (Worksheet 5 lab): range=16, shift=10
arr[i] = rand() % 16 + 10;
Array Calculations
A[5]=7, A[1]=5, A[2]=2. Order of operations: multiplication first. β 7 + (5 Γ 2) = 7 + 10 = 17
grid[0][0]=1, grid[2][2]=9, grid[1][1]=5, grid[1][2]=6 β (1+9)Γ5β6 = 50β6 = 44
2D Arrays
// Declaration: [rows][columns]
int grid[3][4];
// Initialize with braces-per-row
int b[2][2] = {{1,2}, {3,4}};
// Access: [row][col]
grid[1][2] = 25; // row 1, column 2
// Nested loop to traverse
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 4; col++) {
total += grid[row][col];
}
}
// Pass 2D to function: MUST specify column size
void printMatrix(int matrix[][3], int rows);
// β column size is mandatory!
arr[3] is at 1000 + (3 Γ 4) = 1012Sorting Algorithms
The test asks you to do a manual trace β no code needed for Q6. You must show the array state after EVERY pass.
How Bubble Sort Works
Compare each adjacent pair from left to right. Swap if left > right. After each full sweep, the largest unsorted element has "bubbled" to the end. Repeat, but each pass covers one fewer element.
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
Test 1 trace: 14, 3, 22, 11, 6, 19, 2, 9, -4, 7
How Insertion Sort Works
Pick element at position i. Slide it left, shifting larger elements right, until it lands in the correct spot in the already-sorted left portion. Like sorting cards in your hand.
void insertionSort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}
Test 2 trace: 18, 5, 12, 1, 20, 7, 4, 16, -2, 9
How Selection Sort Works
Find the minimum element in the unsorted portion, swap it to the front of the unsorted section. Repeat.
void selectionSort(int arr[], int n) {
for (int i = 0; i < n-1; i++) {
int minIdx = i;
for (int j = i+1; j < n; j++) {
if (arr[j] < arr[minIdx]) minIdx = j;
}
if (minIdx != i) {
int temp = arr[i]; arr[i] = arr[minIdx]; arr[minIdx] = temp;
}
}
}
WS6 Q2 trace: 9, 20, 7, 18, 8, 41, 35, 6, 3, 13
Searching Algorithms
Check Every Element One By One
Works on any array (sorted or unsorted). Go through each element until you find the target. Return its index, or -1 if not found.
int linearSearch(int arr[], int size, int key) {
for (int i = 0; i < size; i++) {
if (arr[i] == key) {
return i; // found! return index
}
}
return -1; // not found
}
Pros
Simple. Works on unsorted arrays. Good for small data.
Cons
Slow on large arrays. Checks every element in the worst case.
Eliminate Half the Array Each Step
Array must be sorted first. Check the middle element. If target is smaller, search left half. If larger, search right half.
int binarySearch(int arr[], int size, int key) {
int start = 0, end = size - 1;
while (start <= end) {
int mid = (start + end) / 2;
if (arr[mid] == key) return mid;
else if (key < arr[mid]) end = mid - 1;
else start = mid + 1;
}
return -1;
}
Pros
Extremely fast β 1 million elements needs only ~20 steps. Scalable.
Cons
Array MUST be sorted first. Overkill for small arrays.
Pointers β Master The 10-Mark Question
What A Pointer Actually Is
A pointer is a variable that stores a memory address, not a regular value. It "points to" where another variable lives in memory.
int x = 5; // normal variable, value=5, lives at some address
int *ptr = NULL; // pointer to int, currently points nowhere
ptr = &x; // &x = "address of x" β ptr now holds x's address
printf("%d", *ptr); // *ptr = "value at ptr's address" = 5
*ptr = 10; // changes x to 10 via the pointer
ptr = NULL; // ptr points nowhere again. x is still 10.
& β "address of"
&x gives you the memory address where x lives. Put this INTO a pointer.
* β "dereference / value at"
*ptr gives you the value stored at ptr's address. Use to read OR write.
How To Solve Pointer Tables in 3 Steps
Step 1 β Write out the address table first
Before doing anything, write: "u is at 52012, v is at 52016, w is at 52020". This is your reference map.
Step 2 β Execute statements one at a time, left to right
For EACH statement: (a) identify what the pointer currently points to, (b) compute the new value, (c) update your table immediately before moving to the next statement.
Step 3 β Pointer cell shows an ADDRESS, not a value
When ptrA = &u, the value in the ptrA cell is 52012 (the address), not 6 (the value of u). Many students write 6 β that's wrong.
u=6, v=4, w=3, ptrA=NULL, ptrB=NULL
Addresses: u=52012, v=52016, w=52020
| Statements | u | v | w | ptrA | ptrB |
|---|---|---|---|---|---|
| Initial state | 6 | 4 | 3 | NULL | NULL |
| ptrA = &u; ptrB = &w; | 6 | 4 | 3 | 52012 | 52020 |
| v = *ptrA + v; *ptrB = *ptrB + 2; | 6 | 10 | 5 | 52012 | 52020 |
| u = *ptrB - 1; v++; | 4 | 11 | 5 | 52012 | 52020 |
| ptrA = &v; ptrB = ptrA; | 4 | 11 | 5 | 52016 | 52016 |
| *ptrB = *ptrB * 2; ptrA = NULL; | 4 | 22 | 5 | NULL | 52016 |
Explanation of each row
Row 1: ptrA = &u β stores u's address (52012). ptrB = &w β stores w's address (52020).
Row 2: *ptrA = u = 6. v = 6 + 4 = 10. *ptrB = w = 3. w = 3 + 2 = 5.
Row 3: *ptrB = w = 5. u = 5 β 1 = 4. v++ β v = 10 + 1 = 11.
Row 4: ptrA = &v β 52016. ptrB = ptrA β also 52016. Both point to v now.
Row 5: *ptrB = v = 11. v = 11 Γ 2 = 22. ptrA = NULL (v stays 22).
x=2, y=5, z=4, *left=NULL, *right=NULL
Addresses: x=63012, y=63016, z=63020
| Statements | x | y | z | left | right |
|---|---|---|---|---|---|
| Initial state | 2 | 5 | 4 | NULL | NULL |
| left = &y; right = &z; | 2 | 5 | 4 | 63016 | 63020 |
| x = *left + z; *right = *right - 1; | 9 | 5 | 3 | 63016 | 63020 |
| y = *left * 2; z++; | 9 | 10 | 4 | 63016 | 63020 |
| left = &x; right = left; | 9 | 10 | 4 | 63012 | 63012 |
| *right = *right + y; left = NULL; | 19 | 10 | 4 | NULL | 63012 |
Explanation of each row
Row 1: left = &y β 63016. right = &z β 63020.
Row 2: *left = y = 5. x = 5 + z = 5 + 4 = 9. *right = z = 4. z = 4 β 1 = 3.
Row 3: *left = y = 5. y = 5 Γ 2 = 10. z++ β z = 3 + 1 = 4.
Row 4: left = &x β 63012. right = left β 63012. Both point to x.
Row 5: *right = x = 9. y = 10. x = 9 + 10 = 19. left = NULL.
Pointer β Array Notation (WS8 Q2 & Q3)
// Array notation β pointer notation are equivalent
arr[i] == *(arr + i) // accessing element
&arr[i] == arr + i // getting address
// WS8 Q2: Replace * with []
*(tax + 4) == tax[4]
*(score + 2) == score[2]
*(number+10) == number[10]
*prices == prices[0] // no offset = index 0
// WS8 Q3: Replace [] with *
tax[6] == *(tax + 6)
score[7] == *(score + 7)
num[4] == *(num + 4)
prices[9]== *(prices + 9)
WS8 Q1 β Pointer to pointer
int x;
int* p = &x;
int ***pp = &p; // pointer to pointer to pointer
// To access x's value: **pp (answer: e)
// *pp gives p (the address of x)
// **pp dereferences twice = x's value
Both Tests β Complete Answers
Click any question to reveal the answer and explanation.
TEST 1 β November 2025
int VALUES[10] = {0};Marks for: correct type int (1), correct name VALUES (1), zero-initialization (1).
VALUES[6] = rand() % 48 + (-12);Range = 35β(β12)+1 = 48. 7th element = index 6. Marks: correct index (1), correct range calc (1), correct formula structure (1).
void CaptureValues(int[], int);Must have: void return (1), correct name (1), correct parameter types (1), semicolon.
void CaptureValues(int VALUES[], int LENGTH) {
for (int i = 0; i < LENGTH; i++) {
printf("Enter value %d: ", i + 1);
scanf("%d", &VALUES[i]);
}
}6 marks for: correct header (1), loop from 0 to LENGTH (2), scanf with &VALUES[i] (2), void/no return (1).
CaptureValues(VALUES, 10);~1 mark per pass. Show the full array state after each pass.
See the full worked table in the Pointers tab β "Test 1 Worked Solution".
Final answers: After all statements: u=4, v=22, w=5, ptrA=NULL, ptrB=52016
TEST 2 β December 2025
int BUFFER[10] = {0};BUFFER[1] = rand() % 46 + (-30);Range = 15β(β30)+1 = 46. 2nd element = index 1.
void ReadNumbers(int[], int);void ReadNumbers(int BUFFER[], int COUNT) {
for (int i = 0; i < COUNT; i++) {
printf("Enter value %d: ", i + 1);
scanf("%d", &BUFFER[i]);
}
}ReadNumbers(BUFFER, 10);See the full worked table in the Pointers tab β "Test 2 Worked Solution".
Final answers: After all statements: x=19, y=10, z=4, left=NULL, right=63012
Key Worksheet Answers
The tutorial questions that are most likely to appear in modified form on your actual test.
Q1: Write Prototypes for Each
// a. StartProgram β no args, no return
void StartProgram(void);
// b. InputValue β no args, returns float
float InputValue(void);
// c. OutputValue β int arg, no return
void OutputValue(int);
// d. CalculateTotal β three ints, returns float
float CalculateTotal(int, int, int);
// e. DetermineStatus β float arg, returns char
char DetermineStatus(float);
Q2: Function Calls for Each
StartProgram();
float val = InputValue();
OutputValue(42);
float total = CalculateTotal(1, 2, 3);
char status = DetermineStatus(3.14f);
Tutorial Q1βQ5 Answers
An array is a collection of variables of the same data type stored in contiguous memory locations, all sharing one name and accessed by an index number.
1000 + (3 Γ 4) = 1012
0 to 99
6 elements β size is inferred from the initializer list.
1 β arr[0]=3, arr[1]=2, arr[2]=1
WS6 Q2: Manual Sort Traces
Array: 9, 20, 7, 18, 8, 41, 35, 6, 3, 13
Insertion Sort
Bubble Sort
Selection Sort
88,30,500,70,150,40,8,450,55,150 β Descending
For descending, flip the comparison: swap when left < right (bubble/insertion) or find max instead of min (selection).
Insertion Sort (descending) β after 3 turns:
Pass 1: 88, 30, 500, 70, 150, 40, 8, 450, 55, 150 (no change, 30<88)
Pass 2: 500, 88, 30, 70, 150, 40, 8, 450, 55, 150
Pass 3: 500, 88, 70, 30, 150, 40, 8, 450, 55, 150
After 5 turns:
Pass 4: 500, 150, 88, 70, 30, 40, 8, 450, 55, 150
Pass 5: 500, 150, 88, 70, 40, 30, 8, 450, 55, 150
Q1 Answer: **pp
Given int x; int* p = &x; int ***pp = &p; β to access x's value: **pp (double dereference). Answer is e.
Linear vs Binary (WS6 Q1 β Define)
Linear search: Checks each element one by one from start to end. Simple, works on unsorted arrays, but slow for large datasets O(n).
Binary search: Repeatedly divides the sorted array in half, comparing the target to the middle element. Much faster β O(log n) β but requires a sorted array first.
Everything On One Page
Array + Zero Init
int ARRAY[10] = {0};
// nth element = index n-1
ARRAY[6]; // 7th element
Random Number
rand() % (hi-lo+1) + lo;
// -12 to 35:
rand() % 48 + (-12);
// -30 to 15:
rand() % 46 + (-30);
The Exam Function Template
void Name(int[], int); // prototype
void Name(int ARR[], int SIZE) { // definition
for(int i=0; i<SIZE; i++)
scanf("%d", &ARR[i]);
}
Name(ARR, 10); // call in main
Key Rules
ptr = &x; // ptr = x's address
*ptr // value at ptr
*ptr = 5; // change x via ptr
ptr = NULL; // ptr β nowhere
One Line Each
Bubble: Swap adjacent pairs that are wrong. Largest bubbles to end each pass.
Insertion: Pick element, slide it left to its correct position in sorted portion.
Selection: Find minimum in unsorted, swap to front.
Never Make These Mistakes
array[6] not array[7]. Always nβ1.