You are using two different language features that combined in the wrong way, cause your code to behave erratically.
Implicit deduction of array size.
The C ++ language (and also C) allows the size of an array to be omitted if the elements are given explicitly when initializing it; in that case the compiler will count the elements saving that tedium to the programmer, in your case:
int vecUno[] = {1, 2, 3, 4, 5}; // Arreglo de 5 elementos, equivale a int vecUno[5] = ...
int vecDos[] = {1, 2, 3, 4, 5}; // Arreglo de 5 elementos, equivale a int vecDos[5] = ...
int vecSuma[] = {}; // Arreglo de CERO elementos
int vecProducto[] = {}; // Arreglo de CERO elementos
Since when initializing vecSuma
and vecProducto
you have given them an empty list, the count of elements of these lists is zero, so they contain zero elements; on the other hand vecUno
and vecDos
contain five elements because the count of elements of the list used to initialize them is five; in memory they would look similar to:
As you can see, neither vecSuma
nor vecProducto
point to space in memory because they have 0 elements!
Decay from fix to pointer.
Passing an array to a function without indicating its size is equivalent to passing a pointer to the first element of the array, so your functions mustrar
, suma
and producto
could be rewritten to accept pointers without their behavior was affected:
void mostrar(int vecAMostrar *, int tamanioVector);
void suma(int vec1 *, int vec2 *, int vecResultado *, int tamanioAceptado);
void producto(int vec1 *, int vec2 *, int vecResultado *, int tamanioAceptado);
However, if you had specified the size in the array parameter of the functions (instead of adding it as an additional parameter) you would have encountered an error at compile time:
void mostrar(int (&vecAMostrar)[5]) { ... }
void suma(int (&vec1)[5], int (&vec2)[5], int (&vecResultado)[5]) { ... }
void producto(int (&vec1)[5], int (&vec2)[5], int (&vecResultado)[5]) { ... }
int main()
{
// ...
producto(vecUno, vecDos, vecProducto);
mostrar(vecProducto
// ..
suma(vecUno, vecDos, vecSuma);
mostrar(vecProducto
// ...
return 0;
}
error: ninguna función coincide con la llamada a 'producto'
producto(vecUno, vecDos, vecProducto);
^~~~~~~~
nota: la función candidata no es viable: no existe conversión conocida de 'int [0]' a 'int (&)[5]' para el 3r parámetro
void producto(int (&vec1)[5], int (&vec2)[5], int (&vecResultado)[5]){
^
error: ninguna función coincide con la llamada a 'mostrar'
mostrar(vecProducto);
^~~~~~~
nota: la función candidata no es viable: no existe conversión conocida de 'int [0]' a 'int (&)[5]' para el 1r parámetro
void mostrar(int (&vecAMostrar)[5]){
^
error: ninguna función coincide con la llamada a 'suma'
suma(vecUno, vecDos, vecSuma);
^~~~
nota: la función candidata no es viable: no existe conversión conocida de 'int [0]' a 'int (&)[5]' para el 3r parámetro
void suma(int (&vec1)[5], int (&vec2)[5], int (&vecResultado)[5]){
^
By passing the parameters as a reference to a fixed-size array (that odd parameter of tipo (&nombre)[tamaño]
) we avoid that the array drops to pointer and then the compiler is forced to check if the last parameter matches the expected parameter; As we can see, the errors do not coincide: an arrangement of any element is not an arrangement of five elements.
What happened to your program?
We have seen that vecSuma
and vecProducto
do not point to any space in memory (of course, they have zero elements) so when indexing and writing about them you are forcing a undefined behavior that could make the program work without visible errors, or could cause memory corruption (showing erroneous values), or it could erase your hard drive, cause Third World War or invoke demons inside your nostrils .
How to fix it?
As Dariel Ramos Díaz de Villegas has already commented, a possible solution is to assign size to the destination arrangements ( although it has not explained why this solves it) in this way you avoid indefinite behavior since the fixes vecSuma
and vecProducto
will point to a memory space large enough to assign the results of the operations; if you are going to use fixes of prefixed size I would also advise to use the type of these fixes as type of the parameters, getting in this way that the compiler detects the errors in compile time:
using cinco_enteros = int[5];
void mostrar(const cinco_enteros &vecAMostrar){
for (const auto &valor : vecAMostrar) {
std::cout << valor << '\n';
}
}
void suma(const cinco_enteros &vec1, const cinco_enteros &vec2, cinco_enteros &vecResultado){
for(int i = 0; i < 5; ++i){
vecResultado[i] = vec1[i] + vec2[i];
}
}
void producto(const cinco_enteros &vec1, const cinco_enteros &vec2, cinco_enteros &vecResultado){
for(int i = 0; i < 5; ++i){
vecResultado[i] = vec1[i] * vec2[i];
}
}
In the previous code we have defined an alias for the type int[5]
(an array of five integers) and we use it to declare the parameters of the functions, you can see the code working here ; note that in addition the parameters that will be used only to be read are passed as constants, this is considered a good practice; also bear in mind that I have eliminated the instruction return
of the end of the functions, it is not necessary because the function was already going to end likewise.
Another alternative, knowing the size beforehand, is to use a std::array<int, 5>
instead of a int[5]
.
Other things to consider.
- Encourage when possible (almost always) the pre-increment to the post-increment, read this article for more details.
- In such a short program you will not have many problems, but as far as possible avoid
using namespace std;
in headers (does not apply in your case), read this thread to know why.
- Encourage the use of
\n
versus std::endl
where possible (almost always), read this thread to find out why.