第四章-表达式

求值顺序

  • 如果二元运算符的两个运算对象涉及同一个对象并改变了对象的值,这个表达式将是未定义的
cout << i << " " << ++i << endl;
//可能先++i再求i,也可能先求i再++i
//此表达式行为不可预知
//改写如下
cout << i << " " << i + 1 << endl;

运算符

  • 左值表达式表示一个对象的身份——在内存中的位置;右值表达式表示的是对象的值——内容。理解左值、右值
  • 需要右值的地方可以用左值代替,这时使用的是左值的内容。但不能把右值当成左值(位置)使用
  • 对于没有指定执行顺序的运算符来说,如果表达式修改了同一个对象,将产生未定义行为
int i = 0;
cout << i << ' ' << ++i << endl;
//编译器可能先求++i再求i,最后输出1 1
//也可能先求i再求++i,最后输出0 1
  • 明确规定了求值顺序的运算符是&&、||、?:和,
  • 运算对象的求值顺序和优先级结合律无关
f() + g() * h() + j()
//如果4个函数是无关函数,不会改变同一个对象的状态,也不执行IO任务那没什么事
//如果改变同一个对象那还是会产生未定义行为
  • 参与取余运算的对象都必须是整数类型
  • 取余运算符: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++); //错误!该赋值语句未定义
//编译器可能这样操作*beg = toupper(*beg);
//也可能这样*(beg + 1) = toupper(*beg);
  • 位运算符作用于整数类型的运算对象,并把运算对象看作二进制位的集合

sizeof运算符

  • sizeof运算符返回一条表达式或者一个类型名字所占的字节数。满足右结合律,返回size_t类型的常量表达式
sizeof (type)
sizeof expr

Sales_data data, *p;
sizeof(Sales_data); //存储Sales_data类型的对象所占的空间大小
sizeof data; //同上
sizeof p; //指针所占的空间大小
sizeof *p; //p所指类型的空间大小,同上上
//这里就算p是没有初始化的指针也没事
sizeof data.revenue; //Sales_data的revenue成员对于类型的大小
  • 对引用执行sizeof得到被引用对象所占空间大小
  • 对指针指向sizeof运算符会得到指针本身所占空间大小,而sizeof运算符不会把数组转换成指针来处理
  • 对string或vector执行sizeof只返回该类型固定部分的大小,不会计算对象中的元素占用了多少空间
  • 如果一个运算对象是无符号类型,另外一个是带符号类型,而且其中的无符号类型不小于带符号类型,那么带符号的运算对象转换成无符号的

类型转换

  • 任何具有明确定义的类型转换,只要不包含底层const就可以使用static_cast
double slope = static_cast<double>(j) / i;

//static_cast对于编译器无法自动执行的类型转换也有用
//比如可以用static_cast找回存在于void*指针中的值
void *p = &d;
double *dp = static_cast<double*>(p);
  • const_cast只能改变运算对象的底层const
const char *pc;
char *p = const_cast<char*>(pc);
//将常量转换成非常量一般称之为去const性质
//如果对象本身不是const,使用强制类型转换获得写权限是合法行为
//如果对象是常量,使用const_cast执行写操作会产生未定义后果
  • 不能使用const_cast改变表达式类型
const char *cp;
char *q = static_cast<char*>(cp); //错误!只有const_cast才能改变表达式常量属性
static_cast<string>(cp); //正确,字符串字面值转换为string
const_cast<string>(cp); //错误!,const_cast只用来改变常量属性,不能改变类型
  • reinterpret_cast为运算对象的位模式提供较低层次上的重新解释
int *ip;
char *pc = reinterpret_cast<char*>(ip);
//记住pc所指的真实对象是int而不是字符
string str(pc); //把pc当成普通字符指针使用就可能在运行时发生错误
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值