liveBook · Manning

Indexing

As explained in Modern C, Third Edition

Array indexing is the C operation of selecting an array element with an index expression, such as A[i].

Consider `double A[5] = { [0] = 9.0, [1] = 2.9, [4] = 3.E+25, [3] = .00007 };`. An expression such as `A[4]` selects an element; here it has the value `3.E+25`. Indices measure positions from the start, so a five-element array has indices 0 through 4. The bracketed numbers inside the initializer have a different job: they designate elements to initialize. The omitted element, `A[2]`, is initialized to zero. section 2.3 section 2.2

The same notation connects array access to pointer operations:

  • `A[i]` and `*(A+i)` are equivalent whether `A` is an array or a pointer. When an array is evaluated where a value is needed, it decays to a pointer to its first element. Indexing a pointer does not create an array object or supply its length. section 11.3.1 section 11.1.2
  • In a function declaration, an array parameter is rewritten as a pointer parameter. Put length parameters before array parameters when a declaration uses those lengths; a pointer alone cannot reveal the array’s length. section 11.3.2 section 11.1.2
  • Keep access within the relevant array object. Pointer arithmetic can itself be invalid when it exceeds array bounds; an expression such as `a+len` can mark the position just beyond an array, but it is not an element to read. Prefer `A[i]` over `*(A+i)` when expressing an element access: compilers may more readily detect an invalid index. section 15.1.1 section 11.1.2
void matrix_mult(size_t n, size_t k, size_t m,
                 double       C[n][m],
                 double const A[n][k],
                 double const B[k][m]) {
   for (size_t i = 0; i < n; ++i) {
     for (size_t j = 0; j < m; ++j) {
       C[i][j] = 0.0;
       for (size_t l = 0; l < k; ++l) {
         C[i][j] += A[i][l]*B[l][j];
       }
     }
   }
}

In matrix multiplication, `C[i][j]`, `A[i][l]`, and `B[l][j]` select elements by two indices. The declared dimensions and loop limits show how each access is intended to stay within its matrix. section 11.3.2

TAKEAWAY: Use indexing to name the element you intend to access, but do not mistake readable syntax for a bounds check. When passing an array to a function, pass the length information the function needs. section 15.1.1 section 11.1.2

How Modern C, Third Edition covers it

How deep it goes
Defines zero-based positions, derives indexing from pointer addition and dereferencing, then addresses parameter rewriting and bounds constraints.
Examples
Uses a five-element designated initializer, pointer-based summation, and indexed matrix multiplication.
What it assumes
Builds on array declarations and element positions while introducing pointer equivalence and decay explicitly.
What you can do after
Evaluate/understand it by translating `A[i]` to `*(A+i)` and checking that accesses respect array bounds.
How it connects
Connects indexing to designated initializers, array-to-pointer decay, pointer arithmetic, array parameters, and variable-length arrays.

Also explained in

Compare how 15 books explain indexing →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.