Search

6.2 — Arrays (Part II)

This lesson continues the discussion of arrays that began in lesson 6.1 -- Arrays (part I)

Initializing fixed arrays

Array elements are treated just like normal variables, and as such, they are not initialized when created.

One way to initialize an array is to do it element by element:

However, this is a pain, especially as the array gets larger.

Fortunately, C++ provides a more convenient way to initialize entire arrays via use of an initializer list. The following example is equivalent to the one above:

If there are more initializers in the list than the array can hold, the compiler will generate an error.

However, if there are less initializers in the list than the array can hold, the remaining elements are initialized to 0. The following example shows this in action:

This prints:

7
4
5
0
0

Consequently, to initialize all the elements of an array to 0, you can do this:

In C++11, the uniform initialization syntax can be used instead:

Omitted size

If you are initializing a fixed array of elements using an initializer list, the compiler can figure out the size of the array for you, and you can omit explicitly declaring the size of the array.

The following two lines are equivalent:

This not only saves typing, it also means you don’t have to update the array size if you add or remove elements later.

Arrays and enums

One of the big documentation problems with arrays is that that integer indices do not provide any information to the programmer about the meaning of the index. Consider a class of 5 students:

Who is represented by array element 2? It’s not clear.

This can be solved by setting up an enumeration where one enumerator maps to each of the possible array indices:

In this way, it’s much clearer what each of the array elements represents. Note that an extra enumerator named MAX_STUDENTS has been added. This enumerator is used during the array declaration to ensure the array has the proper size (as the array length should be one greater than the largest index). This is useful both for documentation purposes, and because the array will automatically be resized if another enumerator is added:

Note that this “trick” only works if you do not change the enumerator values manually!

Arrays and enum classes

Enum classes don’t have an implicit conversion to integer, so if you try the following:

You’ll get a compiler error. This can be addressed by using a static_cast to convert the enumerator to an integer:

However, doing this is somewhat of a pain, so it might be better to use a standard enum inside of a namespace:

Passing arrays to functions

Although passing an array to a function at first glance looks just like passing a normal variable, underneath the hood, C++ treats arrays differently.

When a normal variable is passed by value, C++ copies the value of the argument into the function parameter. Because the parameter is a copy, changing the value of the parameter does not change the value of the original argument.

However, because copying large arrays can be very expensive, C++ does not copy an array when an array is passed into a function. Instead, the actual array is passed. This has the side effect of allowing functions to directly change the value of array elements!

The following example illustrates this concept:

before passValue: 1
after passValue: 1
before passArray: 2 3 5 7 11
after passArray: 11 7 5 3 2

In the above example, value is not changed in main() because the parameter value in function passValue() was a copy of variable value in function main(), not the actual variable. However, because the parameter array in function passArray() is the actual array, passArray() is able to directly change the value of the elements!

Why this happens is related to the way arrays are implemented in C++, a topic we’ll revisit once we’ve covered pointers. For now, you can consider this as a quirk of the language.

As a side note, if you want to ensure a function does not modify the array elements passed into it, you can make the array const:

sizeof and arrays

The sizeof operator can be used on arrays, and it will return the total size of the array (array length multiplied by element size). Note that due to the way C++ passes arrays to functions, this will _not_ work properly for arrays that have been passed to functions!

This prints:

32
4

For this reason, be careful about using sizeof() on arrays!

Indexing an array out of range

Remember that an array of size N has array elements 0 through N-1. So what happens if you try to access an array with a subscript outside of that range?

Consider the following program:

In this program, our array is of length 5, but we’re trying to write a test score into the 6th element (index 5).

C++ does not do any checking to make sure that your indices are valid for the length of your array. So in the above example, the value of 13 will be inserted into memory where the 6th element would have been had it existed, and likely causing your program to malfunction. This could overwrite the value of another variable, or cause your program to crash.

Although it happens less often, C++ will also let you use a negative index, with similarly undesirable results.

Rule: When using arrays, ensure that your indices are valid for the range of your array!.

Quiz

1) Declare an array to hold the high temperature (to the nearest tenth of a degree) for each day of a year. Initialize the array with a value of 0.0 for each day.

2) Set up an enum with the names of the following animals: chicken, dog, cat, elephant, duck, and snake. Put the enum in a namespace. Define an array with an element for each of these animals, and use an initializer list to initialize each element to hold the number of legs that animal has.

Write a main function that prints the number of legs an elephant has, using the enumerator.

Quiz answers

1) Show Solution

2) Show Solution

6.3 -- Arrays and loops
Index
6.1 -- Arrays (Part I)

50 comments to 6.2 — Arrays (Part II)

  • Two questions:
    If arrays can hold more than one integer (or doubles), why I get 4 as output when using sizeof to know the size of an int array of length 30. If it can store 30 different variables, size should be 120 bytes or ++

    If the actual array is passed to a parameter, why we are allowed to use different names of an array in declaration and different as parameter

    And typos:

    Remove still works from comment, because you are using an enum class and it wont work anymore
    Thanks :-)

    • Alex

      You can use sizeof on arrays, and it will tell you the size of the array in total (array length * element size). However, if you pass an array to a function, this will no longer work, because the array "decays" into a pointer, so you end up getting the size of the pointer instead. C++ is weird that way.

      > If the actual array is passed to a parameter, why we are allowed to use different names of an array in declaration and different as parameter

      Names are just names. If you want to call the array something different in the function, you can. This allows us to be able to write the function without having to know what the name of the argument being passed in is. Otherwise our functions wouldn't be very reusable.

  • Shivam Tripathi

    okk...:-)

  • Shivam Tripathi

    Alex...instead of declaring array with an "int" type...can't we declare this array with "Animals" enum type????

    • Alex

      It wouldn't make sense to do that. Each element of the array needs to hold an integer (to represent the number of legs the animal has).

      The enum should be used as the index to select the type of animal to get the number of legs for.

  • cpplx

    can you provide enum class (C++11) variant of solution to quiz2?

    • C++ newbie

      • cpplx

        does not compile. if it was that easy i wouldnt be posting for it

      • Alex

  • Deses

    First of all, thanks a lot for the tutorial thus far.

    Second, I used the enum class instead of enum as recommended elsewhere in this tutorial. This resulted in compiler error since enum class apparently has a non-integer type definition. I got around the issue by using static_cast to convert MAX_WHATEVER to integer. Is this the solution you would recommend or is there a better way around?

  • James

    The last enumerator equaling the size of the array is very clever.

  • Jim

    This is a great site. Very well written. I ve learned so much very quickly.
    A question: When I use the

    inside of a function it does not work. It gives always "1". Why is that? Following is the code I ve written. Any help would be appreciated.

    • alan

      Jim,
      the line in the function does work and correctly gives a result of 1, which is the size of the 'arr' array.
      int arr_len = sizeof(arr) / sizeof(arr[0]);

      The problem is you can't pass an array to a function, only a pointer to the array.
      You then need to determine the length of the array in main() and pass it to the function as a separate parameter. (described by Alex in a later tutorial).
      Not sure what the functions 'distance' and 'find' are doing but I expect you always get 20.93 because loc = 1 thus always points to the 2nd element.

      Probably frowned on but I've rarely used arrays (other than strings), when I have I tend to declare them globally (like you did), then their content, length, etc can be referenced anywhere in the code.
      For Example you could have used;
      int arr_len = sizeof(DN) / sizeof(DN[0]);
      in the function, and not needed to pass the array.

      Alan

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">