INSIGHTS
Software Development

Arrays in C Language: Detailed Overview of Types and Functionalities

In this article
  1. Declare an array and read its elements
  2. Never read or write past the end
  3. Arrays become pointers in function parameters
  4. Two-dimensional arrays have a layout
  5. Strings are character arrays with an end marker
  6. When a pointer is not an array
  7. Test boundary cases

Arrays in C hold a fixed number of elements of one type in contiguous storage. They are efficient for indexed access, but C does not automatically prevent access beyond their bounds. A useful arrays tutorial therefore explains how indexes, array length, pointer decay and function parameters interact—rather than listing array types without showing them in code.

Declare an array and read its elements

An initializer supplies the values in order. Index zero is the first element, not index one. When an array is in scope, sizeof arr / sizeof arr[0] computes the element count for a normal array object.

#include <stdio.h>
int main(void) {
    int scores[] = {10, 15, 20};
    size_t n = sizeof scores / sizeof scores[0];
    for (size_t i = 0; i < n; i++)
        printf("%zu: %d\n", i, scores[i]);
    return 0;
}

Never read or write past the end

The last valid index of a three-element array is two. Accessing scores[3] is not a checked exception; it is undefined behavior. Validate each externally supplied index and ensure a loop uses i < n rather than i <= n. This is especially important when an index is derived from user input or file data.

Arrays become pointers in function parameters

A declaration such as int values[] in a function parameter means the callee receives a pointer, not a complete array object with its length. Pass the count explicitly and avoid applying the array-size sizeof trick inside that function.

#include <stddef.h>
int sum_values(const int *values, size_t count) {
    int total = 0;
    for (size_t i = 0; i < count; i++) total += values[i];
    return total;
}

The caller must supply a pointer to at least count elements and the sum must stay within the valid range for int. Those are part of the function’s contract.

Two-dimensional arrays have a layout

An array of arrays can represent a fixed grid. The rightmost dimension is needed when declaring a compatible function parameter in standard C. Row-major storage means adjacent columns within a row are contiguous.

int grid[2][3] = {{1, 2, 3}, {4, 5, 6}};
printf("%d\n", grid[1][2]); /* 6 */

These statements belong in a function with stdio.h included. For a dynamically sized grid, consider one allocated block plus explicit row and column calculations instead of assuming a pointer-to-pointer is equivalent to a two-dimensional array.

Strings are character arrays with an end marker

A C string is a sequence of characters terminated by . A five-character word requires space for six bytes including that terminator. Use bounded operations when reading or copying; a buffer without a terminator cannot safely be passed to a routine expecting a C string.

When a pointer is not an array

A pointer can point to an array’s first element, but sizeof pointer returns the pointer object size, not the array length. Once the array has been passed through a parameter or assigned to a pointer, keep the length alongside the pointer. That simple discipline prevents entire classes of incorrect-size loops.

Test boundary cases

Try a single-element array, zero iterations, an invalid index and a function receiving a count of zero. Check that every array operation respects ownership and lifetime. In code that must grow dynamically, an allocated buffer with carefully tracked capacity may be more appropriate than an automatic fixed array.

Filed under Software Development