- Good idea to use tools to automatically indent source code
- Jump statements have one of the 4 keywords:
break
,continue
,goto
,return
- Best practice is to avoid using
goto
because it makes the program hard to understand and hard to modify - Exceptions are run time anomalies. Exception handling involves:
throw
expressions: detect something it can't handle. We say athrow
raises an exceptiontry
blocks: deal with an exception. It has >= 1catch
clausescatch
clauses are aka exception handlers
- exception classes: used to pass information about what happened between a
throw
and acatch
- Writing exception safe code is hard. Some programs use exceptions simply to terminate. However, programs that handle exceptions and continue processing must ensure objects are valid, resources don't leak, and program is restored to an appropriate state
Explain each of the following examples, and correct any problems you detect.
(a) while (string::iterator iter != s.end()) { /* ... */ }
// Error: illegal declaration
// Fix:
string::iterator iter = s.begin();
while (iter != s.end()) {/* ... */ }
(b) while (bool status = find(word)) { /* . . . */ }
if (!status) { /* ... */ }
// Error: status is not defined
// Fix:
bool status;
while (status = find(word)) {/* ... */}
if (!status) {/* ... */}
What is a “dangling else”? How are else clauses resolved in C++?
"Dangling else" is the problem when processing nested if when there are more "if"s than "else"s. In C++, an "if" is always paired with an "else".
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++;
}
// Error: all aCnt, eCnt, iouCnt will be incremeted
// Fix:
unsigned aCnt = 0, eCnt = 0, iouCnt = 0;
char ch = next_text();
switch (ch) {
case 'a': aCnt++; break;
case 'e': eCnt++; break;
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;
}
// Error: ix in default case is not defined
// Fix:
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, 3, 5, 7, 9:
oddcnt++;
break;
case 2, 4, 6, 8, 10:
evencnt++;
break;
}
// Error: syntax error for case statements
// Fix:
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) 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;
}
// Error: case label must be a constant
// Fix:
const 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;
}
Explain each of the following loops. Correct any problems you detect.
(a) for (int ix = 0; ix != sz; ++ix) { /* ... */ }
if (ix != sz)
// . . .
It tries to loop from
ix = 0
toix != sz
. However,ix
is not defined outside of for loop
// Fix:
int ix;
for (ix = 0; ix != sz; ++ix) {/* ... */}
if (ix != sz)
// ...
(b) int ix;
for (ix != sz; ++ix) { /* ... */ }
The loop tries to run from
ix
tosz
. Error, missing statement in for loop
// Fix:
int ix;
for (; ix < sz; ++ix) { /* ... */ }
(c) for (int ix = 0; ix != sz; ++ix, ++ sz) { /* ... */ }
It tries to loop from
ix = 0
untilix != sz
. However, this is an infinite loop asix
andsz
keep incrementing by 1
// Fix:
for (int ix = 0; ix != sz; ++ix) {/* ... */}
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.
string s1, s2;
cin >> s1 >> s2;
do {
if (s1 < s2) cout << s1 << " is less than " << s2 << '\n';
else cout << s2 << " is less than or equal to " << s1 << '\n';
} while (cin >> s1 >> s2);
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.