Arrays in C: Declaration, Initialization and Worked Examples

Learn how C arrays behave through exact contents, safe loop bounds, function calls and two-dimensional traversal. A complete program traces sum, average and maximum.

KnowledgeGate Team

Exam prep & CS education

Updated 21 Jul 20266 min read

A declaration such as int marks[5] looks simple, but zero-based indexes, fixed bounds, initialization, traversal and function parameters cause most early mistakes. Almost every array bug a beginner writes reduces to one of four questions: which indexes are valid, what an initializer leaves in the cells it does not name, what a function actually receives, and how a two-dimensional array sits in memory. Each has an exact answer, and the answers are worth holding as numbers rather than as rules of thumb. If you are building a wider programming foundation, Coding & DSA Courses for Placements places C alongside the next problem-solving skills.

Arrays in C: what they store and why indexes start at zero

An array stores a contiguous sequence of elements of one type. Instead of declaring five unrelated variables, write:

int marks[5] = {72, 81, 69, 90, 78};

The name marks identifies five elements: marks[0] = 72, marks[1] = 81, marks[2] = 69, marks[3] = 90 and marks[4] = 78. Indexing starts at zero, so length 5 gives valid indexes 0 through 4. Zero is the starting point because an index is an offset, not a position number: marks[i] names the element exactly i elements past the base address of the block, so marks[0] is the base address itself. Counting from one would put a subtraction into every single element access.

marks[5] is outside the array, and accessing it has undefined behaviour. A loop changes one index to process all five marks; separate variables need five statements.

Declaring and initializing one-dimensional C arrays

In int marks[5];, int is the element type, marks is the name and 5 is the count. An automatic local array starts with indeterminate elements, so initialize them before reading.

These common initialization forms produce different but predictable contents:

int marks[5] = {72, 81, 69, 90, 78}; // [72, 81, 69, 90, 78]
int zeros[5] = {0};                  // [0, 0, 0, 0, 0]
int partial[5] = {4, 9};             // [4, 9, 0, 0, 0]
int primes[] = {2, 3, 5, 7, 11};     // inferred length: 5

Where the real array object is visible, size_t count = sizeof marks / sizeof marks[0]; gives 5. Do not use this as a general solution in a function parameter, where an array parameter is adjusted to a pointer.

Five contiguous memory cells for int marks[5] = {72, 81, 69, 90, 78}, with indexes 0 to 4 above the cells, the values 72, 81, 69, 90 and 78 inside them, and illustrative addresses 1000, 1004, 1008, 1012 and 1016 below, on the stated assumption that int occupies 4 bytes in this example.

These addresses are illustrative, not portable. The example assumes a four-byte int only to show contiguous placement.

Reading, updating and traversing an array with loops

With int marks[5] = {72, 81, 69, 90, 78};, marks[2] is 69. After marks[2] = 74;, the array is [72, 81, 74, 90, 78].

A forward traversal is:

for (size_t i = 0; i < count; i++)
    printf("%d ", marks[i]);

It prints 72 81 74 90 78. Use i < count, not i <= count, because count is not a valid index. Reverse safely with:

for (size_t i = count; i > 0; i--)
    printf("%d ", marks[i - 1]);

This prints 78 90 74 81 72. Here i - 1 moves from index 4 to 0, and the loop stops before unsigned size_t goes below zero. Repeated comparisons and swaps lead naturally to Sorting Algorithms: Complexity and Comparison.

Worked C array program: sum, average and maximum

This runnable program derives the length and updates the sum and maximum in one loop:

#include <stdio.h>

int main(void) {
    int scores[] = {18, 24, 15, 27, 21, 30};
    size_t n = sizeof scores / sizeof scores[0];
    int sum = 0;
    int max = scores[0];
    size_t max_index = 0;

    for (size_t i = 0; i < n; i++) {
        sum += scores[i];
        if (scores[i] > max) {
            max = scores[i];
            max_index = i;
        }
    }

    double average = (double) sum / n;
    printf("sum=%d, average=%.2f, max=%d, max_index=%zu\n",
           sum, average, max, max_index);
    return 0;
}

The loop develops as follows:

Index

scores[index]

Running sum

Current max

Max index

0

18

18

18

0

1

24

42

24

1

2

15

57

24

1

3

27

84

27

3

4

21

105

27

3

5

30

135

30

5

A six-step trace table for scores = {18, 24, 15, 27, 21, 30} with columns index, scores[index], running sum, current max, and max index; rows show (0,18,18,18,0), (1,24,42,24,1), (2,15,57,24,1), (3,27,84,27,3), (4,21,105,27,3), and (5,30,135,30,5), followed by average = 135 / 6 = 22.50.

The arithmetic is 18 + 24 + 15 + 27 + 21 + 30 = 135, then 135 / 6 = 22.5. Output is sum=135, average=22.50, max=30, max_index=5. The strict > comparison retains the first occurrence of a tied maximum.

Passing arrays to C functions without losing the length

Pass the element count with the array:

int sum_array(const int values[], size_t n) {
    int total = 0;
    for (size_t i = 0; i < n; i++)
        total += values[i];
    return total;
}

const promises that the function will not modify elements through values. At the caller:

int readings[] = {12, 15, 9, 14};
size_t n = sizeof readings / sizeof readings[0];
int total = sum_array(readings, n);

The total moves 0 -> 12 -> 27 -> 36 -> 50, so sum_array(readings, 4) returns 50. In a parameter, int values[] becomes int *values, so the length is not received automatically. sizeof values / sizeof values[0] would use the pointer size, not the caller's element count. Pass n explicitly.

Two-dimensional arrays in C: rows, columns and nested loops

int sales[2][3] = {{5, 7, 9}, {6, 8, 10}}; creates two rows and three columns. Here sales[0][1] is 7, while sales[1][2] is 10.

Nested loops keep each bound clear:

int grand_total = 0;
for (size_t row = 0; row < 2; row++) {
    int row_sum = 0;
    for (size_t col = 0; col < 3; col++)
        row_sum += sales[row][col];
    grand_total += row_sum;
}

Row 0 totals 5 + 7 + 9 = 21, row 1 totals 6 + 8 + 10 = 24, and the grand total is 45. Row-major order is 5, 7, 9, 6, 8, 10: row 0 precedes row 1 in memory.

Common C array errors and three exercises with answer checks

Most array bugs come from these causes:

Error

Consequence

Fix

for (i = 0; i <= 5; i++) for five elements

Reaches invalid index 5

Use i < 5

Read int data[3]; before assignment

Uses indeterminate values

Initialize before reading

Use a = b; for two arrays

Whole-array assignment is not permitted

Copy elements in a loop or use a suitable library routine

Use scanf("%d", values[i])

Omits the element's address

Validate the index, then use scanf("%d", &values[i]) and check its result

int a[3] = {1, 2, 3, 4}; requires a diagnostic because four values cannot fit three elements. In contrast, int a[3] = {1, 2}; is valid and zero-fills the remainder.

Three C array exercises with answer checks

Written papers and lab vivas keep returning to the same three abilities: naming the valid index range, predicting what an initializer leaves behind, and stating what a function receives. Work all three on paper first, then check the answer line under the list.

  1. Reverse {3, 8, 1, 6, 4} in place.

  2. For {10, 20, 30, 40}, compute the average and count how many elements exceed it.

  3. For {{2, 1, 0}, {4, 3, 5}, {7, 8, 6}}, sum the main diagonal.

Answers: {4, 6, 1, 8, 3}; average 25.0 with 2 elements above it (30 and 40); and 2 + 3 + 6 = 11.

For the same ground in question form, Array Basics MCQs in C: 11 Solved Questions with Explanations works through solved items one at a time. Arrays also support bounded push, pop, enqueue and dequeue operations; Stacks and Queues: Operations and Uses shows why index checks matter.

Arrays in C: the short version and next practice

Keep five rules in view:

  1. Declare the correct element count.

  2. Initialize elements before reading them.

  3. Keep every index between 0 and n - 1.

  4. Derive the length only where the real array object is visible.

  5. Pass the length explicitly into functions.

The scores total 135, average 22.50, and have maximum 30 at index 5; the 2 x 3 sales array totals 45. For the complete language sequence and more practice, continue with C Language Course: Concepts, MCQs and Coding.

As a final check, change scores[2] from 15 to 33. Predict the new total 153, average 25.50, maximum 33, and maximum index 2, then rerun the program and verify each value.

Discussion