算数操作符
- eg: + - *
逻辑操作符
- eg: & | ! < =
位操作符
:
| Operator | Function|
| :--------: | :--------:|
| ~ | bitwise NOT 位求反 |
|<<| left shift 左移|
|>>| right shift 右移|
|&|bitwise AND 位与|
|^|bitwise XOR 位异或|
| | bitwise OR 位或|- IO操作符的优先级和结合性:移位操作符具有中等优先级,其优先级比算术操作符低,但比关系操作符、赋值操作符和条件操作符优先级高。
cout << 42 + 10; // ok, + has higher precedence, so the sum is printed
cout << (10 < 42); // ok: parentheses force intended grouping; prints 1
cout << 10 < 42; // error: attempt to compare cout to 42!
赋值操作符
- 赋值操作符具有右结合性,赋值操作返回的是左值。
ival = jval = 0
,这一句中先将0赋给jval,返回值是jval,再将jval赋给ival。
自增和自减操作符
- 前置操作返回左值,后置操作返回右值。只有在必要的时候才使用后置操作符,因为前置操作需要做的工作更少。
*iter++
后自增的优先级高于解引用,所以这句代码意义是先后自增,然后解引用,当然后自增返回的副本是未自增前的。作为c++程序员,最好熟悉并使用这种简洁又准确的方式。
箭头操作符
.
和->
,知道用就行了。
条件操作符
cond ? expr1 : expr2;
要注意避免深度嵌套,代码太长的话,用if可读性更强些。- 条件操作符的优先级相当低。
sizeof操作符
- 有三种语法形式。
sizeof (type name);
sizeof (expr);
sizeof expr;
- sizeof 操作符的作用是返回一个对象或类型名的长度,返回值的类型为 size_t
逗号操作符
- 逗号表达式是一组由逗号分隔的表达式,这些表达式从左向右计算。逗号表达式的结果是其最右边表达式的值。如果最右边的操作数是左值,则逗号表达式的值也是左值。
复合表达式的求值
- 什么是优先级,什么是结合性?优先级是不同操作符之间先算哪个,结合性是相同优先级操作符之间先算左边还是先算右边的。
- 大多数操作符没有规定其操作数的求值顺序:由编译器自由选择先计算左操作数还是右操作数。
*++iter
iter先自加然后解引用。
new和delete表达式
- 动态创建的对象,初始化情况和静态的一样。
类型转换
- 隐式类型转换(编译器自动进行的)
- 操作数两端的类型被转换成相同类型。
- 用作条件表达式的类型被转换成bool类型。
- 不同类型的变量和表达式之间初始化或者赋值的时候。例如
int *p = 0
int 0 converted to null pointer of type int* - 算术转换,比如整数提升,bool提升到int就是1和0。其他还有很多奇葩的转换细节,一般不会自找麻烦这么写吧
指针转换。看个例子
int a[10]; int* p = a;// 这里是有一个array到指针的转换,我以前以为a就是指针,现在知道却是存在一个类型转换的,不然的话,&a的值就应该是 std::cout<<a<;//所以这里也有转换 std::cout<<&a;//取址和sizeof没有转换,或者引用也没有转换 std::cout<<p;
经过测试,这三个输出结果都是一样的。
- 算数值和指针都可以转换为bool。
- 枚举类型转换成int。
标准库类型定义的转换,例如
while (cin >> s)
这里隐式使用了 IO 标准库定义的类型转换。
- 显式转换
static_cast
:编译器隐式执行的任何类型转换都可以由 static_cast 显式完成dynamic_cast
const_cast
:添加或删除const特性。例如const_cast<char*>(pc_str)
就是可以将const类型的pc_str转换为char*reinterpret_cast
: 这个用的少吧,书上的解释是A reinterpret_cast generally performs a low-level reinterpretation of the bit pattern of its operands- 使用的格式是
castname<type>(expression)
,castname是上面四种转换方式中的名字,type是要转换的类型。
- 建议:避免使用强制类型转换