Introduction, Data Structures & Arrays
This chapter builds the first foundations of the course: what data and information are, why we organise data with data structures, and a close look at the simplest linear data structure, the array, including how array elements are addressed in memory for both 1D and 2D arrays. (Course logistics — syllabus, textbook, assessment, and timetable — are on the home page.)
1.2Data and Information
1.3Organising Information: Field, Record, File
Information is organised hierarchically:
| Level | Meaning | Example |
|---|---|---|
| Field | A single element of information | Age |
| Record | A collection of field values | An employee of a company (name, age, dept.) |
| File | A collection of records | All the employees of a company |
1.4What is a Data Structure?
Files can be very large, and we need to perform many operations on them efficiently:
- Insertion
- Deletion
- Updation
- Searching
- Viewing (traversing)
- Queries such as finding the employee with the maximum salary
- Many more…
Doing these efficiently requires organising the data in computer memory in a deliberate way — that organisation is the data structure.
Where does a data structure live?
In this definition, computer memory normally means
main memory (RAM) while a program is running. For example, when
Python executes A = [10, 20, 30, 40], the list and
the information needed to manage it exist in the program's memory, backed
primarily by RAM.
SSD / HDD
Stores data persistently, even when the program or computer is off.
101 Alice
102 Bob
103 John
RAM · running program
The program organises the records into a useful runtime structure.
students.txt file stays on the SSD/HDD.Classification
| Category | Examples |
|---|---|
| Sequential | Array |
| Non-sequential | Linked lists |
| Hierarchical | Trees, Heaps |
| Graphical | Graphs |
1.5Why Data Structures Matter
The choice of data structure decides how fast each operation can be. The same four operations cost very differently across structures:
| Operation | Insert | Search | Find Min | Delete Min |
|---|---|---|---|---|
| Unsorted array | O(1) | O(n) | O(n) | O(n) |
| Sorted array | O(n) | O(log n) | O(1) | O(n) |
| Linked list | O(1) | O(n) | O(n) | O(n) |
| Min heap | O(log n) | O(n) | O(1) | O(log n) |
No single structure wins everywhere — each trades speed in one operation for speed in another, which is why we study many of them.
1.6Arrays
The array is the simplest linear data structure. It is:
- Stored in a contiguous block of memory,
- Made of elements of the same data type, and
- Supports random access — any element can be reached directly by its index.
int arr[5] = {10, 20, 30, 40, 50};
Ready to place the five integers in contiguous memory.
1.7Array Indexing (Offset or Position)
For int arr[5] = {10, 20, 30, 40, 50}; there are two indexing conventions:
0-based indexing — most common in programming languages
| Value | 10 | 20 | 30 | 40 | 50 |
| Index | 0 | 1 | 2 | 3 | 4 |
1-based indexing — used only in theory
| Value | 10 | 20 | 30 | 40 | 50 |
| Index | 1 | 2 | 3 | 4 | 5 |
1.8Array Operations
Traversal — iterating through elements
for (int i = 0; i < n; i++) {
printf("%d ", A[i]);
}
Insertion — adding an element at a specific index
A[index] = 5;
Deletion — removing an element at a specific index (requires shifting)
for (int i = index; i < n - 1; i++) {
A[i] = A[i + 1];
}
n--;
Before: [10, 20, 30, 40, 50] n = 5 Shift right from the end: A[5] = A[4] → [10, 20, 30, 40, 50, 50] A[4] = A[3] → [10, 20, 30, 40, 40, 50] A[3] = A[2] → [10, 20, 30, 30, 40, 50] Place: A[2] = 25 →[10, 20, 25, 30, 40, 50] n = 6
Inserting in the middle needs every element from the index onward shifted right — here 3 shifts. Inserting at the front of an n-element array costs n shifts; inserting at the end costs none.
Before: [10, 20, 30, 40, 50] n = 5 A[1] = A[2] → [10, 30, 30, 40, 50] A[2] = A[3] → [10, 30, 40, 40, 50] A[3] = A[4] → [10, 30, 40, 50, 50] Shrink: n-- → [10, 30, 40, 50] n = 4
Deletion closes the gap by shifting everything after the index one place left; the last slot becomes stale and n shrinks. Like insertion, the cost depends on the position — worst at the front, free at the end.
Search — finding an element
Linear search or binary search (binary search needs the array to be sorted).
Update — modifying an element
Assign a new value at the given index, e.g. A[index] = new_value;
1.9Strengths and Limitations
| Strengths | Limitations |
|---|---|
| Fast access to elements via index | Fixed size — resizing requires creating a new array |
| Easy to implement and use | Costly insertions and deletions (due to shifting) |
1.10Array Addressing
Because arrays are contiguous, the memory address of any element can be computed directly from its index.
Base_address + data_size × i
Base_address + data_size × (i − 1)
An int array (4 bytes each) starts at base address 2000. What is the address of arr[7]?
show answer
Address = 2000 + 4 × 7 = 2028.
A char array (1 byte each) starts at base address 500. What is the address of arr[9]?
show answer
Address = 500 + 1 × (9 − 1) = 508. Note the (i − 1): in 1-based indexing the first element sits at the base address itself.
#include <stdio.h>
int main(void) {
int arr[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++) {
printf("&arr[%d] = %p\n", i, (void *)&arr[i]);
}
return 0;
}
Ready to compile and run.
&arr[i] for an int array shows consecutive addresses exactly 4 bytes apart, confirming the contiguous layout behind the addressing formula.1.112-Dimensional (2D) Arrays
A 2D array is an array of arrays, representing data in rows
and columns (matrix format). Elements are accessed using two indices —
a row index and a column index, e.g. A[i][j].
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
1.122D Arrays: Memory Representation
Memory is one-dimensional, so a 3 × 4 matrix must be flattened into a line. Two conventions exist:
| Order | Idea | Layout of the 3 × 4 example |
|---|---|---|
| Row-major | Elements of a row are stored sequentially | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 |
| Column-major | Elements of a column are stored sequentially | 1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12 |
1.132D Array Addressing (0-based)
Example: for the 3 × 4 array above, the element
arr[i=2][j=2] in row-major order sits at
Base_address + ((2 × 4) + 2) × size.
1.14Worked Question
A character array A[1…10][1…15] is stored in computer memory
following row-major order. The base address of the array is 100.
What is the address of the element A[i][j]?
show answer
Solution: the array has 15 columns and indices start at 1, so Address = 100 + ((i − 1) × 15 + (j − 1)) × 1 = 100 + 15i − 15 + j − 1 = 15i + j + 84 (a char takes 1 byte, so the data size is 1).
An int array A[0…9][0…14] (10 rows × 15 columns) is stored in
column-major order with base address 5000. What is the address of
A[3][5]?
show answer
Column-major: Address = 5000 + ((j × Rows) + i) × 4 = 5000 + ((5 × 10) + 3) × 4 = 5000 + 53 × 4 = 5212. Verify it yourself in the explorer above by switching the order to column-major.
- For the same array
A[1…10][1…15]of chars (base 100), derive the address formula in column-major order and simplify it like the worked question. - An int array
B[0…7][0…7]starts at base 4000. Find the address ofB[6][2]in both row-major and column-major order — and explain why only the diagonal elements get the same address in both. - If a 1D char array’s element
arr[12](0-based) lives at address 712, what is the base address?
1.15Observations: Why "Same Data Type"?
Section 1.6 said an array holds elements of the same data type. What actually happens if we cheat? Two experiments from the lecture:
Experiment 1 — a char and a float in an int array
int arr[5] = {1, 2, 3, 'A', 5.5};
printf("arr[3] is %d, and arr[4] is %d \n", arr[3], arr[4]);
printf("Char in arr[3] is %c", arr[3]);
#include <stdio.h>
int main(void) {
int arr[5] = {1, 2, 3, 'A', 5.5};
printf("arr[3] as int = %d\n", arr[3]);
printf("arr[3] as char = %c\n", arr[3]);
printf("arr[4] = %d\n", arr[4]);
return 0;
}
Ready to compile and run.
Experiment 2 — a string in an int array
int arr[5] = {1, 2, 3, "hello", 5.5}; // ERROR?!
#include <stdio.h>
int main(void) {
int arr[5] = {1, 2, 3, "hello", 5.5};
printf("%d\n", arr[3]);
return 0;
}
Ready to compile.
char * pointer, and turning a pointer into an int is rejected ("makes integer from pointer without a cast"). Same-type storage is enforced, not just recommended.