- Exercise 5.1
- Exercise 5.2
- Exercise 5.3
- Exercise 5.4
- Exercise 5.5
- Exercise 5.6
- Exercise 5.7
- Exercise 5.8
- Exercise 5.9
- Exercise 5.10
- Exercise 5.11
- Exercise 5.12
- Exercise 5.13
- Exercise 5.14
- Exercise 5.15
- Exercise 5.16
- Exercise 5.17
- Exercise 5.18
- Exercise 5.19
- Exercise 5.20
- Exercise 5.21
- Exercise 5.22
- Exercise 5.23
- Exercise 5.24
- Exercise 5.25
What is a null statement? When might you use a null statement?
A null statement is a single semicolon. A null statement is useful where the language requires a statement but the program's logic does not, such as a while loop where no concrete operation is needed.
What is a block? When might you might use a block?
A block is a (possibly empty) sequence of statements and declarations surrounded by a pair of curly braces.
Use the comma operator (§ 4.10, p. 157) to rewrite the while loop from § 1.4.1 (p. 11) so that it no longer requires a block. Explain whether this rewrite improves or diminishes the readability of this code.
Explain each of the following examples, and correct any problems you detect.
(a) while (string::iterator iter != s.end()) { /* ... */ }
(b) while (bool status = find(word)) { /* ... */ }
if (!status) { /* ... */ }
(a) Define an iterator to access every character in a string. The problem is iter is not initialized:
string::iterator iter = s.begin();
while (iter != s.end()) { /* ... */ }
(b) Define a bool variable in while loop and then use it outside the while loop. This is illegal, because status is out of scope:
bool status = false;
while(status == find(word)) { /* ... */ }
if (!status) { /* ... */ }
Using an if–else statement, write your own version of the program to generate the letter grade from a numeric grade.
Rewrite your grading program to use the conditional operator (§ 4.7, p. 151) in place of the if–else statement.
Correct the errors in each of the following code fragments:
(a) if (ival1 != ival2) ival1 = ival2
else ival1 = ival2 = 0;
(b) if (ival < minval) minval = ival;
occurs = 1;
(c) if (int ival = get_value())
cout << "ival = " << ival << endl;
if (!ival)
cout << "ival = 0\n";
(d) if (ival = 0)
ival = get_value();
(a) if (ival1 != ival2)
ival1 = ival2;
else
ival1 = ival2 = 0;
(b) if (ival < minval) {
minval = ival;
occurs = 1;
}
(c) if (int ival = get_value())
cout << "ival = " << ival << endl;
else
cout << "ival = 0\n";
(d) if (ival == 0)
ival = get_value();
What is a “dangling else”? How are else clauses resolved in C++?
If there is more if branches than else branches, we need to know which if a given else belongs. Such else is a dangling else.
In C++, the ambiguity is resolved by specifying that each else is matched with the closest preceding unmatched if.
Write a program using a series of if statements to count the number of vowels in text read from cin.
There is one problem with our vowel-counting program as we’ve implemented it: It doesn’t count capital letters as vowels. Write a program that counts both lower- and uppercase letters as the appropriate vowel—that is, your program should count both 'a' and 'A' as part of aCnt, and so forth.
Modify our vowel-counting program so that it also counts the number of blank spaces, tabs, and newlines read.
Modify our vowel-counting program so that it counts the number of occurrences of the following two-character sequences: ff, fl, and fi.
Each of the programs in the highlighted text on page 184 contains a common programming error. Identify and correct each error.
(a) unsigned aCnt = 0, eCnt = 0, iouCnt = 0;
char ch = next_text();
switch (ch) {
case 'a': aCnt++;
case 'e': eCnt++;
default: iouCnt++;
}
(b) unsigned index = some_value();
switch (index) {
case 1:
int ix = get_value();
ivec[ ix ] = index;
break;
default:
ix = ivec.size()-1;
ivec[ ix ] = index;
}
(c) unsigned evenCnt = 0, oddCnt = 0;
int digit = get_num() % 10;
switch (digit) {
case 1, 3, 5, 7, 9:
oddcnt++;
break;
case 2, 4, 6, 8, 10:
evencnt++;
break;
}
(d) unsigned ival=512, jval=1024, kval=4096;
unsigned bufsize;
unsigned swt = get_bufCnt();
switch(swt) {
case ival:
bufsize = ival * sizeof(int);
break;
case jval:
bufsize = jval * sizeof(int);
break;
case kval:
bufsize = kval * sizeof(int);
break;
}
(a) unsigned aCnt = 0, eCnt = 0, iouCnt = 0;
char ch = next_text();
switch (ch) {
case 'a': aCnt++; break;
case 'e': eCnt++; break;
default: iouCnt++; break;
}
(b) unsigned index = some_value();
int ix;
switch (index) {
case 1:
ix = get_value();
ivec[ ix ] = index;
break;
default:
ix = ivec.size()-1;
ivec[ ix ] = index;
}
(c) unsigned evenCnt = 0, oddCnt = 0;
int digit = get_num() % 10;
switch (digit) {
case 1: case 3: case 5: case 7: case 9:
oddcnt++;
break;
case 2: case 4: case 6: case 8: case 10:
evencnt++;
break;
}
(d) constexpr unsigned ival=512, jval=1024, kval=4096;
unsigned bufsize;
unsigned swt = get_bufCnt();
switch(swt) {
case ival:
bufsize = ival * sizeof(int);
break;
case jval:
bufsize = jval * sizeof(int);
break;
case kval:
bufsize = kval * sizeof(int);
break;
}
Write a program to read strings from standard input looking for duplicated words. The program should find places in the input where one word is followed immediately by itself. Keep track of the largest number of times a single repetition occurs and which word is repeated. Print the maximum number of duplicates, or else print a message saying that no word was repeated. For example, if the input is
how now now now brown cow cow
the output should indicate that the word now occurred three times.
Explain each of the following loops. Correct any problems you detect.
(a) for (int ix = 0; ix != sz; ++ix) { /* ... */ }
if (ix != sz)
// ...
(b) int ix;
for (ix != sz; ++ix) { /* ... */ }
(c) for (int ix = 0; ix != sz; ++ix, ++sz) { /*...*/ }
(a) Define an int ix inside the for loop and increment ix until ix is equal to sz. The if test is illegal, because ix is out of scope.
(b) Illegal:
int ix;
for (;ix != sz; ++ix) { /* ... */ }
(c) The loop is illegal. The problem is if sz is not equal to ix, the loop won't break, because both ix and sz is incremented at the end of one iteration.
The while loop is particularly good at executing while some condition holds; for example, when we need to read values until end-of-file. The for loop is generally thought of as a step loop: An index steps through a range of values in a collection. Write an idiomatic use of each loop and then rewrite each using the other loop construct. If you could use only one loop, which would you choose? Why?
Idiomatic loop:
- while loop
int i;
while (cin >> i) {
cout << i << " ";
}
- for loop
for (auto i = v.begin(); i != v.end(); ++i) { // v is a pre defined vector of int
cout << *i << " ";
}
- exchange two loops:
auto i = v.begin();
while (i != v.end()) { // v is a pre defined vector of int
cout << *i << " ";
++i;
}
for (int i; cin >> i;) {
cout << i << " ";
}
- conclusion
- for loop is quite fit for accessing elements in a sequence.
- while loop is quite fit for uncertain number of iterations.
Given two vectors of ints, write a program to determine whether one vector is a prefix of the other. For vectors of unequal length, compare the number of elements of the smaller vector. For example, given the vectors containing 0, 1, 1, and 2 and 0, 1, 1, 2, 3, 5, 8, respectively your program should return true.
Explain each of the following loops. Correct any problems you detect.
(a) do // there should be a pair of curly braces
int v1, v2;
cout << "Please enter two numbers to sum:" ;
if (cin >> v1 >> v2)
cout << "Sum is: " << v1 + v2 << endl;
while (cin);
(b) do {
// ...
} while (int ival = get_response()); // ival shouldn't be defined here
(c) do {
int ival = get_response();
} while (ival); // ival is out of scope here
(a) do {
int v1, v2;
cout << "Please enter two numbers to sum:" ;
if (cin >> v1 >> v2)
cout << "Sum is: " << v1 + v2 << endl;
} while (cin);
(b) int ival;
do {
// ...
} while (ival == get_response());
(c) int ival;
do {
ival = get_response();
} while (ival);
Write a program that uses a do while loop to repetitively request two strings from the user and report which string is less than the other.
Write a program to read a sequence of strings from the standard input until either the same word occurs twice in succession or all the words have been read. Use a while loop to read the text one word at a time. Use the break statement to terminate the loop if a word occurs twice in succession. Print the word if it occurs twice in succession, or else print a message saying that no word was repeated.
Revise the program from the exercise in § 5.5.1 (p. 191) so that it looks only for duplicated words that start with an uppercase letter.
The last example in this section that jumped back to begin could be better written using a loop. Rewrite the code to eliminate the goto.
int sz;
while (sz <= 0) {
sz = get_size();
}
for (int sz = get_size()) {
/* ... */
}
int sz;
do {
sz = get_size();
} while (sz <= 0)
Write a program that reads two integers from the standard input and prints the result of dividing the first number by the second.
Revise your program to throw an exception if the second number is zero. Test your program with a zero input to see what happens on your system if you don’t catch an exception.
Revise your program from the previous exercise to use a try block to catch the exception. The catch clause should print a message to the user and ask them to supply a new number and repeat the code inside the try.