算术运算符(左结合律)
运算符 | 功能 | 用法 | 例子 |
---|---|---|---|
+ | 一元正号 | + expr | +1=1 |
- | 一元负号 | - expr | -1=-1 |
* | 乘法 | expr * expr | 4*4=16 |
/ | 除法 | expr / expr | 9/3=3 |
% | 求余(取模) | expr % expr | 5%2=1 |
+ | 加法 | expr + expr | 3+3=6 |
- | 减法 | expr - expr | 10-2=8 |
逻辑和关系运算符
结合律 | 运算符 | 功能 | 用法 | 例子 |
---|---|---|---|---|
右 | ! | 逻辑非 | !expr | |
左 | < | 小于 | expr < expr | |
左 | <= | 小于等于 | expr <= expr | |
左 | > | 大于 | expr > expr | |
左 | >= | 大于等于 | expr >= expr | |
左 | == | 相等 | expr == expr | |
左 | != | 不相等 | expr != expr | |
左 | && | 逻辑与 | expr && expr | |
左 | || | 逻辑或 | expr || expr |
赋值运算符和复合赋值运算符
递增和递减运算符
递增运算符(++
)和递减运算符(--
)为对象的加1和减1 操作
提供了一种简洁的书写形式。这两个运算符还可应用于迭代器,因为很多迭代器本身不支持算术运算,所以此时递增和递减运算符除了书写简洁外还是必须的。
递增和递减运算符有两种形式:前置版本和后置版本。前置版本的运算符首先将运算对象加1(或减1),然后将改变后的对象作为求值结果。后置版本也会将运算对象加1(或减1),但是求值结果是运算对象改变之前那个值的副本:
int i=0,j;
j=++i; //j=1,i=1:前置版本:j得到i递增之后的值
j=i++; //j=1,i=2:后置版本:j得到i递增之前的值
递增和递减运算符都必须作用于左值运算对象。前置版本将对象本身作为左值返回,后置版本则将对象原始值的副本作为右值返回。
建议:除非必要,否则不用递增递减运算符的后置版本。原因:前置版本的递增运算符在把值加1后直接返回改变了的运算对象。与之相比,后置版本需要将原始值存储下来以便于返回这个未修改的内容。如果我们不需要修改前的值,那么后置版本的操作就是一种浪费。
解引用与取地址运算符
成员访问运算符
点运算符(.
)和箭头运算符(->
)都可以用于访问类(结构)的成员,其中,点运算符获取类对象的一个成员;箭头运算符作用于一个指针类型的运算对象,其与点运算符有关,表达式:pointor->member
等价于(*pointor).member
(pointor是一个指针变量)。
string s="I'm a string!",*p=&s;
int n=s.size(); //运算string对象s的size成员
n=(*p).size(); //运行string类型指针p所指对象的size成员
n=p->size(); //等价于(*p).size()
因为解引用运算符*
的优先级低于点运算符.
,所以执行解引用运算的子表达式两端必须加上括号()
。如果没加括号,代码的含义会大不相同:
//运行p的size成员,然后解引用size的结果,
//但由于p是一个指针,它是没有名为size的
//成员的,故此语句会无法通过编译而出错。
*p.size();
条件运算符
位运算符(左结合律)
运算符 | 功能 | 用法 | 例子 |
---|---|---|---|
~ | 位求反 | ~expr | |
<< | 左移 | expr1 << expr2 | |
>> | 右移 | expr1 >> expr2 | |
& | 位与 | expr1 & expr2 | |
^ | 位异或 | expr1 ^ expr2 | |
| | 位或 | expr1 | expr2 |
移位运算符(<<运算符和>>运算符
)的内置含义是对其运算对象执行基于二进制位的移动操作,首先令左侧运算对象的内容按照右侧运算对象的要求移动指定位数,然后将经过移动的左侧运算对象的拷贝作为求值结果。其中,右侧的运算对象一定不能为负,而且值必须严格小于结果的位数,否则就会产生未定义的行为。左移运算符(<<
)在右侧插入值为0的二进制位。右移运算符(>>
)的行为则依赖于其左侧运算对象的类型:如果该运算对象是无符号类型,在左侧插入值为0的二进制位;如果该运算对象是带有符号类型,在左侧插入符号位的副本或值为0的二进制位,如何选择要视具体环境而定。
位求反运算符(~
)将运算对象逐位求反后生成一个新值,将1置为0、将0置为1。
位与(&
)、位或(|
)、位异或(^
)运算符在两个运算对象上逐位执行相应的逻辑操作。对于位与运算符(&
)来说,如果两个运算对象的对应位置都是1则运算结果中该位为1,否则为0。对于位或运算符(|
)来说,如果两个运算对象的对应位置至少有一个为1则运算结果中该位为1,否则为0。对于位异或运算符(^
)来说,如果两个运算对象的对应位置有且只有一个为1则运算结果中该位为1,否则为0。
运算对象可以是带符号的,也可以是无符号的。如果运算对象是带符号的且它的值为负,那么位运算符如何处理运算对象的“符号位”依赖于机器。而且,此时的左移操作可能会改变符号位的值,因此是一种未定义的行为。
建议:仅将位运算符用于处理无符号类型。
例子
//定义一个无符号的字符型变量bits
unsigned char bits=0233;
//移位运算符
bits=0233;bits<<8; cout<<"bits<<8:"<<bits<<endl;
bits=0233;bits<<31;cout<<"bits<<31:"<<bits<<endl;
bits=0233;bits>>3; cout<<"bits>>3:"<<bits<<endl;
//位求反运算符
bits=0227;~bits; cout<<"~bits:"<<~bits<<endl;
//位与、位或、位异或运算符
unsigned char b1=0145;
unsigned char b2=0257;
cout<<"b1 & b2 :"<<b1&b2<<endl;
cout<<"b1 | b2 :"<<b1|b2<<endl;
cout<<"b1 ^ b2 :"<<b1^b2<<endl;
0233是八进制的字面值,将其转为十进制数得:
2
×
8
2
+
3
×
8
1
+
3
×
8
0
=
128
+
24
+
3
=
155
2 \times8^2+3 \times8^1+3 \times8^0=128+24+3=155
2×82+3×81+3×80=128+24+3=155,再将其转为二进制数得:2->010,3->011,3->011,0233->10011011
0227是八进制的字面值,将其转为十进制数得:
2
×
8
2
+
2
×
8
1
+
7
×
8
0
=
128
+
16
+
7
=
151
2 \times8^2+2 \times8^1+7 \times8^0=128+16+7=151
2×82+2×81+7×80=128+16+7=151,再将其转为二进制数得:2->010,2->010,7->111,0227->10010111
0145是八进制的字面值,将其转为十进制数得:
1
×
8
2
+
4
×
8
1
+
5
×
8
0
=
64
+
32
+
5
=
101
1 \times8^2+4 \times8^1+5 \times8^0=64+32+5=101
1×82+4×81+5×80=64+32+5=101,再将其转为二进制数得:1->001,4->100,5->101,0145->01100101
0257是八进制的字面值,将其转为十进制数得:
2
×
8
2
+
5
×
8
1
+
7
×
8
0
=
128
+
40
+
7
=
175
2 \times8^2+5 \times8^1+7 \times8^0=128+40+7=175
2×82+5×81+7×80=128+40+7=175,再将其转为二进制数得:2->010,5->101,7->111,0227->10101111
移位运算符
在对bits进行移位操作前,首先把无符号字符类型
的bits提升成int类型
,然后再向左或向右移动指定位数。
bits<<8;
向左移动8位:
10011011(提升成int类型)
00000000 00000000 00000000 10011011(向左移动8位)
00000000 00000000 10011011 00000000
bits<<31;
向左移动31位,把最左边超出边界的7位丢弃掉:
10011011(提升成int类型)
00000000 00000000 00000000 10011011(向左移动31位)
10000000 00000000 00000000 00000000
bits>>3;
向右移动3位,把最右边超出边界的3位丢弃掉:
10011011(提升成int类型)
00000000 00000000 00000000 10011011(向右移动3位)
00000000 00000000 00000000 00010011
位求反运算符
char类型的运算对象首先提升成int类型,提升时运算对象原来的位保持不变,往高位(high order position)添加0即可。
~bits;
将bits提升成int类型,增加24个高位0,随后将提升后的值逐位求反:
10010111(提升成int类型)
00000000 00000000 00000000 10011011(逐位求反)
11111111 11111111 11111111 01100100
sizeof运算符
逗号运算符