C++学习笔记(三)

第四章 - 表达式

位运算符和强制类型转换两部分没有详细看

1. 算术运算符

  • (m/n)*n + m%n 的求值结果与m相等;

  • 除了 -m 导致溢出的特殊情况,其他时候

    • (-m)/nm/(-n) 都等于 -(m/n)

    • m%(-n) 等于 m%n

    • (-m)%n 等于 -(m%n)

      -12 % -8 = -5
      21 % -5 = 1
      

2. 逻辑与 && 和 逻辑或 || 运算符

2.1 短路求值(short-circuit evaluation)
  • 对于逻辑与 运算符来说, 当且仅当左侧运算对象为真时才对右侧运算对象求值
  • 对于逻辑或 运算符来说, 当且仅当左侧运算对象为假时才对右侧运算对象求值
2.2 相等性测试与布尔字面值
if (val == true) {/* ... */ };		// 只有当 val 等于1时2条件才为真, 等价于
if (val == 1 {/* ... */ };			// 比较前编译器会首先把 true 转换成 val 的类型
  • 进行比较运算时,除非比较的对象是布尔类型,否则不要使用布尔字面值 truefalse 作为运算对象

3. 递增和递减运算符

3.1 前置 和 后置
  • 前置: 首先将运算对象加1 (或减1) , 然后将改变后的对象作为求值结果

  • 后置: 也会将运算对象加1 (或减1), 但是求值结果是运算对象改变之前那个值的副本

  • 除非必须,否则不用递增递减运算符的后置版本

    int i = 0, j;
    j = ++i;						// j = 1, i = 1
    j = i++;						// j = 1, i = 2
    
3.2 在一条语句中混用解引用和递增运算符
// 输出 v 中的元素直到遇到第一个负值为止
auto pbeg = v.begin();
while (pbeg != v.end() && *pbeg >= 0)
    cout << *pbeg++ << endl;			// 首先将 pbeg 的值加1, 然后解引用加1前的值
  • cout << *iter++ << endl; 要比 cout << *iter << endl; ++iter; 简洁,也更少出错

4. 条件运算符

  • 嵌套条件运算符

    // 成绩在90分以上得到“high pass”,在60分以下得到“fail”,其他为“pass”
    finalgrade = (grade > 90) ? "high pass" 
        : (grade < 60) ? "fail" : "pass";
    
    • cond?expr1:expr2; 首先求 cond 的值, 如果条件为真, 对 expr1 求值并返回该值; 否则对 expr2 求值并返回该值
    • 条件运算符的优先级低于 <<

5. 位运算符

6. sizeof 运算符

6.1 基本概念
  • sizeof 运算符返回一个表达式或一个类型名字所占的字节数,满足右结合律,所得的值是一个 size_t 类型

    sizeof (type)
    sizeof expr					// 返回表达式结果类型的大小,不实际计算运行对象的值
    
6.2 sizeof expr
Sales_data data, *p;
sizeof(Sales_data);				// 存储 Sales_data 类型对象所占的空间大小
sizeof data;					// data 的类型大小,等价于上一条语句
sizeof p;						// 指针 p 所占的空间大小
sizeof *p;						// p 所指的对象所占的空间大小,同 sizeof(Sales_data)
sizeof data.revenue;			// Sales_data 中 revenue 成员对应类型所占的空间大小
sizeof Sales_data::revenue;		// 同上一条语句
  • sizeof 的优先级与 * 运算符的优先级一样,所以表达式按照从右向左的顺序组合,其等价于 sizeof (*p)
  • sizeof 的运算对象中解引用一个无效指针任然是一种安全行为,因为指针实际上并没有被真正使用
sizeof 运算符的结果
对象或表达式类型结果
char1
引用被引用对象所占空间的大小
指针指针本身所占空间的大小
解引用指针指针所指向对象所占空间的大小,指针无需有效
数组整个数组所占空间的大小
stringvector返回固定部分的大小,不会计算对象中的元素占用的空间
constexpr size_t sz = sizeof (ia)/sizeof(*ia);		// 返回 ia 的元素数量
7. 逗号运算符
// 将从 size 到1的值赋给 ivec 的元素
vector<int>::size_type cnt = ivec.size();
for (vector<int>::size_type ix = 0; ix != ivec.size(); ++ix, --cnt)
    ivec[ix] = cnt;
  • 逗号运算符(comma operator)中含有两个运算对象,按照从左向右的顺序一次求值。首先对左侧的表达式求值,然后将求值结果丢弃,逗号运算符真正的结果是右侧表达式的值
8. 类型转换
8.1 显示转换
  • static_cast

    int i = 3, j = 5;
    double slope = static_cast<double>(j) / i;			// 强制转换以进行浮点数除法
    
  • const_cast 只能改变运算对象的底层 const

    const char *pc;
    char *p = const_cast<char*>(pc);					// 去掉 const 性质(cast away the const)
    
    • 只有const_cast 能改变表达式的常量属性
8.2 尽量避免使用强制类型转换
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值