每日十问6c+±分支语句和逻辑运算符
1.请看下面两个计算空格和换行符数目的代码片段。//版本 1
while(cin.getch()) //在遇到 EOF 时退出
if(ch =='')
spaces++; if(ch =='\n')
newlines++
/
//版本 2
while(cin.getch()) //在遇到EOF 时退出
if(ch =='9
spaces++;
else if(ch == '\n')
newlines++
\
}
第2个版本比第1个版本好在哪里呢?
解析:
题目中的两种分支语句都能够正确统计空格符和换行符。两者的差异在于版本 1 使用了两次 if 语句,针对所有输入的字符变量 ch,都要进行两次判断,分别判断是否是空格符和是否是换行符;版本2的代码使用 if… else 语句,针对所有输入字符 ch,都首先判断是否是空格符,针对所有非空格符ch再次判断是否是换行符。原理上版本2的执行效率会略高于版本 1。但是对于现代编译器来说,编译器的优化可能会消除这两种版本之间的差异。对于非大规模的分支语句,可以选择更加清晰易懂的语句来实现。
2.在程序清单 6.2 中,用 ch+1 替换++ch 将发生什么情况呢?
解析:
程序清单 6.2 中关于++ch 的代码如下。
while(ch != '.')
{
if(ch =- '\n')
std::cout<<ch;
else
std::cout<<++ch;
std::cin.get(ch);
}
该程序清单的主要功能是将非换行符的 ASCII 字符加 1,例如,若输入的 ch 为字符’A’则输出的++ch 为’B’。通常情况下 C++语言中的++运算符表示变量的递增,但是++操作符和 ch+1的区别在于,对于后者,加法运算符会在左右两侧数据参与运算时进行数据类型的转换。ch 为字符型变量,常量1为 int 类型常量,因此其运算结果会转换为 int 类型,所以会输出 ASCII 字符的十进制整型数值。而++运算符则不会发生这种情况,它仅保证了原变量的递增。输出仍为字符型数据。
3.请认真考虑下面的程序。
#include <iostream>
using namespace std; int main(){
char ch;
int ct1,ct2; ctl=ct2=0;
while((ch = cin.get()) != '$')
cout << ch; ct1++;
if(ch = '$')
ct2++;
cout << ch;
cout<<"ct1 = "<<ctl<<",ct2 = "<<ct2<<"\n"; return 0;
假设输入如下(请在每行末尾按 Enter 键)。食 Hi!
Send $10 or $20 now!则输出将是什么?习题解析:
程序的输出结果如下。
Hi!
H
i
i
i!$
$Send $10 or
20
n
o
w
!
S
20 now! S
20now!Se
n
n
nd$
c
t
1
=
9
,
c
t
2
=
9
在程序中,
i
f
(
c
h
=
′
ct1=9,ct2=9 在程序中,if(ch= '
ct1=9,ct2=9在程序中,if(ch=′‘)语句使用了赋值运算符而不是=-逻辑运算符,因此会造成对于输入的非’
′
运算符都会首先执行
c
t
l
+
+
,随后执行
c
h
=
′
'运算符都会首先执行ctl++,随后执行 ch='
′运算符都会首先执行ctl++,随后执行ch=′‘赋值语句,由于赋值语句右侧的表达式的值总为真,因此总是执行 ct2++。例如,当输入 Hi!时,循环语句块会首先输出 ch(第1次输出的ch为字符’H’),随后ctl++,接着ch被赋值为’
′
,
c
t
2
+
+
,最后输出
c
h
(
第
2
次输出
c
h
时,
c
h
为字
符
′
',ct2++,最后输出ch(第2 次输出 ch 时,ch 为字符'
′,ct2++,最后输出ch(第2次输出ch时,ch为字符′')。然后进入下一次循环。最终形成 H
i
i
i!
的输出结果,且
c
t
1
与
c
t
2
为
3
。重要的是,此时还应该注意空白字符在程序内的处理方式,这里主要是空格符和换行符。由于这两个字符在显示上容易被忽略,但是依然会被重新赋值
为
′
的输出结果,且 ct1与ct2为3。重要的是,此时还应该注意空白字符在程序内的处理方式,这里主要是空格符和换行符。由于这两个字符在显示上容易被忽略,但是依然会被重新赋值为'
的输出结果,且ct1与ct2为3。重要的是,此时还应该注意空白字符在程序内的处理方式,这里主要是空格符和换行符。由于这两个字符在显示上容易被忽略,但是依然会被重新赋值为′‘并显示,因此最终 ctl 和 ct2 同为 9。这一点可以根据回显的’$'字符计算。
4.创建表示下述条件的逻辑表达式。
a. weight 大于或等于 115,但小于 125。
b. ch 为 q 或 Q。
c.x为偶数,但不是 26。
d. x为偶数,但不是 26 的倍数。
e. donation 介于1 000~2 000 或guest 为 1。
f.ch 是小写字母或大写字母(假设小写字母是依次编码的,大写字母也是依次编码的,但在大小写字母间编码不是连续的)。
解析:
a. weight >=115 && weight <125
b. ch == 'q’llch == ‘Q’
c.x%2 == 0 &&x!= 26
d.x%2 == 0 && x%26 !0
e.(donation>=1000 && donation<2000)ll guest ==1
f.(ch>=‘a’ && ch<=‘z’)ll(ch>=‘A’ && ch<=‘Z’)
5.在英语中,"I will not not speak(我不会不说)”的意思与“I will speak(我要说)”相同。在 C++中,!!x是否与x相同呢?
解析:
逻辑运算符“!”表示逻辑非,作用是将其右侧的表达式的值取反,因此其运算结果是 true 或者 false。!!x的运算顺序可以表示为!(!x),即先执行右侧的逻辑非运算,再运算左侧的逻辑非运算。当x是一个布尔值时,!!x的运算结果等于x;当x是其他类型时,则x和!!x在类型上并不相同,运算符会将x转换成合适的布尔类型值之后,再进行逻辑运算。因此,并不能简单认为两次取反(!!)就等于原值。
6.创建一个条件表达式,其值为变量的绝对值。也就是说,如果变量x为正,则表达式的值为x;如果x为负,则表达式的值为-x–这是一个正值。
解析:
首先本题的逻辑规则可以使用if条件语句判断,即x和0的大小关系。如果使用条件表达式,则可以表示如下。
(x<0)?-x:x
或者
(x>=0)?x:-x
7.用switch 改写下面的代码片段。
if(ch == ‘A’)
a_grade++;
else if(ch --‘B’)
b_grade++;
else if(ch --‘c’)
c_grade++;
else if(ch ==‘D’)
d_grade++;
else f_grade++;
解析:
代码中的多重条件语句依次判断输入数据ch分别是’A"B"C"D’的情况,首先字符数据也可以当作整型数据进行比较判断,因此该代码可以改写为 switch 语句。由于 switch 语句在处理多种条件判断上格式更加清晰可读,因此在多重条件语句中应当优先选择使用 switch语句。本题中 switch 语句末尾应当添加 break 语句。完整代码如下。
switch(ch)
{
case ‘A’: a_grade++;
break;
case ‘B’: b grade++?
break;
case ‘C’: c_grade++;
break; :林随配区
case ‘D’: d_grade++;
break;
default: f_grade++;
break;
}
8.对于程序清单 6.10,与使用数字相比,使用字符(如a和 c)表示菜单选项和 case标签有何优点呢?(提示:思考用户输入q和输入5的情况。)
解析:
程序清单 6.10 中相关代码如下。
char choice;
cin>>choice;
while(choice != 5){
switch(choice){
case 1:
cout<<"\a\n"; break;:
default:
cout<<"That's not a choice.\n";
cin>>choice;
由于多重选择语句中标签需要使用整数常量,因此 choice 使用 int 类型或者 char 类型都可以正确编译和执行这些语句,但是用户的输入可以有很多种情况。当 choice 类型为 int 类型时(标签为整型数据),如果用户输入整型数据(阿拉伯数字 09),程序可以正常运行,但是当用户输入字符(AZ等英文字母或者其他特殊符号)时,输入读取语句 cin>>choice;将会产生读取异常,最终导致程序无法处理 switch 分支语句而崩溃。但是如果 choice 是一个字符型变量,所有的键盘输入都可以以 ASCH 字符的形式正确读取(例如,用户输入 5,既可以正确转换为整数5,也可以正确转换为字符’5’),从而保证了 switch 分支语句的正确运行。也就是说,使用字符类型的标签能够在一定程度上提高程序的健壮性。
9.请看下面的代码片段。
int line =0; char ch;
while (cin.get(ch))
if(ch == ‘Q’)
break;
if(ch != ‘\n’)
continue;
line++;
请重写该代码片段,不要使用 break 和 continue 语句。
解析:
首先应当对代码的逻辑关系进行分析,代码首先读取系统标准输入。当输入数据为’Q时,利用 break 语句退出整个循环;如果输入为换行符,则暂停当前循环(即 line不计数)并开始下一次读取。为了避免使用 break 和 continue,可以在循环入口条件中添加退出循环的条件,在循环体内添件计数的判断条件。修改后的代码如下。
int line =0;
char ch;
while (cin.get(ch) && ch != ‘Q’)
{
if(ch ==‘\n’)
line++;
}