C++ 运算符
【C++学习】以w3cschool的教程为框架,记录总结C++Primer第五版的学习内容。
- C++定义了一元运算符和二元运算符,除此之外,还有三元运算符。函数调用也是一种特殊的运算符,它对运算对象的数量没有限制。
算术运算符
-
一元运算符的优先级最高,接下来是乘法和除法,优先级最低的是加法和减法;
-
运算符都满足左结合律,运算对象和求值结果都是右值;
-
取模运算符
%
的运算对象必须是整数,若m%n
不等于0,则它的符号和m相同。
关系运算符
- 关系运算符作用于算术类型或指针类型;
- 比较对象的大小并返回布尔值,满足左结合律,运算对象和求值结果都是右值;
- 包括
==
、!=
、>
、<
、>=
、<=
逻辑运算符
- 逻辑运算符作用于任意能转换成布尔值的类型;
- 返回布尔值,运算对象和求值结果都是右值;
- 包括
&&
、||
、!
;
位运算符
-
位运算符作用于整数类型的运算对象,并逐位执行操作;
-
假设如果 A = 60,且 B = 13,现在以二进制格式表示,它们如下所示:
A = 0011 1100
B = 0000 1101
运算符 | 描述 | 实例 |
---|---|---|
& | 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 | (A & B) 将得到 12,即为 0000 1100 |
| | 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 | (A | B) 将得到 61,即为 0011 1101 |
^ | 如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 | (A ^ B) 将得到 49,即为 0011 0001 |
~ | 二进制补码运算符是一元运算符,具有"翻转"位效果。 | (~A ) 将得到 -61,即为 1100 0011,2 的补码形式,带符号的二进制数。 |
<< | 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 | A << 2 将得到 240,即为 1111 0000 |
>> | 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 | A >> 2 将得到 15,即为 0000 1111 |
赋值运算符
-
赋值运算符的左侧对象必须是一个左值,赋值运算的结果是它的左侧对象,并且也是一个左值;
-
如果左右两个运算对象类型不同,则右侧对象将转换为左侧运算对象的类型;
-
赋值运算符满足右结合律;
-
赋值运算的优先级相对较低,所以通常需要给赋值部分加上括号;
-
包括
=
、+=
、-=
、*=
、/=
等。
递增和递减运算符
- 前置版本
++a
:先将运算对象加1,然后将改变后的对象作为求值结果; - 后置版本
a++
:将运算对象加1,但求值结果是运算对象改变之前那个值的副本;- 后置递增运算符的优先级高于解引用运算符;
- 尽量不要使用后置运算符。
成员访问运算符
- 点运算符:获取类对象的一个成员
(*ptr).mem
;- 由于解引用运算符的优先级低于点运算符,所以执行解引用运算的子表达式两端必须加上括号;
- 箭头运算符:与点运算符有关,
ptr->mem
等价于(*ptr).mem
;
sizeof运算符
- sizeof运算符返回一条表达式或一个类型名字所占的字节数;
- 满足右结合律,所得的值是一个size_t类型的常量表达式;
- sizeof并不实际计算其运算对象的值;
- sizeof运算符结果部分地依赖于其作用的类型:
- 对引用类型得到被引用对象所占空间的大小;
- 对指针类型得到指针本身所占空间的大小,对解引用类型得到指向对象所占空间的大小;
- 对数组得到整个数组所占空间的大小;
- 对string和vector得到该类型固定部分的大小,不会计算对象中的元素占用了多少空间。
类型转换
-
算术类型之间的隐式转换被设计得尽可能避免精度损失:
- 运算符的运算对象将会转换成最宽的类型;
- 表达式中既有浮点类型也有整数类型时,整数类型将会转换成相应的浮点类型;
-
其他隐式转换类型:
-
数组自动转换成指向数组首元素的指针(p143):
int ia[10]; int *p = ia;
当数组被用作
decaltype
的参数,或作为取地址符、sizeof
等运算符的对象时,上述转换不会发生; -
常量整数值0或字面值nullptr能转换成任意指针类型;
-
指向任意非常量的指针能转换为void,指向任意对象的指针能转换为const void;
-
-
显示转换
-
命名的强制类型转换:
cast-name<type>(expression);
-
static_cast:
任何具有明确定义的类型转换,只要不包含底层const,都可以用static_cast:
double slope = static_cast<double>(j) / i; //表示不在意潜在的精度损失
-
const_cast:
只能改名运算对象的底层const;
对于将常量对象转换成非常量的行为,称之为“去掉const性质”
-