5.1
(12/3)*4+(5*15)+24%(4/2)==16+75+0=91
5.2
-30*3+21/5=-90+4=-86,不依赖于机器
-30+3*21/5=-30+12=-18,不依赖于机器
30/3*21%5=0,不依赖于机器
-30/3*21%4=-2,依赖于机器
5.3
#include <iostream>
using namespace std;
int main() {
int i;
cin >> i;
if (i%2)
printf("odd number");
else
printf("even number");
return 0;
}
5.4
溢出指的是计算出的数值超出了数据类型能够表示的范围。常见的溢出如下:
// 数组越界
int a[3];
a[4]=1;
// 除0
int a = 2/0;
// 赋值超过范围
unsigned short a = 65536;
5.5
逻辑与,短路求值,如果第一个操作数为true,才计算第二个操作数。
逻辑或,短路求值,如果第一操作数为false,才计算第二个操作数。
相等操作符的操作数,不论什么情况,都需要计算。
5.6
如果指针非空且不是'\0',那么执行循环体,用于遍历字符串。
5.7
#include <iostream>
using namespace std;
int main() {
int a;
while (cin >> a)
if (a == 42)
break;
return 0;
}
5.8
if(a>b && b>c && c>d)
// process code
5.9
ul 0011
ul2 0111
(a) 位运算,与,0011
(b) 逻辑运算,与,true
(c) 位运算,或,0111
(d) 逻辑运算,或,true
5.10
bitset<30> a;
a[3] = 1; // set()
a[3] = 0; // reset()
5.11
d=i=3.5, 则i=3, d=3.0
i = d = 3.5, 则i=3, d=3.5
5.12
第一行编译错误,42是字面值常量,不能赋值
第二行是true,先给变量i赋值42,然后测试i的值,非0表示true。
5.13
pi是指针类型,ival是整型,类型不一致,不能相互赋值。
dval = ival = *pi = 0;
5.14
(a) 赋值操作符的优先级低于比较操作符的优先级,修改为 if((ptr=retrieve_pointer()) != 0)
(b) 赋值操作符,不是比较操作符,赋值操作符,先赋值ival为1024,然后测试ival的值。改为:if(ival==1024)
(c) 赋值操作符的优先级低于 +操作符,先执行ival+1
5.15
前自增操作符,先自增,再返回自增后的值,返回左值,可以被赋值,效率更高。
后自增操作符,先用临时变量保存自增前的值,然后自增,然后返回临时副本,返回的是右值,不能被赋值。
5.16
因为,首先是继承C语言,然后添加了类特性,以及后来的模板、函数式编程等。
5.17
以迭代器的方式遍历,通常会忽略掉vector的第一个元素,而试图访问最后一个元素的下一个位置。
5.18
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string*> a;
a.push_back(new string("C++"));
a.push_back(new string("operator"));
a.push_back(new string("over"));
vector<string*>::iterator iter = a.begin();
while (iter != a.end()) {
printf("%s, %d\n", (*iter)->c_str(), (*iter)->size());
iter++;
}
return 0;
}
5.19
(a) 合法,输出iter指向的string,之后iter指向下一个string
(b) 非法,string对象没有++操作
(c) 非法,iter是迭代器,也就是指针,没有empty成员函数。这是由于解引用操作符的优先级低于点操作符。
(d) 合法,获取iter指向的string是否为空。
(e) 非法,自增运算的优先级高于解引用运算符。
(f) 合法,虽然形式很诡异。
5.20
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
int a, b;
cin >> a >> b;
printf("max=%d, min=%d\n", a>b?a:b, a>b?b:a);
return 0;
}
5.21
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<int> a;
for(size_t i=0; i<5; ++i)
a.push_back(i);
for(auto i=0; i<5; ++i)
a[i] = a[i]%2?2*a[i]:a[i];
for(auto iter=a.begin(); iter!=a.end(); ++iter)
cout << *iter << endl;
return 0;
}
5.22
#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
using namespace std;
int main() {
printf("%s=%d\n", typeid(int).name(), sizeof(int));
printf("%s=%d\n", typeid(float).name(), sizeof(float));
printf("%s=%d\n", typeid(double).name(), sizeof(double));
printf("%s=%d\n", typeid(short).name(), sizeof(short));
printf("%s=%d\n", typeid(bool).name(), sizeof(bool));
printf("%s=%d\n", typeid(short).name(), sizeof(short));
printf("%s=%d\n", typeid(long).name(), sizeof(long));
return 0;
}
5.23
第一个输出是10,也就是数组的长度。x是数组名,不是指针,虽然在数组名当参数进行传递的时候,会转化成指针进行传递。同时数组名也是第一个元素的首地址。
第二个输出1。sizeof(p)=4,sizeof(*p)=4。
5.24
后自减操作,先使用变量的当前值,下一轮loop的时候,使用自减之后的值。
前自减操作,先使变量自减,然后使用变量的值。
本程序,想在ivec[ix]中存储,ix之后的元素个数。而5.5节存储着元素个数是包括当前元素的。
5.25
(a) (!ptr) == (ptr->next)
(b) ch = (buf[bp++]!='\n')
5.26
(a) !(ptr == ptr->next)
(b) (ch=buf[bp++]) != '\n'
5.27
string p1 = s + (s[s.size()-1]=='s'?'':'s')
5.28
我认为不可以接受,这是C++自由性泛滥的表现之一。实现效率和可维护性相比根本不值一提,尤其是C++这种表现能力极强的语言。减少潜在的缺陷应该优于实现效率。
5.29
(a) 判断ptr所指对象的ival是否为0
(b) 先判断jval<kval,其结果判断是否!= ival
(c) &&的优先级最低,先判断ptr是否空指针,然后判断ptr所指向的值是否为0
(d) 先执行ival++,判断ival原始的值,然后判断ival自加后的值
(e) 非法,未定义,C++对于2目运算符,只有&&,||,定义了计算顺序(从左至右),其余的2目运算符都没有定义。该表达式行为未定义。
5.30
(a) 合法,svec初始化10个元素,每个元素都是空字符串(string类型)
(b) 合法,在堆上创建vector,10个元素,元素的类型是string,默认空字符串。
(c) 非法,new 数组,数组元素个数10,每个元素都是一个vector<string>, pvec2应该是 vector<string>类型的指针,而不是指针的指针。
(d) 合法,pv1是vector<string>类型的指针
(e) 合法,pv2也是vector<string>类型的指针
(f) 非法,svec不是指针
(g) 合法
(g) 合法
(i) 非法,pv1指向非动态变量
(j) 合法。
5.31
(a) fval转换为bool类型
(b) ival转换为float类型,相加的结果,转换为double类型
(c) 通通转换为double类型
5.32
(a) 'a'转化为int
(b) ival转化为float,ui转化为float
(c) ui转化为float,结果转化为double
(d) ival先转化为float,相加的结果转化为double,最后的结果转化为char。
5.33
int ival;
double dval;
const string *ps;
char *pc;
void *pv;
pv = static_cast<void *>(const_cast<string*>(ps));
ival = static_cast<int>(*pc);
pv = static_cast<void*>(&dval);
pc = static_cast<char*>(pv);