C Arrays
An array in C is a fixed-size sequence of values stored under one name. Arrays matter because many programs work with groups of related data: scores, sensor readings, prices, character buffers, IDs, and more. Instead of creating one variable per value, you create one array and use an index to choose which element you want.
C arrays are powerful, but they are also low-level. The language gives you direct access to contiguous memory and expects you to stay inside the valid indexes yourself.
Overview: How C Arrays Work
An array contains elements, and every element in one array has the same type. If you write int scores[4];, C reserves enough storage for four int objects placed next to each other in memory. If an int is 4 bytes on your system, the array uses 16 bytes for its elements.
Array indexes start at 0. For an array of length 4, the valid indexes are 0, 1, 2, and 3. The expression scores[2] means: start at the beginning of scores, move forward two elements, and access the object stored there. This is why arrays are fast: indexing is a simple address calculation.
A C array has a fixed length after it is created. You cannot append to it, resize it, or assign a whole new array into it with = after declaration. For flexible collections, later lessons use dynamic memory and pointers. For this lesson, focus on the essential rule: choose a size, keep track of that size, and only access indexes from 0 through size - 1.
There is another important detail: in many expressions, an array name is converted to a pointer to its first element. That is why arrays are often passed to functions together with a separate length. The function can access the elements, but it does not automatically know how many there are.
Syntax
type name[size];
type name[size] = {value1, value2, value3};
type name[] = {value1, value2, value3};
name[index] = new_value;
value = name[index];
| Part | Meaning |
|---|---|
type |
The element type, such as int, double, or char. |
name |
The array variable name. |
size |
The number of elements. It must be large enough for all values you plan to store. |
{...} |
An initializer list. If the size is omitted, C counts the initializer values. |
index |
The zero-based position of one element. |
If you partially initialize an array, C fills the remaining elements with zero values. For example, int flags[5] = {1, 1}; produces 1, 1, 0, 0, 0. Local arrays that are not initialized contain indeterminate values, so read them only after assigning valid data.
Examples
Access And Update Elements
#include <stdio.h>
int main(void)
{
int scores[4] = {90, 85, 78, 92};
printf("First score: %d
", scores[0]);
printf("Last score: %d
", scores[3]);
scores[2] = 80;
printf("Updated third score: %d
", scores[2]);
return 0;
}
Output:
First score: 90
Last score: 92
Updated third score: 80
The array has four elements, but the first index is 0, not 1. The assignment scores[2] = 80; changes the third element only; the other elements keep their original values.
Loop Through An Array
#include <stdio.h>
int main(void)
{
int temperatures[] = {72, 75, 71, 69, 74};
size_t count = sizeof temperatures / sizeof temperatures[0];
for (size_t i = 0; i < count; i++) {
printf("Day %zu: %d
", i + 1, temperatures[i]);
}
return 0;
}
Output:
Day 1: 72
Day 2: 75
Day 3: 71
Day 4: 69
Day 5: 74
When the size is omitted, C counts the initializer values. The sizeof expression calculates the number of elements while the array is still in scope: total bytes in the array divided by bytes in one element.
Calculate From Array Data
#include <stdio.h>
int main(void)
{
double prices[] = {19.99, 5.50, 12.25, 8.00};
size_t count = sizeof prices / sizeof prices[0];
double total = 0.0;
double highest = prices[0];
for (size_t i = 0; i < count; i++) {
total += prices[i];
if (prices[i] > highest) {
highest = prices[i];
}
}
printf("Items: %zu
", count);
printf("Total: $%.2f
", total);
printf("Highest: $%.2f
", highest);
return 0;
}
Output:
Items: 4
Total: $45.74
Highest: $19.99
This example uses an array as a small data set. The loop visits each price once, adds it to total, and updates highest when it finds a larger value.
Pass An Array To A Function
#include <stdio.h>
void print_int_array(const int values[], size_t count)
{
for (size_t i = 0; i < count; i++) {
printf("%d", values[i]);
if (i + 1 < count) {
printf(", ");
}
}
printf("
");
}
int main(void)
{
int ids[] = {104, 205, 309};
size_t count = sizeof ids / sizeof ids[0];
print_int_array(ids, count);
return 0;
}
Output:
104, 205, 309
The parameter const int values[] means the function receives access to the caller’s array elements and promises not to modify them. The separate count parameter is necessary because the function cannot reliably calculate the original array length from values.
How It Works Step By Step
- The declaration reserves storage for a fixed number of same-type elements.
- An initializer list writes starting values into that storage, in order.
- An indexed expression such as
a[i]computes the address of elementibased on the element size. - The program reads or writes the object at that computed address.
- A loop repeats the same indexed operation for each valid index.
C does not insert automatic bounds checks for ordinary array access. If you write past the end, the program has undefined behavior: it may appear to work, overwrite another variable, crash, or fail later in a confusing place.
Common Mistakes
Using One-Based Indexes
The first element is items[0]. For int items[3], items[3] is not the third element; it is one past the end. Use loop conditions such as i < count, not i <= count.
Reading Uninitialized Elements
A local declaration like int numbers[5]; does not automatically fill the array with zeros. Assign values before reading them, or initialize the array with int numbers[5] = {0}; when you want all elements to start at zero.
Calculating Length After Passing To A Function
sizeof values / sizeof values[0] works in the same scope as the actual array object. Inside a function parameter, values behaves like a pointer, so that formula no longer gives the element count. Pass the count explicitly.
Trying To Assign Arrays
After declaration, a = b; is not valid for arrays. Copy elements one at a time with a loop, or use library functions such as memcpy when you understand the size and type requirements.
Best Practices
- Keep the element count in a variable such as
countwhen you loop more than once. - Use
size_tfor array indexes and element counts because it is the standard unsigned type for object sizes. - Prefer
sizeof array / sizeof array[0]when the array is still in the same scope. - Use named constants or calculated counts instead of repeating magic numbers.
- Initialize local arrays before reading from them.
- Pass arrays to functions with a length parameter.
- Use
constin function parameters when the function should read but not modify array elements. - Be careful with user-provided indexes; validate them before accessing the array.
Practice Exercises
- Create an array of five integers, print each element, then print their sum.
- Create a
doublearray of weekly temperatures and print the average with one digit after the decimal point. - Write a function
find_maxthat receives anintarray and a count, then returns the largest value.
Summary
- A C array stores a fixed number of same-type elements in contiguous memory.
- Indexes start at
0, so the last valid index iscount - 1. - Array access is fast because C computes an element address directly.
- C does not protect you from out-of-bounds indexes.
- Use loops, calculated counts, initialization, and explicit length parameters to work with arrays safely.
