Changes Made from the Second Printing to the Third
Chapter 9
Page |
Line |
Change |
To |
520 |
25 |
introduce vector<T>, a C++ standard class template |
introduce valarrays and vector <T>, C++ standard class templates |
523 |
8-11 of Fig. 9.1 |
iostream.h |
iostream |
|
11B |
InteractiveInput |
InteractiveOpen |
527 |
8T |
int |
count |
533 |
19T |
#include <iostream.h> |
. . . |
534 |
4 of Fig. 9.2 |
iostream.h |
iostream |
535 |
1T |
iomanip.h |
iomanip |
536 |
11T |
<string.h> , stdlib.h>, <stdio.h> |
<cstring> , <cstdlib>, <cstdio> |
|
10B |
(or other) arrays |
(or other) C-style arrays |
537-540 |
|
Replace last 8 lines of p. 537, all of p. 538, all of p. 539, Fig. 9.4 and the 6 lines following with the following new subsection: |
|
There are, therefore, two significant problems with C-style arrays: |
With respect to the second problem, we have seen that the C++ class mechanism allows different data members to be stored within a single object. This provides a solution to the second problem by storing an array, its capacity, and its size within a class structure, a single class object can encapsulate all three pieces of information. This is the approach used by valarrays that we describe next and vectors described in the next section. As we shall see, they also provide solutions to the first problem. |
An OOP Approach valarrays |
An important use of arrays is in vector processing and other numeric computation in science and engineering. In mathematics the term vector refers to a sequence (one-dimensional array) of real values on which various arithmetic operations are performed; for example, +, , scalar multiplication, and dot product. Because much numeric work relies on the use of such vectors, highly-efficient libraries are essential in many fields. For this reason, C++ provides the standard library <valarray>, which is designed to carry out vector operations very efficiently. |
Declarations of valarrays. A valarray declaration has one of the forms |
valarray<T> v; |
valarray<T> v(n); |
valarray<T> v(value, n); |
valarray<T> v(array); |
valarray<T> v(w); |
where T is a numeric type; n is an integer specifying the capacity of v; value is a value of type T; array is an array of T values; and w is a valarray.3 To illustrate, consider the following examples: |
valarray<double> v0; |
valarray<float> v1(100); |
valarray<int> v2(999, 100); |
const double a[] = {1.1, 2.2, 3.3, 4.4, 5.5}; |
valarray<double> v3(a, 4), v4(4, -1.0); |
The first declaration creates v0 as an empty valarray of doubles (which can be resized later); the second constructs v1 as a valarray containing 100 float values, initially 0; the third creates v2 as a valarray of 100 int values, initially 999; the last declarations construct v3 as a valarray of 4 doubles, initially the first four values (1.1, 2.2, 3.3, 4.4) stored in array a, and v4 as a valarray of 4 doubles, initially 1.0. |
There also are four auxiliary types that specify subsets of a valarray: slice_array, gslice_array, mask_array, and indirect_array. These seem inappropriate, however, for a first course in computing and are thus left for the sequel to this text. |
valarray Operations. The function members for valarrays are: |
Example: -v3 gives 1.1, 2.2, 3.3, 4.4 If D denotes one of these operations, v D= x; is equivalent to: for (int i = 0; i < v.size(); i++) v[i] = v[i] D x; Example: v3 += v4 changes v3 to 0.1, 1.2, 2.3, 3.4
Example: v3.size() is 4
Example: cin >> n; v0.resize(n);
There also are several nonmember operations, which are applied elementwise:
+ , -, *, /, , &, |, ^, <<, >>, &&, ||, ==, !=, <, >, <=, >=
These operations and functions are applied elementwise. The operands may be valarrays or a valarray and a scalar |
acos(), asin(), atan(), cos(), cosh(), exp(), log(), log10(), sin(), sinh()(), sqrt(), tan(), tanh() For example, the assignment statements v4 = 2.0 * v3; w = pow(v3, 2); assign to v4 the values 2.2, 4.4, 6.6, 8.8 and to w the squares of the elements of v3, namely, 1.21, 4.84, 10.89, 19.36. Some other operations that are useful with valarrays are found in the standard <algorithm> and <numeric> libraries (described in the Section 9.4). For example, <numeric> contains functions for calculating the sum of the elements in a sequence, the inner (dot) product of two sequences, the partial sums of a sequence, and differences of adjacent elements in a sequence Input. No predefined input operations are provided for valarrays, and so we must write our own input function to read values and store them in a valarray one at a time. Figure 9.3 presents an input function template. For maximum reusability, it receives the stream from which the values are to be extracted, so that the valarray can be input from the keyboard or from a file. Note that because a valarray carries its capacity (size()) along with it, there is no need to pass it as a parameter. |
Figure 9.3 Input Operation for valarrays. |
/* Read() fills a valarray<T> with input from a stream. * Note: Must #include <valarray> to use this function. * * Receives: type parameter t * in, an istream * theValArray, a valarray * Input: a sequence of T values * Precondition: operator >> is defined for type T. * Passes back: the modified istream and the modified valarray<T> ****************************************************************/ template <class T> void Read(istream & in, valarray<T> & theValarray) { for (int i = 0; i < theValarray.size(); i++) in >> theValarray[i]; }
Output. As with input, there is no output operation defined for valarrays and so a function to perform this operation must display the values in the valarray one at a time. Using a for loop like that in Read() is the approach in the function Print() in Figure 9.4. Again note that because a valarray carries its size along with it, there is no need to pass it as a parameter. |
|
Figure 9.4 Output Operation for valarrays. |
/* Print() displays the T values stored in a valarray. * Note: Must #include <valarray> to use this function. * * Receives: type parameter t * out, an ostream * theValArray, a valarray * Output: each value in theArray to the ostream out * Precondition: operator << is defined for type T. * Passes back: the modified ostream out ************************************************************/ template <class T> void Print(ostream & out, const valarray<T> & theValarray) { for (int i = 0; i < theValarray.size(); i++) out << theArray[i] << " "; }
542 |
6 |
int i, j, n = 9; |
int i, j, n = 9, |
543 |
21B & 18B |
open an fstream |
open a stream |
|
17B |
to the fstream |
to the file stream |
|
16B |
close the fstream |
close the stream |
|
2B |
Open an fstream |
Open a stream |
|
1B |
from an fstream |
from a file stream |
544 |
1T |
an fstream |
a file stream |
|
3T |
Open an fstream |
Open a stream |
|
4T |
to an fstream |
to a file stream |
546 |
1-6T |
iostream.h |
iostream |
548 |
Last sentence of first para. |
Replace |
The ISO/ANSI standard includes STL among the standard C++ libraries. |
|
9T |
The simplest container |
One of the simplest containers |
550 |
2 above table |
array but without the limitations of C-style arrays |
array or valarray but without the limitations of C-style arrays and valarrays |
551 |
5-8T |
Replace |
v .size() returns the number of values in v. As with C-style arrays and valarrays, the index of the first value of a vector<T> is always 0; but unlike arrays and valarrays, which provide no way to identify the final values stored in them, the index of the last value stored in a vector<T> object v is always v.size() - 1. |
554 |
8-9T |
As with C-style arrays, |
As we have noted, |
|
11T |
the elements |
the values stored |
|
18T |
C-style arrays |
C-style arrays and valarrays. |
|
19-20T |
Replace last sentence of paragraph |
To illustrate the difference, suppose we modified the Read() function in Figure 9.3 to read values into a vector<T> as follows: |
555 |
4 of Fig. 9.6 |
Insert a comment line |
* Input: a sequence of T values |
|
4 of Fig. 9.7 |
Insert a comment line |
* Output: each T value stored in theVector to ostream out |
562 |
Paragraph above table |
Replace |
STL provides over 80 algorithm templates. An in-depth examination of these algorithms is beyond the scope of this text and is left for the sequel. The table that follows provides a brief introduction to what is available. All of these algorithms are in the <algorithm> library except for accumulate(), which was moved to the<numeric> library in the final ISO/ANSI standard. |
|
Footnote |
Delete |
|
563 |
6T |
count(begin,end,value,0) |
count(begin,end,value) |
|
9-10T |
Delete entry for function iota() |
|
|
1B |
Insert comment line before this line |
* Note: Must #include <numeric> to use accumulate() |
564 |
11T |
algorithm |
algorithm from the <numeric> library |
|
13-14T |
Famility with the algorithms provided by STL |
Famility with the standard algorithms in C++ |
565 |
9B |
Insert before last sentence of paragraph. |
(We will not consider valarrays here because they can be used only for numeric values.) |
566 |
10T |
Append: |
and valarray operations are limited to numeric applications. |
|
12T |
both the C-style array and |
the C-style array, valarrays, and |
|
16T |
in an array or |
in an array, valarray<int>, or |
|
4B |
Footnote number 8 |
7 |
|
Footnote |
8 |
7 |
568 |
3T |
an fstream |
a stream |
|
4T |
the fstream |
the file stream |
571 |
10 of Fig. 9.10 |
iomanip.h |
iomanip |
572 |
In Fig. 9.11: line 16 |
Replace |
using namespace std; |
573 |
10-20 |
Replace definition of function Read() |
} |
578 |
20 |
ANSI/ISO draft standard for C++ in 1995 |
ISO/ANSI standard for C++ in 1997 |
|
22 |
are becoming a reality |
have become a reality |
579 |
24B |
arrays and |
arrays, valarrays, and |
|
20B |
C-style array. |
C-style array of a valarray. |
|
4B |
array or vector<T> |
array, valarray, or vector<T> |
580 |
13T |
array or vector<T> |
array, valarray, or vector<T> |