c++ primer 第五版第五章
5.01 什么是空语句,什么时候会用到?
空语句只含有一个单独的分号。当循环的全部工作在条件部分就可以完成时,通常就会用到空语句。
5.02 什么是块,什么时候会用到块?
用花括号括起来的语句和声明的序列成为块,一个块就是一个作用域。如循环体内有多条执行语句,就需要用到块,函数也需要用到块。
5.03 使用逗号运算符重写while循环,使他不再需要块,改写之后可读性提高了吗?
while (val <= 10) sum += val, ++val;
可读性并没有提高,用块更易读。
5.04 说明下列例子的含义,如果存在问题,试着修改。
- (a) while (string::iterator iter != s.end()) { /* ... */ }
- (b) while ( bool status = find(word) ) {/* ... */ }
if ( !status ) { /* ... */ }
对于a,iter没有指向,直接判断其不等于s.end()是非法的。
对于b,while执行的条件就是status为真,因此if判断永远不成立。
5.05 写一段自己的程序,使用if else语句实现把数字成绩转化为字母成绩的要求。
void test505()
{
const vector<string> scores = {"F", "D", "C", "B", "A", "A++"};
float grade;
string letterGrade;
while (cin >> grade)
{
if (grade < 60)
{
letterGrade = scores[0];
}
else
{
letterGrade = scores[(grade-50)/10];
}
cout << letterGrade << endl;
}
}
5.06 改写上题程序,使用条件运算符代替if-else语句。
void test506()
{
const vector<string> scores = {"F", "D", "C", "B", "A", "A++"};
float grade;
string letterGrade;
while (cin >> grade)
{
(grade < 60) ? letterGrade = scores[0] : letterGrade = scores[(grade-50)/10];
cout << letterGrade << endl;
}
}
5.07 改正下面代码段中的错误。
-a if (ival1 != ival2)
ival1 = ival2
else ival1 = ival2 = 0; // ival1 = ival2一句丢失了句末分号
-b if (ival < minval)
minval = ival;
occurs = 1; // if语句应该加大括号,否则occurs=1;不会执行。
-c if (int ival = get_value())
cout << "ival = " << ival << endl;
if (!ival)
cout << "ival = 0\n"; // 第二个if中的ival未定义,ival的作用域仅限于第一个if循环中
-d if (ival = 0)
ival = get_value(); // if中的判断应写为 if (0 == ival)
5.08 什么是“悬垂else”?c++语言是如何处理else字句的?
> 当if语句嵌套时,可能会出现if语句的数量大于else语句的情况,这时,我们如何确定给定的else是和哪个if匹配的呢?这个问题就称作悬垂else。
c++中规定,else与离它最近且尚未匹配的if语句匹配。
5.09 编写一段程序,使用if语句统计从cin读入的文本中有多少元音字母。
void test509()
{
int aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
char ch;
while (cin >> ch)
{
if ('a' == ch)
{
++ aCnt;
}
else if ('e' == ch)
{
++ eCnt;
}
else if ('i' == ch)
{
++ iCnt;
}
else if ('o' == ch)
{
++ oCnt;
}
else if ('u' == ch)
{
++ uCnt;
}
}
cout << "Number of vowel a is " << aCnt << "\nNumber of vowel e is " << eCnt
<< "\nNumber of vowel i is " << iCnt << "\nNumber of vowel o is " << oCnt
<< "\nNumber of vowel u is " << uCnt << endl;
}
5.10 上述代码有一个问题,如果是大写字母则不会被统计在内。编写程序,使大写字母和小写字母都能够统计在内。
void test509()
{
int aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
char ch;
while (cin >> ch)
{
if (('a' == ch) || ('A' == ch))
{
++ aCnt;
}
else if (('e' == ch) || 'E' == ch)
{
++ eCnt;
}
else if (('i' == ch) || 'I' == ch)
{
++ iCnt;
}
else if (('o' == ch) || 'O' == ch)
{
++ oCnt;
}
else if (('u' == ch) || 'U' == ch)
{
++ uCnt;
}
}
cout << "Number of vowel a is " << aCnt << "\nNumber of vowel e is " << eCnt
<< "\nNumber of vowel i is " << iCnt << "\nNumber of vowel o is " << oCnt
<< "\nNumber of vowel u is " << uCnt << endl;
}
5.11 修改统计元音字母的程序,使其也能统计空格、制表符和换行符的数量。
while (cin >> noskipws >> ch)
{
if (('a' == ch) || ('A' == ch))
{
++ aCnt;
}
else if (('e' == ch) || 'E' == ch)
{
++ eCnt;
}
else if (('i' == ch) || 'I' == ch)
{
++ iCnt;
}
else if (('o' == ch) || 'O' == ch)
{
++ oCnt;
}
else if (('u' == ch) || 'U' == ch)
{
++ uCnt;
}
else if (' ' == ch)
{
++ spaceCnt;
}
else if ('\t' == ch)
{
++ tabCnt;
}
else if ('\n' == ch)
{
++ newlineCnt;
}
}
cout << "Number of vowel a is " << aCnt << "\nNumber of vowel e is " << eCnt
<< "\nNumber of vowel i is " << iCnt << "\nNumber of vowel o is " << oCnt
<< "\nNumber of vowel u is " << uCnt << endl;
cout << "Number of space is " << spaceCnt << "\nNumber of tab is " << tabCnt
<< "\n Number of line feed is " << newlineCnt << endl;
注意cin要使用noskipws,noskipws会告诉istream读取字符时不要跳过空白符。
5.12 修改统计元音字母的程序,使其能统计以下含有两个字符的字符序列的数量:ff,fl, fi
5.13 下面显示的每个程序都有一个常见的编程错误,指出错误在哪里,然后修改它们。
5.14
5.15 说明下面循环的含义并改正其错误。
-- a
for(int ix = 0; ix != sz; ++ ix) {...}
if (ix != sz) // for循环结束的条件是ix == sz,因此if语句永远不成立。
// ...
-- b
int ix;
for (ix != sz; ++ix) {/* ... */} // 省略了初始化语句必须要有“;”,表示一个空语句。
--c
for (int ix = 0; ix != sz; ++ix; ++ sz) {/* ... */} // ++ix和++sz同时执行,则for会一直循环下去。
5.16
5.17 假设有两个包含整数的vector对象,编写一段程序,检验其中一个vector的对象是否为另一个的前缀。为了实现这一目标,对于两个不等长的vector,只需挑出长度较短的那个,把它的所有元素和另一个vector对象比较即可。例如,两个vector的元素分别是0、1、1、2和0、1、1、2、3、5、8,则程序的返回结果应该为真。
5.18
5.19
5.20