Chapter | Page | Description |
---|---|---|
3 | 29 | Point 2, run time=>compile time |
3 | 34 | comp needs to declare arguments as const (cm) |
4 | 50 | Line 7, Slicing occurs only with stack-resident, see footnote. (gk) |
4 | 51 | 2nd Par. Some earlier compilers will abort on insufficient memory (gk) |
4 | 60 | remove void in header for String::StringReference::StringReference (cm) |
4 | 61 | Line g = b is wrong, should be g = c (rb) |
4 | 62 | should point out that globals will be destructed just before the program exits. (gk) |
5 | 66 | See more on include files |
5 | 79 | print in child class has wrong text (cm) |
5 | 79 | Line -2, should be cast to child pointer (cm) |
5 | 80 | Should mention static inner classes (see footnote). |
6 | 93 | Sec 6.1.1 Exact size of internal pointer is machine dependent (gk) |
6 | 94 | line 6, println should be printf (cm) |
6 | 96 | line 4, no & needed in Java code (cm) |
6 | 96 | printf at bottom missing newlines (gk) |
6 | 102 | Cat should derive from Animal, not Mammal (cm) |
7 | 110 | List of overloadable operators is not complete, missing pointer dereferencing (gk) |
7 | 112 | rule: const only needed for objects, automatic for primitive types (gk) |
7 | 118 | Missing address operator, this == & right (gk) |
7 | 129 | extra * in ampresand operator, should be ``return this'' (gk) |
7 | 130 | Missing const declarations, see footnote (gk) |
8 | 138 | Line 1, hexadecimal is misspelled (gk) |
8 | 138 | Line 2, 0123 => 123 (no zero) (gk) |
8 | 138 | Line 2, L'01234' => L'\1234' (slash, no zero) (gk) |
8 | 138 | The L modifier can also be applied to strings, to get wide strings (gk) |
8 | 139 | strncopy, strncat - should say "at most n" (cm) |
8 | 140 | Code at bottom, literal => text (twice) (gk) |
9 | 154 | The list proves=>the list provides (line -9) |
9 | 159 | value should be const in find declaration (although const isn't really discussed until chapter 12) (cm) |
9 | 161 | Random numbers, see footnote (gk) |
10 | 166 | should mention that puts adds a newline, fputs doesn't (gk) |
10 | 167 | Error message should go to stderr, not stdout (gk) |
10 | 167 | String for fputs needs newline (gk) |
11 | 182 | Line -15 ``made it into the STL'' should be ``made it into the language'' |
11 | 186 | Line 3, iof => of |
12 | 196 | differences between import and include (see footnote) |
12 | 201 | Should mention const_cast, specifically for casting away const (gk) |
12 | 201 | default arguments can only be trailing (gk) |
12 | 205 | midpage, overwritten => overridden (gk) |
14 | 233 | putback code is wrong if EOF is encountered, putting back EOF is complicated(gk) |
15 | 239 | could use find instead of count (gk) |
16 | 263 | see earlier comments on random numbers (gk) |
A * anAptr = new A; B aBvalue; *anAptr = aBvalue; // will get sliced anAptr = & aBvalue; // will not get sliced
The randomInteger class suffers from two serious problems. First, there are three different library functions commonly available for generating pseudorandom numbers. Of these, rand() is by far the poorest, and it should always be avoided. Much better pseudorandom numbers are generated by the random() function, which returns a 31-bit pseudorandom integer. The best commonly available generator, however, is drand48(), which also has the advantage of returning double-precision values between zero (inclusive) and 1 (noninclusive). You should always start with drand48() as your preferred generator, and fall back to random() only if drand48() is unavailable.
The other problem with the example code is the use of the modulo (%) operator to reduce the pseudorandom numbers to a small range. I emphasize to my students that they should never use modular arithmetic with pseudorandom numbers! There are two reasons for this:
1. Most pseudorandom numbers are less random in the least significant bits. For example, if you use a max of 16 in Budd's sample class, you may find that your "random" number repeats as often as every 16 values. The most significant bits of the number are much more "random."
2. If your range does not precisely divide the range of the pseudorandom-number generator, there will be a slight bias because some values are more likely than others.
For these reasons, the output of a pseudorandom-number generator should be scaled by division. The easiest way to do it is to convert the result to a double-precision number in the range 0 to 1, and then multiply by the desired range. For example:
#includeEither of these sequences will generate a pseudorandom integer in the range of 0 to max - 1, inclusive.... int i = ((double)random() / RAND_MAX) * max; int j = max * drand48();
Finally, astute students will note that I always refer to pseudorandom, not random, numbers. The values returned by the functions under discussion are not truly random,
Last Modified: 22 October 2003