I will start this lesson with a simple experiment.
I declared an array with three integers, and I'm wondering
what will be the output of this sizeof operator when I
pass it the name of the array.
Since we said that the name of the array works like a pointer,
this should probably return 8, because on this system
we need 8 bytes to store a pointer.
However, as you can see, the result is not 8, it is 12.
Like we mentioned before,
array names can be used like pointers in certain situations,
but this is not one of them.
When you declare an array, C++ will add a little bit of magic,
a little bit of syntactic sugar to it. Compiler will actually know that
this name is assigned to an array and it will return 12 bytes, because
that is the actual size of the whole array.
Each integer needs 4 bytes, so 3 integers make an array of 12 bytes.
This is the size of the array in memory, but you may have
also noticed that in the previous lesson,
I used the word size to refer to the number of elements.
Terminology for this is not consistent,
but I guess I could have said that the number of elements is the
length of the array. But since I'm only going to use the sizeof
operator with arrays in this lesson,
I will keep referring to the array length as size.
Now, let's say that I want to pass this array to a function as an argument.
The name of the function will be printArray and the
purpose of the function is obvious.
The function will print the elements from the given array, but
notice the syntax for using the array as a parameter.
This is the correct way to do this and it will work.
The parameter will accept the array of integers of any size,
but we still need to know the size of the array, because we will need
it to create a for loop inside of the function.
Since this expression gives us the size of the whole array,
maybe we can divide it by the size of one integer to get the number of elements.
Let's try to compile this, and it works. Now, let's do the
same thing from inside of the function.
I will pass this parameter to the sizeof operator, compile
this to make sure that it's still working, and it seems that
it's not, because we get 2. But why?
Also, it's hard not to notice this big warning message which says that the
sizeof operator will return the sizeof a pointer to an integer.
This is because of a somewhat dangerous and really common
occurrence of something called a pointer decay. Whenever
you pass an array to a function,
the parameter that should accept the array will decay
from an array to a simple pointer.
This is known as decay because a little bit information
has been lost. Inside of this function,
the compiler no longer adds that syntactic sugar to our array
that lets us get the size of all elements.
So this is the same as defining this parameter as a
simple pointer to an integer.
The square bracket syntax is allowed because of programmers, so that we
can be more explicit about our intentions in the code.
If you use square brackets,
compiler will figure out that your intention is to pass an
array, so, that is why we got that big warning message that
warns us about pointer decay.
You can also use a simple pointer to pass an array, but
only if you know what you're doing.
So, using this sizeof operator to get the number of
elements inside of a function is not possible.
Whenever you want to pass an array,
you also need to pass another argument which will inform the function
about the number of elements inside of that array.
I will continue referring to this as size, so that's
how I will name the parameter.
So now that we know the size,
we can print all of the elements by looping through the array.
I use the pointer arithmetic to do this, just like we
learned in one of the previous lessons.
However,
if you know that this decayed pointer will always represent an array, you can
use the square brackets operator just like you normally would.
So, other than passing this size explicitly, everything else works in
the same way. You could have also put the expected size here in the
square brackets, but this wouldn't do anything.
This would still be just a pointer.
I also need to mention that you should not use this approach for
calculating size, even in the main function, It is not reliable,
and once we learn about dynamic arrays,
you will see that this will only work with static arrays like this one.
You should always personally keep track of the size and pass it
to functions that require array arguments.
Now, let's implement this new concept in our calculator.
I will create a special function for each operation, sum function will add all
of the elements, and multiply will, of course, multiply them.
The first argument is the array of numbers, and the second one is the
size of the array, just like we learned. The function logic is the same
as before, we just need to define the result in each function and then
print it out to the terminal.
Now I can remove the result variable from the main function
and delete the logic from every case.
We don't need this anymore.
Instead, I will just call our two new functions and pass
them the numbers array and its size.
This will make our main function more readable, but we will
continue to optimize it in the next lesson.