So, I just moved past simple data types in my computer science course, and we've moved onto arrays. I'm so confused. Here's my task:
Write a C++ program that declares an array list of 40 components of type double. Initialize the array so that the first 20 components are equal to the square of the index variable, and the last 20 components are equal to three times the index variable. Output the array so that 5 elements per line are printed
Even just tips will be a great help. Thank you!
I was also wondering how to pass arrays as the input parameter of a function.
An array is like a box of "stuff". A double array would be similar to a "box" of doubles. You create an array of doubles like this:
double arr[40]
You now have 40 doubles that are easy to access!
You access them from 0-39 like this:
1 2 3 4
arr[0]; //First Element
.
.
arr[39]; //Last Element
Of course, there's usually no reason to access them one at a time like this, so we use loops:
1 2 3 4 5 6
//You start at 0 and continue until i is equal to 40, because you don't want to
//access arr[40] since it doesn't exist
for(int i = 0; i < 40; i++)
{
arr[i] = 1; //This will set all elements to 1
}
A loop like that will go through all the elements and set them to 1, one at a time.
Hopefully mbozzi's code is easier to understand knowing this.
I was also wondering how to pass arrays as the input parameter of a function.
This is where we meet a legacy of C.
C++ can pass parameters to function by value or by reference.
1 2 3
void func( int arg ); // by value; arg is a copy of value of caller's variable
void func( int& arg ); // by reference; arg refers to caller's variable
void func( int* arg ); // by value; arg is a copy of value of caller's variable (which is a pointer)
Array decays to pointer in some situations. That way it is not necessary to copy the array.
1 2 3 4 5 6 7 8
double list[40]; // list is an array
// sizeof(list) is size that 40 doubles need
double* ptr = list; // implicit decay: ptr points to first element of list
// sizeof(ptr) is size of one pointer
void func( int* arg );
func( list ); // implicit decay: arg points to first element of list
The func cannot know, whether arg points to 1, 40, 5000 doubles, (or to invalid memory).
That is why the size is passed as separate parameter:
1 2 3 4
void func( int* arg, int size );
double list[40]; // list is an array
func( list, 40 );
Then there is std::vector. It has the size variable inside its object.
1 2 3 4 5
#include <vector>
void func( std::vector<double> arg ); // note that this copies the array that is in the vector
std::vector<double> list( 40 );
func( list );
What if we don't want to copy, to keep things efficient?
1 2 3
void func( std::vector<double> arg ); // by value, a copy
void func( std::vector<double>& arg ); // by reference
void func( const std::vector<double>& arg ); // reference, but func cannot change arg
be careful with pointers and arrays and copy vs reference.
you can change the data IN the array when you pass it in, even if it is a 'copy'. The 'copy' is a copy of the address (pointer), not the data in those memory locations. As a beginner it helps to think of arrays as *always* being passed by reference.
Vectors are safer about this issue, because the array isnt being passed, the external object wrapper to the array is being passed, and that makes all the difference. Most modern code avoids arrays.