第五章 表达式Word文件下载.docx
- 文档编号:21374280
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:16
- 大小:22.73KB
第五章 表达式Word文件下载.docx
《第五章 表达式Word文件下载.docx》由会员分享,可在线阅读,更多相关《第五章 表达式Word文件下载.docx(16页珍藏版)》请在冰豆网上搜索。
&
*cp)
该while循环的条件为:
当指针cp为非空指针并且cp所指向的字符不为空字符null('
\0'
)
时执行循环体。
即该循环可以对字符串"
中的字符进行逐个处理。
习题5.7
编写while循环条件从标准输入设备读入整型(int)数据,当读入值为42时循
环结束。
intval;
cin>
>
val;
while(val!
=42)
或者,while循环条件也可以写成
while(cin>
ival&
ival!
习题5.8
编写表达式判断4个值a、b、c和d是否满足a大于b、b大于c而且c大于d
的条件。
表达式如下:
a>
b&
b>
c&
c>
d
习题5.9
假设有下面两个定义:
93
unsignedlongul1=3,ul2=7;
下列表达式的结果是什么?
(a)ul1&
ul2(b)ul1&
ul2
(c)ul1|ul2(d)ul1||ul2
各表达式的结果分别为3、true、7、true。
习题5.10
重写bitset表达式:
使用下标操作符对测验结果进行置位(置1)和复位(置
0)。
bitset<
30>
bitset_quiz1;
bitset_quiz1[27]=1;
bitset_quiz1[27]=0;
习题5.11
请问每次赋值操作完成后,i和d的值分别是多少?
inti;
doubled;
d=i=3.5;
i=d=3.5;
赋值语句d=i=3.5;
完成后,i和d的值均为3。
因为赋值操作具有右结合性,所以首先
将3.5赋给i(此时发生隐式类型转换,将double型字面值3.5转换为int型值3,赋给i),
然后将表达式i=3.5的值(即赋值后i所具有的值3)赋给d。
赋值语句i=d=3.5;
完成后,d的值为3.5,i的值为3。
因为先将字面值3.5赋给d,然后
将表达式d=3.5的值(即赋值后d所具有的值3.5)赋给i(这时也同样发生隐式类型转换)。
习题5.12
解释每个if条件判断产生什么结果?
94
if(42=i)//...
if(i=42)//...
前者发生语法错误,因为其条件表达式42=i是一个赋值表达式,赋值操作符的左操作数必
须为一个左值,而字面值42不能作为左值使用。
后者代码合法,但其条件表达式i=42是一个永真式(即其逻辑值在任何情况下都为true),
因为该赋值表达式的值为赋值操作完成后的i值(42),而42为非零值,解释为逻辑值true。
习题5.13
下列赋值操作是不合法的,为什么?
怎样改正?
doubledval;
intival;
int*pi;
dval=ival=pi=0;
该赋值语句不合法,因为该语句首先将0值赋给pi,然后将pi的值赋给ival,再将ival的
值赋给dval。
pi、ival和dval的类型各不相同,因此要完成赋值必须进行隐式类型转换,
但系统无法将int型指针pi的值隐式转换为ival所需的int型值。
可改正如下:
dval=ival=0;
pi=0;
习题5.14
虽然下列表达式都是合法的,但并不是程序员期望的操作,为什么?
怎样修改这些表
达式以使其能反映程序员的意图?
(a)if(ptr=retrieve_pointer()!
=0)
(b)if(ival=1024)
(c)ival+=ival+1;
对于表达式(a),程序员的意图应该是将retrieve_pointer()的值赋给ptr,然后判断ptr
95
的值是否为0,但因为操作符“=”的优先级比“!
=”低,所以该表达式实际上是将
retrieve_pointer()是否为0的判断结果true或false赋给ptr,因此不是程序员期望的操作。
对于表达式(b),程序员的意图应该是判断ival的值是否与1024相等,但误用了赋值操
作符。
对于表达式(c),程序员的意图应该是使ival的值增加1,但误用了操作符“+=”。
各表达式可修改如下:
(a)if((ptr=retrieve_pointer())!
(b)if(ival==1024)
(c)ival+=1;
或ival++;
或++ival;
习题5.15
解释前自增操作和后自增操作的差别。
前自增操作和后自增操作都使其操作数加1,二者的差别在于:
前自增操作将修改后操作数
的值作为表达式的结果值;
而后自增操作将操作数原来的、未修改的值作为表达式的结果
值。
习题5.16
你认为为什么C++不叫作++C?
C++之名是RickMascitti在1983年夏天定名的(参见TheC++Programming
Language(SpecialEdition)1.4节),C说明它本质上是从C语言演化而来的,“++”是C语言
的自增操作符。
C++语言是C语言的超集,是在C语言基础上进行的扩展(引入了new、
delete等C语言中没有的操作符,增加了对面向对象程序设计的直接支持,等等),是先有
C语言,再进行++。
根据自增操作符前、后置形式的差别(参见习题5.15的解答),C++
表示对C语言进行扩展之后,还可以使用C语言的内容;
而写成++C则表示无法再使用C
的原始值了,也就是说C++不能向下兼容C了,这与实际情况不符。
习题5.17
如果输出vector内容的while循环使用前自增操作符,那会怎么样?
将导致错误的结果:
ivec的第一个元素没有输出,并企图对一个多余的元素进行解引用。
96
习题5.18
编写程序定义一个vector对象,其每个元素都是指向string类型的指针,读
取该vector对象,输出每个string的内容及其相应的长度。
//定义一个vector对象,其每个元素都是指向string类型的指针,
//读取该vector对象,输出每个string的内容及其相应的长度
#include<
iostream>
string>
vector>
usingnamespacestd;
intmain()
{
vector<
string*>
spvec;
//读取vector对象
stringstr;
cout<
<
"
Entersomestrings(Ctrl+Ztoend)"
<
endl;
str){
string*pstr=newstring;
//指向string对象的指针
*pstr=str;
spvec.push_back(pstr);
}
//输出每个string的内容及其相应的长度
:
iteratoriter=spvec.begin();
while(iter!
=spvec.end()){
97
**iter<
(**iter).size()<
iter++;
//释放各个动态分配的string对象
iter=spvec.begin();
delete*iter;
return0;
习题5.19
假设iter为vector<
iterator类型的变量,指出下面哪些表达式是
合法的,并解释这些合法表达式的行为。
(a)*iter++;
(b)(*iter)++;
(c)*iter.empty();
(d)iter->
empty();
(e)++*iter;
(f)iter++->
(a)、(d)、(f)合法。
这些表达式的执行结果如下:
(a)返回iter所指向的string对象,并使iter加1。
(d)调用iter所指向的string对象的成员函数empty。
(f)调用iter所指向的string对象的成员函数empty,并使iter加1。
习题5.20
98
编写程序提示用户输入两个数,然后报告哪个数比较小。
可编写程序如下:
//提示用户输入两个数,然后报告哪个数比较小
intval1,val2;
//提示用户输入两个数并接受输入
Entertwointegers:
"
val1>
val2;
//报告哪个数比较小
Thesmalleroneis"
(val1<
val2?
val1:
val2)<
习题5.21
编写程序处理vector<
int>
对象的元素:
将每个奇数值元素用该值的两倍替换。
//处理vector<
//将每个奇数值元素用该值的两倍替换
99
ivec(20,1);
//ivec包含20个值为1的元素
for(vector<
iteratoriter=ivec.begin();
iter!
=ivec.end();
++iter)
*iter=(*iter%2==0?
*iter:
*iter*2);
习题5.22
编写程序输出每种内置类型的长度。
//输出每种内置类型的长度
type\t\t\t"
size"
endl
bool\t\t\t"
sizeof(bool)<
char\t\t\t"
sizeof(char)<
signedchar\t\t"
sizeof(signedchar)<
unsignedchar\t\t"
sizeof(unsignedchar)<
wchar_t\t\t\t"
sizeof(wchar_t)<
100
short\t\t\t"
sizeof(short)<
signedshort\t\t"
sizeof(signedshort)<
unsignedshort\t\t"
sizeof(unsignedshort)<
int\t\t\t"
sizeof(int)<
signedint\t\t"
sizeof(signedint)<
unsigendint\t\t"
sizeof(unsignedint)<
long\t\t\t"
sizeof(long)<
sigendlong\t\t"
sizeof(signedlong)<
unsignedlong\t\t"
sizeof(unsignedlong)<
float\t\t\t"
sizeof(float)<
double\t\t\t"
sizeof(double)<
longdouble\t\t"
sizeof(longdouble)<
习题5.23
预测下列程序的输出,并解释你的理由。
然后运行该程序,输出的结果和你预
测的一样吗?
如果不一样,为什么?
intx[10];
int*p=x;
sizeof(x)/sizeof(*x)<
sizeof(p)/sizeof(*p)<
在表达式sizeof(x)中,x是数组名,该表达式的结果为数组x所占据的存储空
间的字节数,为10个int型元素所占据的字节数。
表达式sizeof(*x)的结果是指针常量x所指向的对象(数组中第一个int型元
素)所占据的存储空间的字节数。
101
表达式sizeof(p)的结果是指针变量p所占据的存储空间的字节数。
表达式sizeof(*p)的结果是指针变量p所指向的对象(一个int型数据)所占
据的存储空间的字节数。
各种数据类型在不同的系统中所占据的字节数不一定相同,因此在不同的系统
中运行上述程序段得到的结果不一定相同。
在MicrosoftVisualC++.NET2003
系统中,一个int型数据占据4个字节,一个指针型数据也占据4个字节,因
此运行上述程序得到的输出结果为:
10
1
习题5.24
本节的程序与5.5节在vector对象中添加元素的程序类似。
两段程序都使用递
减的计数器生成元素的值。
本程序中,我们使用了前自减操作,而5.5节的程
序则使用了后自减操作。
解释为什么一段程序中使用前自减操作而在另一段程
序中使用后自减操作。
5.5节的程序中必须使用后自减操作。
如果使用前自减操作,则是用减1后的
cnt值创建ivec的新元素,添加到ivec中的元素将不是10~1,而是9~0。
本节的程序中使用后自减操作或前自减操作均可,因为对cnt的自减操作和对
cnt值的使用不是出现在同一表达式中,cnt自减操作的前置或后置形式不影响
对cnt值的使用。
习题5.25
根据表5-4的内容,在下列表达式中添加圆括号说明其操作数分组的顺序(即
计算顺序):
(a)!
ptr==ptr->
next
(b)ch=buf[bp++]!
='
\n'
添加圆括号说明其计算顺序如下:
(a)((!
ptr)==(ptr->
next))
(b)(ch=((buf[(bp++)])!
))
102
习题5.26
习题5.25中的表达式的计算次序与你的意图不同,给它们加上圆括号使其以你
所希望的操作次序求解。
添加圆括号获得与上题不同的操作次序如下:
(ptr==ptr->
next)
(b)(ch=buf[bp++])!
习题5.27
由于操作符优先级的问题,下列表达式编译失败。
请参照表5-4解释原因,应
该如何改正?
strings="
word"
;
//addan'
s'
totheend,iftheworddoesn'
talreadyendin'
stringpl=s+s[s.size()-1]=='
?
:
s"
由表5-4可知,在语句stringpl=s+s[s.size()-1]=='
中,赋值、加法、条件操作符三者的操作次序为:
先执行“+”操作,再用表达
式s+s[s.size()-1]的结果参与条件操作,最后将条件操作的结果赋给pl。
但表达式s+s[s.size()-1]的结果是一个string对象,不能与字符'
进行
相等比较,所以编译失败。
改正为:
stringpl=s+(s[s.size()-1]=='
);
。
习题5.28
除了逻辑与和逻辑或外,C++没有明确定义二元操作符的求解次序,编译器可自
由地提供最佳的实现方式。
只能在“实现效率”和程序语言使用中“潜在的缺
陷”之间寻求平衡。
你认为这可以接受吗?
说出你的理由。
这可以接受。
因为,操作数的求解次序通常对结果没什么影响。
只有当二元操作符的两个操
作数涉及同一对象,并改变该对象的值时,操作数的求解次序才会影响计算结
103
果;
后一种情况只会在部分(甚至是少数)程序中出现。
在实际使用中,这种
“潜在的缺陷”可以通过程序员的努力得到弥补,但“实现效率”的提高却能
使所有使用该编译器的程序受益,因此利大于弊。
习题5.29
假设ptr指向类类型对象,该类拥有一个名为ival的int型数据成员,vec是
保存int型元素的vector对象,而ival、jval和kval都是int型变量。
请解
释下列表达式的行为,并指出哪些(如果有的话)可能是不正确的,为什么?
如何改正?
(a)ptr->
ival!
=0(b)ival!
=jval<
kval
(c)ptr!
=0&
*ptr++(d)ival++&
ival
(e)vec[ival++]<
=vec[ival]
表达式的行为如下:
(a)判断ptr所指向的对象的ival成员是否不等于0。
(b)判断ival是否不等于“jval是否小于kval”的判断结果,即判断ival是
否不等于true
(1)或false(0)。
(c)判断ptr是否不等于0。
如果ptr不等于0,则求解&
操作的右操作数,即,
ptr加1,且判断ptr原来所指向的对象是否为0。
(d)判断ival及ival+1是否为true(非0值)(注意,如果ival为false,
则无需继续判断ival+1)。
(e)判断vec[ival]是否小于或等于vec[ival+1]。
其中,(d)和(e)可能不正确,因为二元操作符的两个操作数涉及同一对象,并
改变该对象的值。
(d)ival&
ival+1
(e)vec[ival]<
=vec[ival+1]
习题5.30
下列语句哪些(如果有的话)是非法的或错误的?
104
(a)vector<
svec(10);
(b)vector<
*pvec1=newvector<
(10);
(c)vector<
**pvec2=newvector<
[10];
(d)vector<
*pv1=&
svec;
(e)vector<
*pv2=pvec1;
(f)deletesvec;
(g)deletepvec1;
(h)delete[]pvec2;
(i)deletepv1;
(j)deletepv2;
错误的有(c)和(f)。
(c)的错误在于:
pvec2是指向元素类型为string的vector对象的指针的指
针(即pvec2的类型为vector<
**),而new操作返回的是一个指向元
素类型为string的vector对象的指针,不能用于初始化pvec2。
(f)的错误在于:
svec是一个vector对象,不是指针,不能对它进行delete操
作。
习题5.31
根据5.12.2节的变量定义,解释在计算下列表达式的过程中发生了什么类
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第五章 表达式 第五