c++ Primer 第四章:表达式 练习答案记录
下面练习程序别忘记开头都加上这一语句
#include<iostream>
4.1节 基础
练习4.1 表达式5+10*20/2的求值结果是多少
using namespace std;
int main()
{
int a = 5 + 10 * 20 / 2;
cout << a << endl;
}
练习4.2 根据4.12节中的表,在下述表达式的合理位置添加括号,使得添加括号后运算对象的组合顺序与添加括号前一致
using namespace std;
int main()
{
string vec;
(*(vec.begin()));
(*(vec.begin()) + 1);
}
练习4.3 c++语言没有明确规定大多数二元运算符的求值顺序,给编译器优化留下了余地。这种策略实际上是代码生成效率和程序潜在缺陷之间进行了权衡,你认为这可以接受吗?请说出你的利用
可以,因为这样会使得c++运行时候代码的效率更快,而编译者应该尽量避免产生程序的潜在缺陷
4.2节 算术运算符
练习4.4 在下面的表达式中添加括号,说明其求值的过程及最终结果。编写程序编译该(不加括号)的表达式并输出其结果验证之前的推断
using namespace std;
int main()
{
int a = 12 / 3 * 4 + 5 * 15 + 24 % 4 / 2;
int b = ((12 / 3) * 4) + (5 * 15) + ((24 % 4) / 2);
cout << a << " " << b << endl;
}
练习4.5 写成下列表达式的求值结果
using namespace std;
int main()
{
int a = -30 * 3 + 21 / 5;
int b = -30 + 3 * 21 / 5;
int c = 30 / 3 * 21 % 5;
int d = -30 / 3 * 21 % 4;
cout << a << " " << b << " " << c << " " << d;
}
练习4.6 写成一条表达式用于确定一个整数是奇数还是偶数
using namespace std;
int main()
{
int a;
cout << "请输入一个整数,我将判断是奇数还是偶数" << endl;
while (cin >> a) {
if (a % 2 == 0) {
cout << "偶数" << endl;
}
else {
cout << "奇数" << endl;
}
}
}
练习4.7 溢出是何含义?写出三条将导致溢出的表达式
using namespace std;
int main()
{
int a = 2147483647;
a++;
cout << a << endl;
short b = 32767;
b++;
cout << b << endl;
}
4.3 逻辑和关系运算符
练习4.8 说明在逻辑与、逻辑或及相关性运算符中运算对象求值的顺序
逻辑与,先判断左边表达式是否为真,否输出false;若为真则判断右边表达式是否为真,真输出true,否输出false 逻辑或,先判断左边表达式是否为真,若为否则判断右边表达式是否为真,真输出true,否输出false;若为真直接输出true 相关性运算符先返回左边比较的结果,再将这个结果与右边表达式比较
练习4.9 解释在下面的if语句中条件部分的判断过程
using namespace std;
int main()
{
const char* cp = "Hello World";
if (cp && *cp);
}
练习4.10 为while循环写一个条件,使其从标准输入中读取整数,遇到42时停止
using namespace std;
int main()
{
int i = 0;
while (cin >> i && i != 42);
}
练习4.11 书写一条表达式用于测试四个值a、b、c、d的关系,确保a大于b,b大于c,c大于d
using namespace std;
int main()
{
int a, b, c, d;
if (a > b && b > c && c > d);
}
练习4.12 假设i、j、k是三个整数,说明表达式i!=j<k的含义
首先判断i是否等于j,若等于,则判断k是否大于0,若不等于,则判断k是否大于1
4.4 赋值运算符
练习4.13 在下述语句中,当赋值完成后i和d的值分别是多少?
using namespace std;
int main()
{
int i;
double d;
d = i = 3.5;
i = d = 3.5;
}
练习4.14 执行下述if语句后将发生什么情况?
int main()
{
if (42 = i);
if (i = 42);
}
练习4.15 下面的赋值是非法的,为什么?应该如何修改?
int main()
{
double dval;
int ival;
int* pi;
dval = ival = pi = 0;
}
练习4.16 尽管下面的语句合法,但它们实际执行的行为可能和预期并不一样,为什么?应该如果修改?
int main()
{
if (p = getptr() != 0);
if (i = 1024);
}
4.5 递增和递减运算符
练习4.17 说明前置运算符和后置运算符的区别
前置运算符是对变量本身进行加,后置运算符将对象原始值的副本作为右值返回
练习4.18 如果第132页那个输出vector对象元素的while循环使用前置递增运算符将得到什么结果?
第一次循环则解引用第二个地址;最后一次循环,则解引用vector最后一个地址的后一个位置
练习4.19 假设ptr的类型是指向int的指针,vec的类型是vector、ival的类型是int,说明下面表达式是何含义?
如果表达式不正确,为什么?应该如何修改?
#include<vector>
using namespace std;
int main()
{
int* ptr;
vector<int> vec;
int ival;
ptr != 0 && *ptr++;
ival++&& ival;
vec[ival++] <= vec[ival];
}
4.6 成员访问运算符
练习4.20 假设iter的类型是vector::iterator,说明下面的表达式是否合法。如果合法,表达式的含义是什么?如果不合法错在何处?
#include<vector>
#include<string>
using namespace std;
int main()
{
vector<string>::iterator iter;
*iter++;
(*iter)++;
*iter.empty();
iter->empty();
++* iter;
iter++->empty();
}
4.7 条件运算符
练习4.21 编写一段程序,使用条件运算符从vector中找到哪些元素的值是奇数,然后将这些奇数值翻倍
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> a={1,2,3,4};
vector<int> b;
for (int i = 0; i < 4; i++) {
b.push_back((a[i] % 2 != 0) ? (2 * a[i]) : a[i]);
cout << b[i] << endl;
}
}
练习4.22 本节的示例程序将成绩划分成high pass、pass和fail三种,扩展该程序使其进一步将60分到75分之间的成绩设置为low pass。
要求程序包含两个版本:一个版本只使用条件运算符;另一个版本使用1个或多个if语句。哪个版本的程序更容易理解呢?为什么?
#include<string>
#include<vector>
using namespace std;
int main()
{
int socres;
cout << "请输入所得分数:" << endl;
cin >> socres;
string a = ((socres < 60) ? "fail" : (socres <= 75) ? "loe pass" : (socres <= 90) ? "pass" : "high pass");
cout << a << endl;
cout << "请输入所得分数:" << endl;
cin >> socres;
if (socres < 60) {
cout << "fail" << endl;
}
else if (socres <= 75) {
cout << "low pass" << endl;
}
else if (socres < 90) {
cout << "pass" << endl;
}
else {
cout << "high pass" << endl;
}
}
练习4.23 因为运算符的优先级问题,下面这条表达式无法通过编译。根据4.12节中的表(第147页)指出它的问题在哪里?应该如何修改?
#include<vector>
#include<string>
using namespace std;
int main()
{
string s = "word";
string p1 = s + ((s[s.size() - 1] == 's') ? "" : "s");
}
练习4.24 本节的示例程序将成绩划分成high pass、pass和fail,它的依据是条件运算符满足右结合律。
假如条件运算符满足的是左结合律,求值过程将会是怎么样的?
那就比如string a = ((socres < 60) ? “fail” :(socres <= 75) ? “loe pass” : (socres <= 90) ? “pass” : “high pass”); 改成string a = ((socres >90) ? “fail” : (socres >75) ? “loe pass” :(socres >60) ? “pass” : “high pass”);
4.8 位运算符
对于符号位如何处理没有明确的规定,所以强烈建议仅将位运算符用于处理无符号类型
练习4.25 如果一台机器int占32位、char占8位,用的是Latin-1字符串,其中’q‘的二进制形式是01110001,那么表达式~‘q’<<6的值是什么?
首先对q取反则是10001110,再向左移6位,则为10000000,是2的7次方=128
练习4.26 在本节关于测验成绩的例子中,如果使用unsigned int作为quiz1的类型会发生什么情况?
超过16位的同学,就算通过了测验也是0,会出现位数不够的情况
/练习4.27 下列表达式的结果是什么?
#include<string>
#include<vector>
using namespace std;
int main()
{
unsigned long u11 = 3, u12 = 7;
int a = u11 & u12;
int b = u11 | u12;
int c = u11 && u12;
int d = u11 || u12;
cout << a << " " << b << " " << c << " " << d << endl;
}
4.9 sizeof运算符
|