C++ Demystified(c) A Self-Teaching Guide
An array is a variable. Therefore, like the other variables we have covered so far, an array must be declared before it can be used.
The syntax for declaring an array is almost identical to the syntax for declaring integers, characters , or other variables. For example, you would declare an integer variable testScore as follows :
int testScore;
By contrast, you would declare an array of three test scores this way:
int testScore[3];
This declaration contains an array of integers. You instead could declare an array of floats, characters, or strings in the following manner:
float GPA [5]; char grades[7]; string names[6];
While an array may be one of several data types, all the values in a particular array must be of the same data type. You cannot have an array in which some elements are floats, others are strings, still others are integers, and so on.
The declaration of both a single variable and an array of variables begins with the data type followed by a variable name and ending with a semicolon. The only difference between declaring a variable that holds a single value and an array is that, when declaring an array, the variable name is followed by a number within square brackets. That number is the array s size declarator.
Note | There is one exception to the necessity of having a size declarator. As discussed later in this chapter in the section on Initialization, the square brackets may be empty if you initialize the array when you declare it. |
The purpose of the size declarator is to tell the computer how much memory to reserve. The size declarator, combined with the data type of the array, determines how much memory to reserve.
As you may recall from Chapter 3, the declaration of a variable reserves memory for the number of bytes required by the data type of that variable, that number of bytes depending on the particular operating system and compiler. For example, if an integer variable required 4 bytes on your operating system and compiler, then declaring the integer variable testScore would reserve 4 bytes. If instead you declared an array of three integer variables, then the amount of memory reserved by that declaration would be 12 bytes, 4 —3.
Tip | You should give careful consideration to the number of elements in an array before you declare the array since you can t resize an array in the middle of a program in the event the array is too small or unnecessarily large. Sometimes, the number of elements is obvious; an array of the days in a week will have seven elements. However, other times the number of elements is not intuitive. In those circumstances, you should err on the side of declaring too many rather than too few elements. The reason is that the consequence of declaring too many elements, wasted memory, is less severe than the consequence of declaring too few elements, the inability to store values in the array. |
Constants
Each of the size declarators used in the previous section was a literal. A literal is a value that is written exactly as it is meant to be interpreted. For example, the number 3 is a literal. Its value cannot be anything other than 3. You can t change the number 3 to have some different value. Accordingly, the number 3 may be used in the following program as the size declarator:
#include <iostream> using namespace std; int main () { int testScore[3]; return 0; }
The size declarator may not be a variable. The following program attempts, unsuccessfully, to use a variable numTests in declaring the size of an array:
#include <iostream> using namespace std; int main () { int numTests; cout << "Enter the number of test scores:"; cin >> numTests; int testScore[numTests]; return 0; }
The result is a compiler error. The compiler will flag the declaration of the array ( int testScore[numTests] ) and complain that a constant expression was expected.
Note | It is possible to declare the size of an array with a variable if you use a different array declaration technique, dynamic memory allocation, which is covered in Chapter 11. |
The term constant is new. A constant is a name that represents the same value throughout a program. That value may be any one you specify. This is different than mathematical constants such as PI, which correspond to a given value.
A constant is the converse of a variable, while a variable is a name that may represent different values during the execution of a program. However, the value of a constant cannot change during the execution of a program.
Note | While neither a literal nor a constant changes its value during the execution of a program, they are not the same. While a constant is a name that represents a value, a literal is not a name, but instead the value itself. |
You may use a constant instead of a literal as a size declarator. The size declarator in the following program uses a constant for the value 3 rather than the literal 3.
#include <iostream> using namespace std; int main () { const int numTests = 3; int testScore[numTests]; return 0; }
Going back to the definition of a constant, a name that represents the same value throughout a program, the name is numTests, and it represents the value 3.
The syntax for declaring a constant is similar to, but not the same as, a syntax for declaring a variable. Each requires a data type (here int ) and a variable name (here numTests ) and ends in a semicolon. However, there are two differences.
First, the declaration of a constant must begin with the const keyword. This tells the compiler that you are declaring a constant instead of a variable.
Second, the declaration terminates by assigning the constant a value. You also ma y assign a variable a value when you are declaring it; you learned in Chapter 3 this is called initialization. However, assigning a variable a value when you declare it is optional. On the other hand, assigning a constant a value when you are declaring it is mandatory; the declaration of the constant will not compile if you don t, the compiler error being that a constant object must be initialized . The reason is, since you cannot assign a value of a constant after you declare it, the only time you can assign a value to a constant is when you declare it.
Note | The declaration of a constant does reserve memory just as does the declaration of a variable. The difference is that with a constant the value stored at the memory address cannot change during the life of the program. |
The following program illustrates that you cannot assign a value of a constant after you declare it:
#include <iostream> using namespace std; int main () { const int numTests = 3; cout << "Enter the number of test scores:"; cin >> numTests; int testScore[numTests]; return 0; }
The result is a compiler error. The compiler will flag the attempt to assign a value to the constant ( cin >> numTests ) and complain that the stream extraction operator >> cannot have a right-hand operand that is a constant. This is simply another way of saying you can t assign a value to a constant after you declare it.
The following program modifies the previous one by assigning the user input to a variable (so far so good) and then attempting to assign that variable to the constant (not good):
#include <iostream> using namespace std; int main () { const int numTests = 3; int num; cout << "Enter the number of test scores:"; cin >> num; numTests = num; int testScore[numTests]; return 0; }
Once again, the result is a compiler error. The compiler will flag the attempt to assign a value to the constant ( numTests = num ); the error message will be different than in the previous example, that l-value specifies const object. The 1 in l-value is a small L, not the number one, and refers to the value to the left of the assignment operator. This again is another way of saying you can t assign a value to a constant after you declare it.
While you can use a constant instead of a literal array to declare the size of an array, the question remains: why would you go to the trouble of doing so? The reason is that in your code you may need to often refer to the size of the array, not only when declaring it, but also, as shown later in this chapter, when assigning values to, and displaying them from, the array. However, the needs of the program may require you to modify the code to change the size of the array, usually to make it larger. For example, if as a teacher I change my policy from giving three tests to giving five tests, I need to change the size of the testScore array from three to five. If I use the literal number 3, I have to find that number each time it is referred to in the program and change it to 5. Not only is this time-consuming , but the potential exists that I could miss a reference I needed to change. By contrast, if I use a constant, such as const int numTests = 3, then all I need to do is change the 3 to 5 in that one place, and I m done.
You may be thinking, Wait a second, you just told me earlier in this chapter that you can t resize an array. Yes, you cannot resize an array while the program is running. However, you can change the size of the array in the code, and then recompile the program.
Constants have many uses in addition to signifying the size of an array, and those uses will be covered in this and further chapters of this book.
Array Index
The entire array has only one name. However, you need to be able to refer to individual elements of the array. You can refer to the individual elements of the array by their position within the array. This position is referred to as an index or subscript. I will use the term index in this book, but both terms are used, and are equally correct.
The first index in an array is always 0. There are no exceptions. The last index in an array is always 1 less than the number of elements in the array; again, with no exceptions.
The fact that the first index in an array is 0 instead of 1 is explained by the concept of an offset. An offset refers to a value added to a base address to produce a second address.
Figure 10-1 may be helpful in illustrating how offsets work with arrays. This figure shows graphically the result of declaring a three-element integer array such as int testScore[3]. The base address of an array is the address where the array begins. In Figure 10-1, the base address of the testScore array is 101.
The address of the first element of the array in Figure 10-1, 101, is the same as the base address of the array itself. Therefore, the value that would be added to the base address of the array to obtain the address of the first element of the array is 0, which is the index of the first element of the array.
The address of the second element of the array is the base address of the array, 101, plus 1 times the size of the data type of the array, 4, which is 101 + (1 — 4), or 105. Similarly, the address of the third element of the array is the base address of the array, 101, plus 2 times the size of the data type of the array, 4, which is 101 + (2 — 4), or 109.
Thus, the address of any element of the array is the base address of the array plus the offset, and in turn the offset is determined by the index of the array multiplied by the size of the array s data type.
Note | We will revisit addresses and offsets in the next chapter on pointers. |
Since the first index in an array must always be 0, the last index in an array must always be 1 less than the number of elements in the array. If you were counting three numbers , starting at 1, the last element would be number 3. However, if you are starting at 0 instead of 1, then the last number would be 2, not 3.
Caution | A common beginning programming mistake is to assume the index of the last element of the array is equal to the number of elements in the array. As you will learn later in this chapter, this can result in (depending on the compiler) run-time errors or unpredictable results, neither of which is good. |
At this point, we have not assigned a value to any of the elements of the array. The value of each element likely will be some strange number such as “858993460. As discussed in Chapter 3, the program does its best to interpret whatever value is at a given memory address, perhaps left over from some other program, but the resulting output often makes little sense.
Note | If the array variable is declared globally rather than locally, then each element is initialized to a default value, 0 for numeric data types and the null character for a character array. However, I already have given you my lecture against global variables. |
You can assign values to an array after you declare it, and later in this chapter I will show you how. However, it is also possible to assign values to an array at the same time that you declare it, as I will show you in the very next section.
Категории