The elements in an array are accessed by sequential index numbers ranging from 0 to one less than the size of the array. This indexing scheme lends itself to iterative access or processing driven by a for-loop and using the loop control variable as the array index.
int test[10]; for (int i = 0; i < 10; i++) cout << test[i] << endl; |
float test_score[10][4]; for (int i = 0; i < 10; i++) for (int j = 0; j < 4; j++) cout << test_score[i][j] << endl; |
One-Dimensional Array | Two-dimensional Array |
---|
The size of an array is fixed when the program creates it. This observation holds for both automatic and dynamic arrays. Sometimes, we know how many elements an array needs so it doesn't run out of or waste space. However, when we take data directly from user input or a file, we generally don't know how many data items the program will read. So, if we store the data in an array, we don't know how big to make it, and we can't change its size while the program runs. How do we solve this problem?
The only situation worse than wasting space in an array is running out of space! So, we use a technique common to many engineering disciplines: design for the worst-case scenario and then over-engineer the solution (i.e., add an extra safety margin). Some engineering disciplines have well-accepted rules of thumb for various safety margins, but software engineering generally lacks these rules. Nevertheless, in most contemporary computing environments, main memory is relatively ample and inexpensive, which argues for a generous safety margin.
Although a program establishes the size of an array when making it, it is not required to use every array element. In practice, we start filling the array at the beginning - at element 0 - and continue adding data sequentially until all data is stored. It's important to count how many elements the program fills, which requires an additional counter variable. This approach is useful when reading data from a file (illustrated in a later chapter) or entered by a user.
int scores[100]; int score; int count = 0; cout << "Enter a score (-1 to stop): "; cin >> score; while (score != -1) { scores[count++] = score; cin >> score; } |
int scores[100]; int count = 0; cout << "Enter a score (-1 to stop): "; do { cin >> scores[count++]; } while (scores[count - 1] != -1); count--; // discard the -1 |
We previously explored array assignment where we learned that assignment alone cannot copy an array. Nevertheless, it is sometimes necessary to copy an array, so how can we do it? It takes two steps to copy an array. First, we create a new array large enough to hold all the elements in the original array. Second, we copy the elements from the original array to the new one, one element at a time, as illustrated in the following figure.
int scores[50]; int* p2 = scores; |
int scores[50]; int* p2 = new int[50]; for (int i = 0; i < 50; i++) p2[i] = scores[i]; |
(a) | (b) |
int scores[50]; int p2[50]; for (int i = 0; i < 50; i++) p2[i] = scores[i]; |
void copy (int* p2, int p* p1, int size) { ... } |
(c) | (d) |