1.参与取余运算的运算对象必须是整数类型
int ival = 12;
double dval = 3.14;
ival % 12; //正确,结果为6
ival % dval;//错误,ival为int,dval为double
2.如果m%n结果不为0,则m%n的符号和m符号相同
21 % 6;//=3……3,结果为3
21 % 7;//=3……0,结果为0
-21 % -8;//=2……5,结果为-5
21 % -5;//=4……1,结果是1
3.进行比较运算时,除非比较对象是布尔类型,否则不要使用布尔字面值true和false作为运算对象
4.递增和递减运算符的两种形式:前置版本和后置版本
int i = 0, j;
j = ++i;// j = 1,i = 1:前置版本得到递增之后的值
j = i++;// j = 1,i = 2:后置版本得到递增之前的值
建议:除非必须,否则不用递增递减运算符的后置版本
- 前置版本的递增运算符避免了不必要的工作,它把值+1后直接返回改变了的运算对象
- 后置版本需要将原始值存储下来以便于返回这个未修改的内容。如果我们不需要修改前的值,那么后置版本就是一种浪费
建议:养成使用前置版本的习惯
cout << *iter++ << endl;//输出当前值并将iter向前移动一个元素
等价于
cout << *iter << endl;
cout << ++iter << endl;
5.成员访问运算符
箭头运算符作用于一个指针类型的运算对象
string s1 = " a string ", *p = &s1;
auto n = s1.size();//运行string对象s1的size成员
n = (*p).size();//运行p所指对象的size成员
n = p ->size();//等价与(*p).size();
6.位运算符
位运算符作用与整数类型的运算对象并把运算对象看成是二进制位的集合
强烈建议:仅将位运算符用于处理无符号类型
使用左移运算符和一个unsigned long类型的整数字面值1表示学生27通过了测验(第27位为1)
1UL << 27//生成一个值,该值只有第27位为1
位与、位或、位异或运算符
7.sizeof运算符
- 返回一条表达式或一个类型名字所占的字节数
sizeof (type)
- 返回表达式结果类型的大小
sizeof expr
sizeof并不实际计算其运算对象的值
Sales_data data,*p;
sizeof(Sales_data); //存储Sales_data类型的对象所占的空间大小
sizeof data; //data的类型大小,即sizeof(Sales_data)
sizeof p; //指针所占的空间大小
sizeof *p; //p所指类型的空间大小,即sizeof(Sales_data)
sizeof data.revenue;//Sales_data的revenue成员对应类型的大小
C++11新标准允许我们使用==作用域运算符==( : : )来获取类成员的大小
sizeof Sales_data::revenue;//另一种获取revenue大小的方式
sizeof运算符的结果部分地依赖于其作用的类型
对char或者类型为char的表达式执行sizeof运算,结果得1
char a='b';
cout<< sizeof(char)<<endl;
cout<< sizeof(a)<<endl;
Results
对引用类型执行sizeof运算得到被引用对象所占空间的大小
int a=3;
int *b = &a;
cout<< sizeof(b)<<endl;//在64-bit系统中指针b的大小为8 bytes
cout<< sizeof(*b)<<endl;//指针b所指元素3的类型为int,一个int所占空间4 bytes
Result
对指针执行sizeof运算得到指针本身所占空间的大小
int *p=0;//直接将指针p初始化为字面值常量0
cout<< sizeof(p)<<endl;//64-bit系统一个指针占8 bytes
Result
对解引用指针执行sizeof运算得到指针指向的对象所占空间的大小,指针不需要有效
1.
int *p=0;//直接将指针p初始化为字面值常量0
cout<< sizeof(*p)<<endl;//int类型 4 bytes
Result
2.
double *p=0;//直接将指针p初始化为字面值常量0
cout<< sizeof(*p)<<endl;//double类型 8 bytes
Result
对数组执行sizeof运算得到整个数组所占空间的大小,等价于对数组中所有的元素各执行一次sizeof运算并将所得结果求和。注意,sizeof运算不会把数组转换成指针来处理
1.
int a[3]={1,2,3};
cout<< sizeof(a)<<endl;//一个int类型4 bytes,数组内有三个元素,3×4=12
Result
2.
int c=0;
int a[3]={1,2,3};
cout<< sizeof(a)<<endl;//一个int类型4 bytes,数组内有三个元素,3×4=12
//等价于对数组中所有元素各执行一次sizeof运算并将所得结果求和
for (auto b:a)//遍历数组
c+= sizeof(b);//每个元素都是int类型,即sizeof(b)是一个元素的类型大小为4,4+4+4=12
cout<< c<<endl;//c=12
Result
对string对象或vector对象执行sizeof运算只返回该类型固定部分的大小,不会计算对象中的元素占用了多少空间
1.
string s1="Hello";
cout<< sizeof(s1)<<endl;
Result
2.
string s1="HelloWorld";
cout<< sizeof(s1)<<endl;
Result
3.
vector<int> v={5,1};
cout<< sizeof(v)<<endl;
Result
4.
vector<int> v={10,1};
cout<< sizeof(v)<<endl;
Result
命名的强制类型转换
建议:避免强制类型转换
一个命名的强制类型转换具有如下形式:
cast-name< type >(expression)
- type是转换的目标类型
- expression是要转换的值
- cast-name
举例:
例子1:
double slope = static_cast<double>(j) / i;
例子2:
const char *cp;
static_cast<string>(cp);//字符串字面值转换成string类型
例子3:
const char *pc;//常量指针
char *p = const_cast<char*>(pc);//char *p为非常量
例子4:
int *ip;
char *pc = reinterpret_cast<char*>(ip);