Now that we know how arrays work in theory,
let's see how we can utilize them in practice.
I will declare an array of four integers. Like we
discussed in the previous lesson,
we can use square brackets to specify the size, but what we didn't mention is
that we can initialize the array elements by using curly braces after the
declaration. Each one of these integer literals will get assigned to the
specific element of the array in this specific order.
If you decide to initialize an array in this way,
you can omit the array size from the square brackets.
The size will be deducted from the number of assigned elements;
however, I like to be explicit, so I'll get this number back.
Now that we declared this array, we can start using it.
I will print out the first element of the array to the terminal.
Remember that in this context, square brackets will act as an operator.
Number 0 is an offset, so this expression is equal to adding
this offset to the pointer of the first element and then
dereferencing that memory address.
Let's compile this program to see if this works as
expected. And it seems like it does.
Number 1 is the first element from the array.
Since this is just that the dereferenced memory address,
it is also possible to assign a new value to each element.
Let's say that I want to change the second element from number 2 to 5.
I will move this output expression after the assignment
and print out the second element.
This should print out number 5, and it does. Great.
Okay, but what if I want to print out all of the elements?
This is actually one of the great advantages of using arrays, they
work really well with loops, for loops especially.
So let's create a simple for loop that loops from 0 to 4.
The reason we want to start from 0 is because we want to use this iterator
variable as an offset inside of the square brackets.
Once it reaches 4, this condition will be false, and the loop
will be over, which is great because this array doesn't have
an element at the offset of 4.
Let's compile this now to see all of the elements.
Since we have a way to loop through the array,
we can use this loop for anything we want. We can use it to
initialize the whole array with the same value,
get an input from user for each element, or simply execute the
same code on each element from the array.
When we use static arrays like this one,
it is a good practice to store the size of the array
inside of some kind of a constant.
I could create a macro, but we will do that in one of
the following modules. Instead,
let's just create a constant variable and name it SIZE.
The size of our array is, of course, 4. In one of the previous
lessons, we learned how CPU manages stack memory and this array
will also be stored on the stack.
That means that its size should be known at compile time,
but if we use a variable to define the size,
compiler will be confused because variables are created at runtime.
This poses a risk that the variable could have another
value before it reaches this statement,
which is not uncommon because variability is the nature of variables.
For example,
what if this constant was initialized by a value from some other variable, x.
Even though this constant cannot be changed,
this variable could still be modified before this statement.
Const will just make this variable read only, and this is not a
good enough guarantee for the compiler. In C++,
we have a special constexpr keyword, which works
almost like a pre‑processor directive.
It creates a compile‑time constant.
So this would work because now the size is known at compile time; however,
since this is already a constant initialized at
declaration with a simple literal,
you can omit using this const expression keyword because this will
be treated by the compiler as a compile‑time constant because what
else could this constant contain?
Since it is a constant, it will not change.
And since its value is a literal, this literal won't change either.
So the compiler can optimize your code by assuming that this is a
compile‑time expression. I want to be explicit about this, but I just
wanted to explain why just using constant would also work because you
might see other programmers do that.
Okay, and now I can use this constant to declare the array, and
I can also loop through this array by replacing this literal
inside of the for loop condition.
If in the future I change my mind about the size of this array, I can
just change this constant instead of modifying hard‑coded literals all
over the code. Now that we know how arrays work,
let's use them to fix our program from the first lesson.
First of all,
I want to define a constant size, which in this case, will be
4 because we only need 4 operands for now.
I also don't want this number to be hardcoded inside of the
welcoming message, so let's make this message dynamic by
including the SIZE variable.
We don't need to declare a new variable for each operand
anymore, instead, let's declare a new array, which will hold
the specified number of integers.
And we know that we can access each element by using the for loop. Let's do
the same thing here, but instead of printing out values,
I want to wait for the user to input each element to the terminal.
You can see that our code is already easier to read and maintain.
We don't need to declare more variables and we don't have to
add each one of them to this expression.
This loop will do that for us regardless of how
many numbers we want to work with.
Now let's also optimize the switch case calculations.
Until now, we had to manually add every new operand to each one of
these calculations, but since we now use an array,
we can make this code more flexible and maintainable.
I will declare a new integer variable, which will hold the
result of the calculation, and I will initialize it to the value
of the first element from the array.
And now, instead of hardcoding each variable,
let's replace these calculations with for loops. Depending on the chosen
operator, we will either add or multiply each one of the elements with the
result variable. In case you didn't know, this is the same as adding this
element to the result value and then storing the result of that expression
back to the result variable.
You may notice that I'm starting the iterator variable from 1.
This is because I want to skip the first element because the first
element is already stored in the result variable.
So once the result is calculated, we will simply print it out to the terminal.
As you can see,
we are now able to change our mind about the number of operands, and the only
thing we need to do is to change the size of the array.
Everything else will work without any modifications to the rest of the code.
To test this,
I will change this variable to 6. Now, let's compile the program. I
will choose six random numbers and pick the addition operator. And
there you go, everything works as expected. Throughout the rest of
the module, we will learn about new ways to make this program even
more flexible.