Arrays in C
Store multiple values of the same type together! Learn 1D arrays (lists), 2D arrays (tables), and how arrays are stored in memory.
Track Your Progress
Sign in to save your learning progress
What You Will Learn
- ✓Create and initialize arrays
- ✓Access elements using index (arr[0])
- ✓Loop through arrays
- ✓Work with 2D arrays (rows and columns)
01What is an Array?
An array is a collection of elements of the same data type stored in contiguous (adjacent) memory locations. Think of it like a row of boxes, where each box can hold one value and has a number (index) to identify it.
Why Use Arrays?
Without Arrays
int score1 = 85;int score2 = 90;int score3 = 78;int score4 = 92;int score5 = 88;// Tedious with 100 students!With Arrays ✓
int scores[5] = {85, 90, 78, 92, 88};// One variable for all 5 scores!// Easy to loop throughKey Array Facts
- • All elements must be the same type (all int, all float, etc.)
- • Array size is fixed once declared (cannot grow or shrink)
- • Index starts at 0, not 1 (first element is array[0])
- • Elements are stored in contiguous memory
Why Does Indexing Start at 0?
This confuses many beginners! Here's the real reason:
The index is actually an OFFSET from the start.
- •
arr[0]→ 0 steps from start → first element - •
arr[1]→ 1 step from start → second element - •
arr[2]→ 2 steps from start → third element
Memory formula: address = base_address + (index × element_size)
If index started at 1, we'd need to subtract 1 every time — wasteful!
Array Memory Layout Visualized
When you create int scores[5] = {85, 90, 78, 92, 88}, here's what happens in memory:
0x1000
85
[0]
0x1004
90
[1]
0x1008
78
[2]
0x100C
92
[3]
0x1010
88
[4]
Each int is 4 bytes, so addresses increase by 4. They're right next to each other (contiguous)!
02One-Dimensional (1D) Arrays
A 1D array is the simplest form — a single row of elements. Like a list of items.
Declaration Syntax
This snippet shows the basic syntax for declaring arrays of different data types.
1// Syntax: dataType arrayName[size];23int numbers[5]; // Array of 5 integers4float prices[10]; // Array of 10 floats5char letters[26]; // Array of 26 charactersInitialization Methods
▶ Try it: Demonstrates 5 different ways to create and fill arrays with values.
1#include <stdio.h>23int main() {4 // Method 1: Initialize at declaration5 int scores[5] = {85, 90, 78, 92, 88};6 7 // Method 2: Partial initialization (remaining = 0)8 int values[5] = {10, 20}; // {10, 20, 0, 0, 0}9 10 // Method 3: All zeros11 int zeros[5] = {0}; // {0, 0, 0, 0, 0}12 13 // Method 4: Let compiler count size14 int auto_size[] = {1, 2, 3, 4}; // Size = 415 16 // Method 5: Initialize after declaration17 int grades[3];18 grades[0] = 95;19 grades[1] = 87;20 grades[2] = 91;21 22 // Accessing elements23 printf("First score: %d\n", scores[0]); // 8524 printf("Last score: %d\n", scores[4]); // 8825 26 // Calculate size27 int size = sizeof(scores) / sizeof(scores[0]);28 printf("Array size: %d\n", size); // 529 30 return 0;31}How This Program Works
int scores[5] = {85, 90, 78, 92, 88} — Creates an array of 5 integers and fills them with values at once.
int values[5] = {10, 20} — Only first 2 values given; remaining 3 are automatically set to 0.
int auto_size[] = {1, 2, 3, 4} — Compiler counts elements and sets size = 4 automatically.
scores[0] accesses the first element (85), scores[4] accesses the last (88).
sizeof(scores) / sizeof(scores[0]) — Calculates array size: total bytes ÷ bytes per element = number of elements.
Memory Layout of 1D Array
When you create int arr[5], the computer allocates 5 × 4 = 20 bytes of contiguous memory (assuming int is 4 bytes).
Memory Layout: int arr[5] = {10, 20, 30, 40, 50}
arr[0]
arr[1]
arr[2]
arr[3]
arr[4]
1000
1004
1008
1012
1016
Memory addresses (each int = 4 bytes)
Memory Size Calculation
Total memory = number_of_elements × size_of_each_element
For int arr[5]: 5 × 4 bytes = 20 bytes
Address Calculation in 1D Arrays
The CPU uses a simple formula to find any element's memory address. This is why arrays allow O(1) constant-time access — no matter which index you access!
# The Address Formula
Address of arr[i] = Base Address + (i × size_of_element)
Base Address
Starting memory location of arr[0]
i (Index)
Position of element (0, 1, 2...)
size_of_element
Bytes per element (int=4, char=1)
Example: int arr[5] with Base Address = 1000
| Index (i) | Calculation | Address | Value |
|---|---|---|---|
| 0 | 1000 + (0 × 4) | 1000 | 10 |
| 1 | 1000 + (1 × 4) | 1004 | 20 |
| 2 | 1000 + (2 × 4) | 1008 | 30 |
| 3 | 1000 + (3 × 4) | 1012 | 40 |
| 4 | 1000 + (4 × 4) | 1016 | 50 |
▶ Try it: Prints the memory address of each array element and shows how the formula calculates them.
1#include <stdio.h>23int main() {4 int arr[5] = {10, 20, 30, 40, 50};5 6 // Base address (address of first element)7 printf("Base Address (arr or &arr[0]): %p\n", (void*)arr);8 9 // Calculate and verify addresses10 for (int i = 0; i < 5; i++) {11 // Manual calculation12 // Address = Base + (i × sizeof(int))13 printf("arr[%d]: Address = %p, ", i, (void*)&arr[i]);14 printf("Calculated = Base + (%d × %zu) = %p\n", 15 i, sizeof(int), (void*)(arr + i));16 }17 18 // Pointer arithmetic does this automatically!19 // arr + i is same as &arr[i]20 printf("\narr + 2 = %p (same as &arr[2])\n", (void*)(arr + 2));21 22 return 0;23}Why This Matters
Because of this formula, accessing arr[0] or arr[999999]takes the same time! The CPU just does one multiplication and one addition — instant O(1) access.
Looping Through Arrays
▶ Try it: Uses a for loop to print all elements with their addresses, then calculates sum and average.
1#include <stdio.h>23int main() {4 int numbers[5] = {10, 20, 30, 40, 50};5 int size = sizeof(numbers) / sizeof(numbers[0]);6 7 // Base address of array8 printf("Base Address: %p\n\n", (void*)numbers);9 10 // Print all elements with their addresses11 printf("Array elements with addresses:\n");12 printf("-----------------------------------------------\n");13 printf("Index | Value | Address | Address Calculation\n");14 printf("-----------------------------------------------\n");15 for (int i = 0; i < size; i++) {16 printf(" %d | %2d | %p | Base + (%d × %zu)\n", 17 i, numbers[i], (void*)&numbers[i], i, sizeof(int));18 }19 printf("-----------------------------------------------\n");20 21 // Calculate sum22 int sum = 0;23 for (int i = 0; i < size; i++) {24 sum += numbers[i];25 }26 printf("\nSum: %d\n", sum);27 printf("Average: %.2f\n", (float)sum / size);28 29 return 0;30}$ ./array_loop
Base Address: 0x7ffd5c3e1a00
Array elements with addresses:
-----------------------------------------------
Index | Value | Address | Calculation
-----------------------------------------------
0 | 10 | 0x7ffd5c3e1a00 | Base + (0 × 4)
1 | 20 | 0x7ffd5c3e1a04 | Base + (1 × 4)
2 | 30 | 0x7ffd5c3e1a08 | Base + (2 × 4)
3 | 40 | 0x7ffd5c3e1a0c | Base + (3 × 4)
4 | 50 | 0x7ffd5c3e1a10 | Base + (4 × 4)
-----------------------------------------------
Sum: 150
Average: 30.00
How This Loop Works Step-by-Step
sizeof(numbers) / sizeof(numbers[0]) calculates size: 20 bytes ÷ 4 bytes = 5 elements.
for (int i = 0; i < size; i++) — Loop runs 5 times: i = 0, 1, 2, 3, 4. Stops when i becomes 5.
numbers[i] — Each iteration accesses a different element: numbers[0]=10, numbers[1]=20, etc.
sum += numbers[i] — Adds each element to sum: 0+10+20+30+40+50 = 150.
(float)sum / size — Casts sum to float for decimal division: 150.0 ÷ 5 = 30.00.
03Two-Dimensional (2D) Arrays
A 2D array is like a table with rows and columns. Think of it as a grid, spreadsheet, or a matrix.
Real-World Examples of 2D Arrays
Spreadsheet
Rows × Columns of data
Image Pixels
Width × Height grid
Chess Board
8 × 8 squares
Declaration & Initialization
▶ Try it: Shows 3 ways to create 2D arrays and how to access elements using [row][column] notation.
1#include <stdio.h>23int main() {4 // Syntax: dataType name[rows][columns];5 6 // Method 1: Full initialization7 int matrix[3][4] = {8 {1, 2, 3, 4}, // Row 09 {5, 6, 7, 8}, // Row 110 {9, 10, 11, 12} // Row 211 };12 13 // Method 2: Linear initialization (fills row by row)14 int grid[2][3] = {1, 2, 3, 4, 5, 6};15 // Same as: {{1,2,3}, {4,5,6}}16 17 // Method 3: Partial initialization18 int partial[2][3] = {{1, 2}, {4}};19 // Result: {{1,2,0}, {4,0,0}}20 21 // Accessing elements: array[row][column]22 printf("matrix[0][0] = %d\n", matrix[0][0]); // 123 printf("matrix[1][2] = %d\n", matrix[1][2]); // 724 printf("matrix[2][3] = %d\n", matrix[2][3]); // 1225 26 return 0;27}Memory Layout of 2D Array
Even though we think of 2D arrays as tables, they're stored in memory as one continuous block (row-major order). Row 0 comes first, then Row 1, etc.
int matrix[2][3] — Logical View vs Memory View
Logical View (How We Think)
| Col 0 | Col 1 | Col 2 | |
|---|---|---|---|
| Row 0 | 1 | 2 | 3 |
| Row 1 | 4 | 5 | 6 |
Memory View (How It's Actually Stored)
[0][0]
[0][1]
[0][2]
[1][0]
[1][1]
[1][2]
Contiguous memory: Row 0 → Row 1 (row-major order)
2D Array Memory Calculation
Total memory = rows × columns × size_of_element
For int matrix[3][4]: 3 × 4 × 4 bytes = 48 bytes
Address Calculation in 2D Arrays
For 2D arrays, the formula must account for row-major order — complete rows are stored one after another. To find any element, we first "skip" complete rows, then move within that row.
# Row-Major Order Formula
Address of arr[i][j] = Base + ((i × COLS) + j) × size
Base
Address of arr[0][0]
i × COLS
Skip i complete rows
+ j
Move j columns in row
× size
Bytes per element
Example: int matrix[3][4] with Base = 2000
Each row has 4 columns (COLS = 4)
| Element | Formula | Calculation | Address |
|---|---|---|---|
| arr[0][0] | 2000 + ((0×4)+0)×4 | 2000 + 0 | 2000 |
| arr[0][2] | 2000 + ((0×4)+2)×4 | 2000 + 8 | 2008 |
| arr[1][0] | 2000 + ((1×4)+0)×4 | 2000 + 16 | 2016 |
| arr[1][3] | 2000 + ((1×4)+3)×4 | 2000 + 28 | 2028 |
| arr[2][1] | 2000 + ((2×4)+1)×4 | 2000 + 36 | 2036 |
▶ Try it: Calculates the address of matrix[1][2] using the row-major formula, then verifies it matches the actual address.
1#include <stdio.h>23int main() {4 int matrix[3][4] = {5 {1, 2, 3, 4},6 {5, 6, 7, 8},7 {9, 10, 11, 12}8 };9 10 int rows = 3, cols = 4;11 int *base = &matrix[0][0]; // Base address12 13 printf("Base Address: %p\n\n", (void*)base);14 15 // Calculate address for matrix[1][2]16 int i = 1, j = 2;17 18 // Formula: Base + ((i × COLS) + j) × sizeof(element)19 int offset = (i * cols) + j; // Linear position: 1×4 + 2 = 620 int *calculated_addr = base + offset;21 22 printf("Finding matrix[%d][%d]:\n", i, j);23 printf(" Step 1: Skip %d complete rows = %d × %d = %d elements\n", 24 i, i, cols, i * cols);25 printf(" Step 2: Move %d columns in current row\n", j);26 printf(" Step 3: Total offset = %d elements = %d bytes\n", 27 offset, offset * (int)sizeof(int));28 printf(" Calculated Address: %p\n", (void*)calculated_addr);29 printf(" Actual Address (&matrix[%d][%d]): %p\n", i, j, (void*)&matrix[i][j]);30 printf(" Value: %d\n", *calculated_addr);31 32 return 0;33}Think of it Like This
To reach arr[2][1] in a 3×4 matrix:
Step 1: Skip 2 complete rows = 2 × 4 = 8 elements
Step 2: Move 1 column into row 2 = 1 element
Total: 8 + 1 = 9 elements from base = 9 × 4 = 36 bytes
Looping Through 2D Arrays
▶ Try it: Uses nested loops to print the matrix as a table, show address calculations, and calculate the total sum.
1#include <stdio.h>23int main() {4 int matrix[3][4] = {5 {1, 2, 3, 4},6 {5, 6, 7, 8},7 {9, 10, 11, 12}8 };9 10 int rows = 3;11 int cols = 4;12 int *base = &matrix[0][0];13 14 printf("Base Address: %p\n\n", (void*)base);15 16 // Print as table17 printf("Matrix:\n");18 for (int i = 0; i < rows; i++) {19 for (int j = 0; j < cols; j++) {20 printf("%3d ", matrix[i][j]);21 }22 printf("\n");23 }24 25 // Show address calculation for each element26 printf("\nAddress Calculation (Row-Major Order):\n");27 printf("----------------------------------------------------------\n");28 printf("Element | Value | Offset Calculation | Address\n");29 printf("----------------------------------------------------------\n");30 for (int i = 0; i < rows; i++) {31 for (int j = 0; j < cols; j++) {32 int offset = (i * cols) + j;33 printf("matrix[%d][%d] | %2d | (%d×%d)+%d = %2d elements | %p\n",34 i, j, matrix[i][j], i, cols, j, offset, (void*)&matrix[i][j]);35 }36 }37 printf("----------------------------------------------------------\n");38 39 // Calculate sum40 int sum = 0;41 for (int i = 0; i < rows; i++) {42 for (int j = 0; j < cols; j++) {43 sum += matrix[i][j];44 }45 }46 printf("\nSum of all elements: %d\n", sum);47 48 return 0;49}$ ./2d_array_loop
Base Address: 0x7ffd5c3e1a20
Matrix:
1 2 3 4
5 6 7 8
9 10 11 12
Address Calculation (Row-Major Order):
----------------------------------------------------------
Element | Value | Offset Calculation | Address
----------------------------------------------------------
matrix[0][0] | 1 | (0×4)+0 = 0 elements | 0x7ffd...1a20
matrix[0][1] | 2 | (0×4)+1 = 1 elements | 0x7ffd...1a24
matrix[0][2] | 3 | (0×4)+2 = 2 elements | 0x7ffd...1a28
matrix[1][0] | 5 | (1×4)+0 = 4 elements | 0x7ffd...1a30
matrix[1][2] | 7 | (1×4)+2 = 6 elements | 0x7ffd...1a38
...
----------------------------------------------------------
Sum of all elements: 78
04Three-Dimensional (3D) Arrays
A 3D array adds another dimension — think of it as multiple 2D tables stacked together. It has layers, rows, and columns.
Real-World Examples of 3D Arrays
Multiple Spreadsheets
Sheets × Rows × Columns
Video Frames
Frames × Height × Width
Building Floors
Floors × Rows × Rooms
Declaration & Initialization
▶ Try it: Creates a 3D array (2×3×4) and shows how to access elements using [layer][row][column] notation.
1#include <stdio.h>23int main() {4 // Syntax: dataType name[layers][rows][columns];5 6 // 3D Array: 2 layers, each with 3 rows and 4 columns7 int cube[2][3][4] = {8 // Layer 0 (first 2D table)9 {10 {1, 2, 3, 4},11 {5, 6, 7, 8},12 {9, 10, 11, 12}13 },14 // Layer 1 (second 2D table)15 {16 {13, 14, 15, 16},17 {17, 18, 19, 20},18 {21, 22, 23, 24}19 }20 };21 22 // Accessing elements: array[layer][row][column]23 printf("cube[0][0][0] = %d\n", cube[0][0][0]); // 124 printf("cube[0][2][3] = %d\n", cube[0][2][3]); // 1225 printf("cube[1][1][2] = %d\n", cube[1][1][2]); // 1926 27 return 0;28}Memory Layout of 3D Array
3D arrays are also stored in contiguous memory. Layer 0 comes first (all its rows), then Layer 1, and so on.
int cube[2][2][3] — Visualization
Layer 0 (cube[0])
| 1 | 2 | 3 |
| 4 | 5 | 6 |
Layer 1 (cube[1])
| 7 | 8 | 9 |
| 10 | 11 | 12 |
In memory: [1,2,3,4,5,6] → [7,8,9,10,11,12] (Layer 0 → Layer 1)
3D Array Memory Calculation
Total memory = layers × rows × columns × size_of_element
For int cube[2][3][4]: 2 × 3 × 4 × 4 bytes = 96 bytes
Address Calculation in 3D Arrays
For 3D arrays, we extend the formula: first skip complete layers, then skip rows within that layer, then move within the row.
# 3D Array Address Formula
Address of arr[i][j][k] = Base + [(i × ROWS × COLS) + (j × COLS) + k] × size
i × ROWS × COLS
Skip i complete layers
j × COLS
Skip j rows in layer
k
Column offset in row
× size
Bytes per element
Example: int cube[2][3][4] with Base = 3000
2 layers × 3 rows × 4 columns
| Element | Calculation | Offset | Address |
|---|---|---|---|
| cube[0][0][0] | (0×3×4)+(0×4)+0 = 0 | 0 × 4 = 0 | 3000 |
| cube[0][1][2] | (0×3×4)+(1×4)+2 = 6 | 6 × 4 = 24 | 3024 |
| cube[1][0][0] | (1×3×4)+(0×4)+0 = 12 | 12 × 4 = 48 | 3048 |
| cube[1][2][3] | (1×3×4)+(2×4)+3 = 23 | 23 × 4 = 92 | 3092 |
▶ Try it: Finds the address of cube[1][2][3] by calculating layer + row + column offsets, then verifies the result.
1#include <stdio.h>23int main() {4 int cube[2][3][4] = {5 {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}},6 {{13,14,15,16}, {17,18,19,20}, {21,22,23,24}}7 };8 9 int layers = 2, rows = 3, cols = 4;10 int *base = &cube[0][0][0];11 12 printf("Base Address: %p\n\n", (void*)base);13 14 // Calculate address for cube[1][2][3]15 int i = 1, j = 2, k = 3;16 17 // Formula: Base + (i×ROWS×COLS + j×COLS + k) × size18 int offset = (i * rows * cols) + (j * cols) + k;19 int *calculated = base + offset;20 21 printf("Finding cube[%d][%d][%d]:\n", i, j, k);22 printf(" Skip %d layers: %d × %d × %d = %d elements\n", 23 i, i, rows, cols, i * rows * cols);24 printf(" Skip %d rows: %d × %d = %d elements\n", 25 j, j, cols, j * cols);26 printf(" Column offset: %d elements\n", k);27 printf(" Total: %d + %d + %d = %d elements = %d bytes\n",28 i * rows * cols, j * cols, k, offset, offset * 4);29 printf(" Address: %p, Value: %d\n", (void*)calculated, *calculated);30 31 return 0;32}Looping Through 3D Arrays
▶ Try it: Uses 3 nested loops to print each layer as a separate table and calculate the total sum of all 24 elements.
1#include <stdio.h>23int main() {4 int cube[2][3][4] = {5 {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}},6 {{13,14,15,16}, {17,18,19,20}, {21,22,23,24}}7 };8 9 int layers = 2, rows = 3, cols = 4;10 11 // Print all layers12 for (int l = 0; l < layers; l++) {13 printf("=== Layer %d ===\n", l);14 for (int r = 0; r < rows; r++) {15 for (int c = 0; c < cols; c++) {16 printf("%3d ", cube[l][r][c]);17 }18 printf("\n");19 }20 printf("\n");21 }22 23 // Calculate total sum24 int sum = 0;25 for (int l = 0; l < layers; l++) {26 for (int r = 0; r < rows; r++) {27 for (int c = 0; c < cols; c++) {28 sum += cube[l][r][c];29 }30 }31 }32 printf("Total sum: %d\n", sum); // 30033 34 return 0;35}05Array Memory Size Summary
| Array Type | Declaration | Elements | Memory (int=4 bytes) |
|---|---|---|---|
| 1D | int arr[5] | 5 | 5 × 4 = 20 bytes |
| 2D | int arr[3][4] | 3 × 4 = 12 | 12 × 4 = 48 bytes |
| 3D | int arr[2][3][4] | 2 × 3 × 4 = 24 | 24 × 4 = 96 bytes |
This simple program uses sizeof() to print the actual memory size of 1D, 2D, and 3D arrays. Run it to verify the calculations!
1#include <stdio.h>23int main() {4 int arr1D[5];5 int arr2D[3][4];6 int arr3D[2][3][4];7 8 printf("Size of int: %zu bytes\n", sizeof(int));9 printf("1D array [5]: %zu bytes\n", sizeof(arr1D));10 printf("2D array [3][4]: %zu bytes\n", sizeof(arr2D));11 printf("3D array [2][3][4]: %zu bytes\n", sizeof(arr3D));12 13 return 0;14}06Common Mistakes
Array Index Out of Bounds
int arr[5] = {1, 2, 3, 4, 5};printf("%d", arr[5]); // ERROR! Valid indices are 0-4printf("%d", arr[-1]); // ERROR! No negative indicesC doesn't check array bounds! Accessing invalid indices causes undefined behavior.
Forgetting Array Indices Start at 0
int scores[5] = {85, 90, 78, 92, 88};// First element is scores[0], NOT scores[1]// Last element is scores[4], NOT scores[5]Using sizeof() Wrong in Functions
void printArray(int arr[]) { // sizeof(arr) returns pointer size, NOT array size! int size = sizeof(arr) / sizeof(arr[0]); // WRONG!}// Solution: Pass size as a parameter!Code Pitfalls: Common Mistakes & What to Watch For
Why beginners get Arrays Wrong!
Arrays are where beginners make its most dangerous mistakes — buffer overflows that can crash programs or create security holes:
1. Off-By-One Buffer Overflow
Beginners often copy loops that access arr[size] instead of stopping at arr[size-1]:
int arr[5];for (int i = 0; i <= 5; i++) { // BUG: i <= 5 arr[i] = i; // arr[5] is OUT OF BOUNDS!}// Correct: i < 52. Wrong sizeof() Usage
Copied code often uses sizeof on arrays passed to functions, which gives pointer size (8 bytes), not array size:
void process(int arr[]) { int n = sizeof(arr) / sizeof(arr[0]); // n = 8/4 = 2, not array length! WRONG!}// Must pass size as separate parameter3. Uninitialized Array Access
Copied code might declare an array and read from it without initializing — C doesn't zero-initialize local arrays!
Golden Rule: For an array of size N, valid indices are 0 to N-1. Always use i < N, never i <= N.
!More Pitfalls: Off-by-One Errors
You may find array code with subtle off-by-one errors that forget C does not automatically initialize local arrays.
If you search online to "loop through an array of 10 elements," it might use for (i = 0; i <= 10; i++) instead of i < 10. This accesses arr[10], which is out of bounds! Similarly, Copied code might read from an uninitialized local array, assuming it contains zeros when it actually contains garbage.
The Trap: Online sources often produce code that looks correct but has fence-post errors. They might also pass arrays to functions without passing the size, then use sizeof() inside the function — which gives the pointer size, not the array size! C's lack of bounds checking means these bugs compile without warnings but cause crashes or security vulnerabilities.
The Reality: For an array of size N, valid indices are 0 to N-1. Always use i < N, never i <= N. Always pass array size as a separate parameter to functions. Initialize arrays explicitly or use = {0} for zero-initialization. Don't trust copied code to handle these C-specific gotchas correctly.
09Frequently Asked Questions
Q:Why do array indices start at 0 instead of 1?
A: The index is actually an offset from the array's starting address. arr[0] means "0 positions from the start."arr[3] means "3 positions from the start." This maps directly to how memory works: arr[i] is equivalent to*(arr + i). Starting at 1 would waste the first element or require extra calculation.
Q:What happens if I access an array out of bounds?
A: Undefined behavior — anything can happen! You might: (1) Get garbage values, (2) Crash with segmentation fault, (3) Corrupt other variables, (4) Create security vulnerabilities. C doesn't check bounds for performance — it trusts you. This is why C is both powerful and dangerous. Always verify your indices!
Q:How do I find the length of an array?
A: Use sizeof(arr) / sizeof(arr[0])— total bytes divided by size of one element. But! This only works where the array was declared. Once passed to a function, the array becomes a pointer andsizeof returns pointer size (8 bytes on 64-bit). Solution: pass the size as a separate parameter.
Q:Can I resize an array after creating it?
A: No! Regular arrays have fixed size. Once int arr[10] is declared, it's always 10 elements. For resizable storage, use dynamic memory allocation:malloc() to create, realloc() to resize, free() to release. We'll cover this in the Dynamic Memory tutorial.
Q:What's the difference between arr and &arr[0]?
A: In most contexts, they're the same — both give the address of the first element. arr "decays" to a pointer. The difference: sizeof(arr) gives total array size, whilesizeof(&arr[0]) gives pointer size. Also,&arr is a pointer to the entire array, not just the first element (affects pointer arithmetic).
Q:How do I pass a 2D array to a function?
A: You must specify all dimensions except the first:void process(int arr[][COLS], int rows). The compiler needs column count to calculate element positions. Alternatively, use a pointer with explicit stride:void process(int *arr, int rows, int cols) and access witharr[i*cols + j].
Q:Are arrays initialized to zero by default?
A: Only global and static arrays!Local arrays contain garbage until you initialize them.int arr[5] = {0} initializes all to 0.int arr[5] = {1, 2} sets first two elements, rest become 0.int arr[5] (no initializer) has garbage in local scope — always initialize!
09Summary
What You Learned:
- ✓WHY: Arrays let us store multiple values of the same type together
- ✓1D Arrays: Single row, accessed with arr[i] (index starts at 0)
- ✓2D Arrays: Table with rows/columns, accessed with arr[row][col]
- ✓Size: Calculate with sizeof(arr) / sizeof(arr[0])
Test Your Knowledge
Related Tutorials
Strings in C
Strings are character arrays ending with \0. Learn to create strings, read them safely, and use string functions like strlen, strcpy, strcmp.
Loops in C
Repeat actions automatically! Master for, while, and do-while loops. Learn which loop to use when, and how to control loops with break and continue.
Structures in C
Group related data together! Create your own data types with struct. Store a student's name, age, and grade in one variable.
Have Feedback?
Found something missing or have ideas to improve this tutorial? Let us know on GitHub!