求值顺序
- 如果二元运算符的两个运算对象涉及同一个对象并改变了对象的值,这个表达式将是未定义的
cout << i << " " << ++i << endl;
cout << i << " " << i + 1 << endl;
运算符
- 左值表达式表示一个对象的身份——在内存中的位置;右值表达式表示的是对象的值——内容。理解左值、右值
- 需要右值的地方可以用左值代替,这时使用的是左值的内容。但不能把右值当成左值(位置)使用
- 对于没有指定执行顺序的运算符来说,如果表达式修改了同一个对象,将产生未定义行为
int i = 0;
cout << i << ' ' << ++i << endl;
- 明确规定了求值顺序的运算符是&&、||、?:和,
- 运算对象的求值顺序和优先级结合律无关
f() + g() * h() + j()
- 参与取余运算的对象都必须是整数类型
- 取余运算符:m % (-n) = m % n;(-m) % n = -(m % n)。换句话说,如果m%n不等于0则符号永远和m相同
- 算术运算符+、-、*、/;关系运算符<、>、!=等;逻辑运算符&&、||、!
- 一般来说优先级算术>关系>逻辑
i != j < k
-> i != (j < k)
- 运算对象可按任意顺序求值。在一个表达式中如果一个子表达式改变了运算对象的值,另一条子表达式又要使用该值:
while (beg != s.end() && !isspace(*beg))
*beg = toupper(*beg++);
- 位运算符作用于整数类型的运算对象,并把运算对象看作二进制位的集合
sizeof运算符
- sizeof运算符返回一条表达式或者一个类型名字所占的字节数。满足右结合律,返回size_t类型的常量表达式
sizeof (type)
sizeof expr
Sales_data data, *p;
sizeof(Sales_data);
sizeof data;
sizeof p;
sizeof *p;
sizeof data.revenue;
- 对引用执行sizeof得到被引用对象所占空间大小
- 对指针指向sizeof运算符会得到指针本身所占空间大小,而sizeof运算符不会把数组转换成指针来处理
- 对string或vector执行sizeof只返回该类型固定部分的大小,不会计算对象中的元素占用了多少空间
- 如果一个运算对象是无符号类型,另外一个是带符号类型,而且其中的无符号类型不小于带符号类型,那么带符号的运算对象转换成无符号的
类型转换
- 任何具有明确定义的类型转换,只要不包含底层const就可以使用static_cast
double slope = static_cast<double>(j) / i;
void *p = &d;
double *dp = static_cast<double*>(p);
- const_cast只能改变运算对象的底层const
const char *pc;
char *p = const_cast<char*>(pc);
const char *cp;
char *q = static_cast<char*>(cp);
static_cast<string>(cp);
const_cast<string>(cp);
- reinterpret_cast为运算对象的位模式提供较低层次上的重新解释
int *ip;
char *pc = reinterpret_cast<char*>(ip);
string str(pc);