cppPrimer第五章习题

5.1 什么是空语句?何时会用到空语句?

空语句中只含有一个单独的分号,如果在程序的某个地方,语法上需要一条语句(如while和for),但逻辑上不需要,此时应该使用空语句。

5.2 什么是块,什么时候会用到块

复合语句是指用花括号括起来的(可能为空的)语句和声明的序列复合语句也被称为块一个块就是一个作用域。

语法上需要一条语句,但是逻辑上需要多条语句,则应该使用复合语句(块)。

5.3 使用逗号运算符重写1.4.1节的while循环,使它不再需要块,观察改写后的代码的可读性提高了还是降低了
while(val <= 10)
    sum += val, ++val;

可读性降低了,虽然逗号运算符规定了求值顺序,但是如果在表达式改变了某个运算对象的值,在表达式的其他地方不要再使用这个运算对象。这里出现了val和++val,故不好

5.4 说明下列例子含义,如果存在问题,试着修改它
while(string::iterator iter != s.end()){} //a
while(bool status = find(word)){} //b
	if(!status){}

a代码想要判断迭代器是否指向s尾后,但iter没有初始化

b代码想要在if中使用status,但status只在while语句中有效。

代码应修改为

string::iterator iter = s.begin();
while(iter != s.end()){} //a
while(bool status = find(word))
{
    if(!status){}
} //b
	
5.7 改正下列代码段中的错误
(a)if(ival1 != ival2)
    ival = ival2	//缺少分号
   else ival1 = ival2;

(b)if(ival < minval)
    	minval = ival; // if语句只能控制一条语句,需加花括号将两条语句并为一个块
		occurs = 1;
(c)if(int ival = get_value())
    	cout<<"ival = "<< ival << endl;
	if(!ival)  //ival作用域只在上一个if语句中,ival需要在if语句外声明
        cout<<"ival = 0\n";
(d)if(ival = 0)//if语句条件表达式恒为false,故statement永不执行
    	ival = get_value();

改正后的代码:

(a)if(ival1 != ival2)
    ival = ival2;	//缺少分号
   else ival1 = ival2;

(b)if(ival < minval)
	{
     minval = ival; // if语句只能控制一条语句,需加花括号将两条语句并为一个块
	 occurs = 1;
	}	

(c)int ival = get_value();
	if(ival)
    	cout<<"ival = "<< ival << endl;
	if(!ival)  //ival作用域只在上一个if语句中,ival需要在if语句外声明
        cout<<"ival = 0\n";
(d)if(ival == 0)//if语句条件表达式恒为false,故statement永不执行
    	ival = get_value();
5.8 什么是悬垂else?C++如何处理else子句的?

当一个if语句嵌套在另一个if语句内时,很可能if分支会多于else分支,我们怎么知道某个给定else和哪个if匹配即为悬垂else。

C++规定else与离它最近的尚未匹配的if匹配。

5.11 修改统计元音字母的程序,使其也能统计空格、制表符和换行符的数量
unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, ffCnt = 0, flCnt = 0, fiCnt = 0;
char ch;
while (cin >> ch)
{
    switch (ch)
    {
        case 'a':
        case 'A':
            ++aCnt;
            break;
        case 'e':
        case 'E':
            ++eCnt;
            break;
        case 'i':
        case 'I':
            ++iCnt;
            break;
        case 'o':
        case 'O':
            ++oCnt;
            break;
        case 'u':
        case 'U':
            ++uCnt;
            break;
        case 'f':
            {
                cin >> ch;
                switch (ch)
                {
                    case 'f':
                        ++ffCnt;
                        break;
                    case 'l':
                        ++flCnt;
                        break;
                    case 'i':
                        ++fiCnt;
                        break;
                    default:
                        break;
                }
            }
            break;
        default:
            break;	
    }
}
cout << "Number of vowel a: " << aCnt << endl;
cout << "Number of vowel e: " << eCnt << endl;
cout << "Number of vowel i: " << iCnt << endl;
cout << "Number of vowel o: " << oCnt << endl;
cout << "Number of vowel u: " << uCnt << endl;
cout << "Number of ff: " << ffCnt << endl;
cout << "Number of fl: " << flCnt << endl;
cout << "Number of fi: " << fiCnt << endl;

5.13 下面显示的每个程序都有一个常见的编程错误,指出错误在哪里,然后修改它们。
(a)unsigned aCnt = 0, eCnt = 0, iouCnt = 0;
char ch = next_text();
switch(ch){
    //与分支'a','e' 以及default 所执行的语句结尾没有break,会导致
    //ch与'a'分支匹配时,aCnt,eCnt以及iouCnt都递增
    case 'a' : aCnt++;
    case 'e' : eCnt++;
    default:iouCnt++;
}

(b)unsigned index = some_value();
switch(index){
    case 1:
        int ix = get_line(); //在没有{}包起的分支中,定义并初始化变量会被控制流略过,故错误
        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: //错误,case标签只能是整型 常量表达式
        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: //错误,case 标签只能是整型常量表达式,而这里是无符号整型变量
        bufsize = ival * sizeof(int);
        break;
    case jval:
        bufsize = jval * sizeof(int);
        break;
    case kval:
        bufsize = kval * sizeof(int);
}

修改后的代码:

(a)unsigned aCnt = 0, eCnt = 0, iouCnt = 0;
char ch = next_text();
switch(ch){
    //与分支'a','e' 以及default 所执行的语句结尾没有break,会导致
    //ch与'a'分支匹配时,aCnt,eCnt以及iouCnt都递增
    case 'a' : aCnt++;break;
    case 'e' : eCnt++;break;
    case 'i': case 'o' : case 'u' :iouCnt++;break;
}

(b)unsigned index = some_value();
int ix;
switch(index){
    case 1:
        {
            ix = get_line(); 
       	 	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标签只能是整型 常量表达式
    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: //错误,case 标签只能是整型常量表达式,而这里是无符号整型变量
        bufsize = ival * sizeof(int);
        break;
    case jval:
        bufsize = jval * sizeof(int);
        break;
    case kval:
        bufsize = kval * sizeof(int);
}
5.14 编写一段程序,从标准输入中读取若干string对象并查找连续重复出现的单词。所谓连续重复出现的意思是:一个单词后面紧跟着这个单词本身。要求记录连续重复出现的最大次数以及对应的单词。如果这样的单词存在,输出重复出现的最大次数,如果不存在,输出一条信息说明任何单词都没有连续出现过。如输入为: how now now now brown cow cow,那么输出应该表明now连续出现了3次。
//思路:记录前一次输入的单词。
string word, preword, wordMax;
int cnt = 0, cntMax = 0;
while (cin >> word)
{
    if (preword == word)
        ++cnt;
    else
    {
        if (cnt > cntMax)
        {
            wordMax = preword;
            cntMax = cnt;
        }
        cnt = 1;
    }

    preword = word;
}

if (cntMax > 1)
    cout << wordMax << " occurs " << cntMax << " times!" << endl;
5.15 说明下列循环的含义并改正其中错误
(a)
for(int ix = 0;ix != sz;++ix){/*....*/}
if(ix != sz)//ix生命周期在for语句结束后就消失
    //....
(b)
int ix;
for(ix != sz;++ix){}//for语句头必须由三个部分构成,init-statement,condition,expression,可以不写但必须用分号隔开
(c)
for(int ix = 0;ix != sz;++ix,++sz){}

修改后:

(a)
int ix;
for(ix = 0;ix != sz;++ix){/*....*/}
if(ix != sz)//ix生命周期在for语句结束后就消失
    //....
(b)
int ix;
for(;ix != sz;++ix){}//for语句头必须由三个部分构成,init-statement,condition,expression,可以不写但必须用分号隔开
(c)
for(int ix = 0;ix != sz;++ix){}
5.16 while循环特别使用于那种条件保持不变,反复执行操作的情况,例如,当文件未达到文件末尾时不断读取下一个值。for循环则更像是按步骤迭代,它的索引值在某个范围内依次变化。根据每种循环的习惯用法各自编写一段程序,然后分别用另一种循环改写。如果只能使用一种循环,你更倾向于使用那种呢?
//while
void p5_16_1()
{
	vector<string> svec{ "hello", "world", "Cpp", "is","hard", "to", "learn" };
	vector<string>::iterator it = svec.begin();
	while (it != svec.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}
//for
void p5_16_2()
{
	vector<string> svec{ "hello", "world", "Cpp", "is","hard", "to", "learn" };
	for(vector<string>::iterator it = svec.begin();it != svec.end();++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}

我更倾向于for,因为for结构清晰,便于理解。

5.18 说明下列循环含义并改正其错误
(a) //do只能控制一条语句,若要控制多条语句需用括号构成一个块。
do
    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());//变量定义不可以放在do的条件部分
(c)
do{
    int ival = get response();
}while(ival);//do条件部分的变量必须定义在循环体外

改正后:

(a) //do只能控制一条语句,若要控制多条语句需用括号构成一个块。
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 = get_response();
do{
    //..
}while(ival = get_response());//变量定义不可以放在do的条件部分
(c)
int ival;
do{
    ival = get response();
}while(ival);//do条件部分的变量必须定义在循环体外
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值