Arrays · Lesson 16 of 35
Arrays in C
Storing the marks of 60 students in 60 separate variables would be absurd. An array stores many values of the same type under one name, side by side in memory, and lets you reach each by its position. Arrays are the most used data structure in C – and the basis of strings, matrices and most algorithms.
In this lesson
- Declaring, initialising and indexing arrays
- How arrays sit in memory
- Common operations: sum, maximum, reverse
- Passing arrays to functions, and out-of-bounds access
Declaring and using an array
#include <stdio.h>
int main(void) {
int marks[5] = {78, 91, 64, 85, 70}; // 5 ints, indexes 0 to 4
marks[2] = 68; // change the third element
printf("first = %d, last = %d\n", marks[0], marks[4]);
for (int i = 0; i < 5; i++) {
printf("marks[%d] = %d\n", i, marks[i]);
}
int zeros[6] = {0}; // all six elements set to 0
int primes[] = {2, 3, 5, 7, 11}; // size worked out from the list: 5
int n = sizeof primes / sizeof primes[0];
printf("zeros[5] = %d, primes has %d elements\n", zeros[5], n);
return 0;
}
first = 78, last = 70 marks[0] = 78 marks[1] = 91 marks[2] = 68 marks[3] = 85 marks[4] = 70 zeros[5] = 0, primes has 5 elements
int marks[5] in memory: consecutive 4-byte slots
- 78[0] · address 1000
- 91[1] · 1004
- 68[2] · 1008
- 85[3] · 1012
- 70[4] · 1016
Indexes start at 0, so an array of size n has indexes 0 to n − 1. Because elements are consecutive, the address of marks[i] is simply start + i × sizeof(int) – that's why indexing is instant, whatever the size.
Common array operations
#include <stdio.h>
int main(void) {
int a[] = {34, 72, 15, 90, 48, 63};
int n = sizeof a / sizeof a[0];
int sum = 0, max = a[0], min = a[0], max_pos = 0;
for (int i = 0; i < n; i++) {
sum += a[i];
if (a[i] > max) { max = a[i]; max_pos = i; }
if (a[i] < min) min = a[i];
}
printf("sum=%d avg=%.2f max=%d (at index %d) min=%d\n", sum, (double)sum / n, max, max_pos, min);
for (int i = 0, j = n - 1; i < j; i++, j--) { // reverse in place
int t = a[i]; a[i] = a[j]; a[j] = t;
}
printf("reversed:");
for (int i = 0; i < n; i++) printf(" %d", a[i]);
printf("\n");
return 0;
}
sum=322 avg=53.67 max=90 (at index 3) min=15 reversed: 63 48 90 15 72 34
Common mistake: starting max at 0
Initialising max = 0 fails when every element is negative. Start with the first element, max = a[0], as above.
Passing arrays to functions
An array passed to a function isn't copied: the function receives the address of the first element. So the function can modify the caller's array – and it doesn't know the length, so you must pass it too:
#include <stdio.h>
void print_array(const int a[], int n) { // const: promises not to modify
for (int i = 0; i < n; i++) printf("%d ", a[i]);
printf("\n");
}
void add_bonus(int a[], int n, int bonus) { // modifies the caller's array
for (int i = 0; i < n; i++) a[i] += bonus;
}
int count_above(const int a[], int n, int limit) {
int count = 0;
for (int i = 0; i < n; i++) if (a[i] > limit) count++;
return count;
}
int main(void) {
int marks[] = {38, 72, 55, 91, 40};
int n = sizeof marks / sizeof marks[0];
print_array(marks, n);
add_bonus(marks, n, 5);
print_array(marks, n);
printf("%d students above 50\n", count_above(marks, n, 50));
return 0;
}
38 72 55 91 40 43 77 60 96 45 3 students above 50
Why sizeof doesn't work inside the function
Inside print_array, the parameter a is really a pointer, so sizeof a gives the size of a pointer (8 bytes), not the array. Compute the length where the array is declared and pass it as a parameter.
Out-of-bounds access
C doesn't check indexes. Reading or writing marks[5] in a 5-element array touches whatever memory comes next – a silent bug that can corrupt other variables or crash the program. It's also behind many real security vulnerabilities (buffer overflows). The sanitizer flags it immediately:
gcc -fsanitize=address -g program.c -o program # AddressSanitizer reports out-of-bounds reads and writes
Always loop with i < n, never i <= n.
Practice
Try it yourself
Find the second largest element in
{12, 45, 7, 45, 30}(it should be 30, since 45 appears twice).Show solution
#include <stdio.h> #include <limits.h> int main(void) { int a[] = {12, 45, 7, 45, 30}; int n = sizeof a / sizeof a[0]; int first = INT_MIN, second = INT_MIN; for (int i = 0; i < n; i++) { if (a[i] > first) { second = first; first = a[i]; } else if (a[i] > second && a[i] != first) second = a[i]; } printf("largest=%d second=%d\n", first, second); return 0; }largest=45 second=30
Count how many times each value 0–4 appears in an array (a frequency table).
Show solution
#include <stdio.h> int main(void) { int data[] = {1, 3, 0, 1, 4, 1, 3, 2}; int freq[5] = {0}; for (int i = 0; i < 8; i++) freq[data[i]]++; for (int v = 0; v < 5; v++) printf("%d appears %d time(s)\n", v, freq[v]); return 0; }0 appears 1 time(s) 1 appears 3 time(s) 2 appears 1 time(s) 3 appears 2 time(s) 4 appears 1 time(s)
Quick check
What are the valid indexes of int a[10]?
0 to 9.
What does int a[5] = {1, 2}; contain?
1, 2, 0, 0, 0 – missing elements are set to 0.
Does C check array bounds?
No – out-of-bounds access is undefined behaviour.
Summary
- Arrays hold same-type values in consecutive memory, indexed from 0.
- Get the length with
sizeof a / sizeof a[0]where the array is declared. - Functions receive the array's address – pass the length too; never index past n − 1.
Finished this lesson?
Mark it complete to track your progress, then carry on with the next lesson.