Concepts / Declaring and accessing array elements

Declaring and accessing array elements

An array can be initialized by an initializer list, which is a braced list of values written in the declaration.

  • Programming

Starting an Array with Known Contents

When you create an array, you often already know what its contents should be. Instead of declaring an empty container and then assigning each slot one at a time, you can supply the starting values together with the declaration. This technique is called initializing an array with an initializer list.

Before reading further, look at a declaration and work out three things: what the name refers to, how many values the declaration asks for, and where those values come from. The rest of this article answers each of these questions in turn.

cpp

Reading the Parts of a Declaration

The declaration has three parts. The name a1 is the identifier you use to refer to the array later. The type portion array<int, 3> carries two pieces of information: the element type int, and the number 3, which is the number of elements the array is specified to hold. The part after the equals sign, enclosed in braces, is the initializer list, the list of values that fill the array when it is created.

array<int, 3>element type int, declaredsize 3a1name used to refer to thearray{10, 20, 30}initializer listdeclaresis initialized by
Which parts of the declaration line are the element type, the name, the declared size, and the initializer list, and how do they relate?

Read the type portion carefully. The 3 in array<int, 3> is the declared size. It is set by the declaration itself, and the braces that follow are checked against it. The values inside the braces are the supplied values.

Mapping Values to Positions

When an initializer list matches the declared size, each value in the braces occupies one slot of the array. The first value sits in the first position, the second in the second, and so on. Counting from zero, the common convention for C++ arrays, the first value goes to position 0, the second to position 1, and the third to position 2. Later code uses these positions to read or change individual elements.

10index 020index 130index 2
Which value from the braced list lands at index 0, index 1, and index 2, and how does each value's position relate to its index?

Read the diagram from left to right. The value that appears first in the braces is at the lowest index, and the value that appears last is at the highest index. The position number is always one less than the value's place in the list, because counting starts at zero.

The Size Rule for Initializer Lists

Definition

The number of values in an initializer list must be equal to or less than the declared size of the array. Let n be the count of values in the braces and N be the declared size. The rule is written as follows.

Formula

Notice that the rule is a comparison, not an exact match. A count equal to the declared size passes, and a smaller count also passes. Only a count that exceeds the declared size breaks the rule. The initializer may match the declared size exactly, or it may supply fewer values. It may never supply more.

Tracing a Valid and an Invalid Declaration

Compare two declarations that both declare an array of size 3. The first supplies three values, which equals the declared size, so it passes. The second supplies four values, which exceeds the declared size, so it breaks the rule.

cpp
Notes on the code
  • The first declaration's count equals the declared size.
  • The second declaration's count exceeds the declared size, so the violation is on this declaration line.
3 valuesequal to size 3, passes4 valuesexceeds size 3, breaks rule2 valuesfewer than size 3, passes
When the braced list has more values than the declared size, which values have no slot, and on which line is the violation found?

In the invalid line, the fourth value has no slot, because the array has only positions 0, 1, and 2. The source material says that when a declaration violates the counting rule, the problem sits in the declaration line, so that is where to look first.

Common Mistakes with Initializer Counts

  • Common mistake

    Thinking the brace count must match the declared size exactly

    What it looks like
    std::array<int, 3> a = {5, 6};
    Why it fails

    A smaller count passes the rule. Only a count larger than the declared size breaks it.

    Do this instead

    Check whether the count is less than or equal to the declared size, not whether it is identical to it.

  • Common mistake

    Reading the declared size from the braces instead of the type

    What it looks like
    std::array<int, 3> a = {1, 2, 3, 4};
    Why it fails

    The size 3 comes from the type portion array<int, 3>. The braces supply values and do not set the size.

    Do this instead

    Find N in the type portion, then count the values in the braces and compare them.

  • Common mistake

    Looking for the error in later code that uses the array

    Why it fails

    The source material says that when the counting rule is violated, the problem sits in the declaration line.

    Do this instead

    Start the search on the declaration line itself.

Predict Before You Check

What do you think happens?

For the declaration std::array<int, 2> p = {7, 8, 9};, does the initializer satisfy the rule, and on which line is any violation found?

  • It passes, because the array has positions 0 and 1 and the values are integers.

  • It violates the rule, because 3 values exceed the declared size of 2, and the violation is on this declaration line.

Reveal answer
Answer:

It violates the rule, because 3 values exceed the declared size of 2, and the violation is on this declaration line.

The declared size N is 2 from the type portion, and the count n of values in the braces is 3. Since n is greater than N, the rule n less than or equal to N is broken, and the declaration line is where to look first.

EASY

For each declaration, state the declared size N, the count n, and whether n is less than or equal to N. Then identify which declarations are valid: (a) std::array<int, 4> x = {1, 2, 3, 4}; (b) std::array<int, 2> y = {1}; (c) std::array<int, 3> z = {1, 2, 3, 4, 5};

Hints
  • The declared size comes from the number inside the type portion, not from the braces.
  • Counts equal to N and counts smaller than N both pass.
  • Only a count greater than N breaks the rule.

Key Takeaways

  • An initializer list is a braced list of values written in an array declaration that fills the array when it is created.
  • In a declaration like array<int, 3>, the 3 is the declared size and the braces supply the values.
  • The rule is that the number of values in the initializer must be equal to or less than the declared size: equal and smaller counts pass, and only a larger count breaks the rule.
  • Values fill positions in order, counting from 0, so the first value goes to index 0.
  • When a declaration breaks the counting rule, check the declaration line first.

Related concepts

More concepts starting with D