《C++Primer》读书笔记(四)表达式

基础

基本概念

  • C++定义了:一元运算符和二元运算符
  • 除此之外,还定义了作用于三个运算对象的三元运算符
  • 函数调用也是一种特殊的运算符

(1)组合运算符和运算对象
- 首先要理解==优先级、结合律以及运算对象的求值顺序==

(2)运算对象转换

(3)重载运算符

(4)左值和右值
- 当一个对象被用作右值时,用的是对象的值
- 当一个对象被用作左值时,用的是对象的身份(内存中的未知)

优先级与结合律

  1. 括号无视优先级与结合律
  2. 优先级与结合律有

求值顺序

(1)有4种运算符明确规定了求值顺序
- (&&)、(||)、(?:)、(,)

算术运算符

  • 一元运算符的级别最高,然后是乘除法,最低是加减法

    计算结果溢出将导致不可预知的后果

  • 取模(%)运算只支持整数类型

  • 在除法运算中,两个运算对象的符号相同则商为正数,否则为负;C++11新标准规定,商一律向0取整(不管正负,直接切除小数部分)

逻辑和关系运算符

  • 关系运算符作用于算术类型或指针类型
  • 逻辑运算符作用于任何能转换成布尔的类型

(1)与和或运算符
- 注意“与”运算符的左侧想检测原则,右侧不一定会检测
(2)非运算符
(3)关系运算符
- 满足左结合律,所以,只要关系运算符两侧的数据类型会马上转变为布尔值,不能再进行连续比较了
(4)相等性测试和布尔字面值

赋值运算符

  • 赋值运算符的左右两个运算对象类型不同,则==右侧运算对象将转换成左侧运算对象==
  • C++11允许用花括号来初始化列表
  • 转换成左侧运算对象时,所占的空间不能大于目标类型空间

(1)赋值运算满足右结合律
- 靠右的赋值运算符会先完成结合

(2)赋值运算符的优先级较低
- 在条件语句中,通常为赋值运算符部分加上括号

(3)切勿混淆相等运算符和赋值运算符

(4)复合赋值运算符
- += -= %= 等等,只执行一次求值,省去了求值拷贝的赋值

递增和递减运算符

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

(1)在一条语句中混用解引用和递增运算符

auto pbeg=v.begin();
while (pbeg!=v.end()&&*pbeg>=0)
    cout<<*pbeg++<<endl;
  • 此时,由于后置递增运算符的优先级高于解引用运算符,所以pebg++ 等价于 (pebg++)
  • 由于将会返回未增加的副本,所以能够实现,显示第一个值,然后向后移动

(2)运算对象可按任意顺序求值
= 不要将递增运算同时符放在赋值运算符的右边和左边

成员运算访问符

  • 点运算符和箭头运算符都可以用来访问成员
  • 其中,点运算符获取类对象的一个成员
  • 箭头运算符,表达式 ptr->mem 等价于 (*ptr).mem
string  s1="a string",*p=&s1;
auto n=s1.size(); //运行string对象s1的size成员
n=(*p).size(); //运行p所指对象的size成员
n=p->size(); //等价于(*p).size()

条件运算符

  • 条件运算符(?:)的使用形式:
cond?expr1:expr2

(1) 嵌套的条件运算符

(2) 在输出表达式中使用条件运算符
- 最好在cond表达式处加上括号,因为条件运算符的优先级很低

位运算符

  • 位运算符提供检查和设置二进制位的功能

(1)移位运算符( >> 或 << )

unsigned char bits=0233;
bits<<8;

(2)位求反运算符(~)

unsigned char bits=0227;
~bits;

(3)位与、位或、位异或

(4)使用位运算符

  • ==第138页==实例

(5)移位运算符
- (<<)移位运算符比的优先级:低于算术运算符、高于关系运算符、赋值运算符、条件运算符

sizeof运算符

  • 对char或者类型为ichar的表达式执行sizeof运算,结果得1
  • 对引用类型执行sizoof运算得被引用对象所占空间的大小
  • 对指针执行sizeof运算得到指针本身的所占空间的大小
  • 对解引用指针执行sizeof运算得到指针指向的对象所占空间的大小,指针不需有效

逗号运算符

  • 对于逗号运算符来说,首先对左侧的表达式求值,然后将求值结果丢弃掉。逗号运算符真正的结果是右侧表达式的值。如果右侧运算对象是左值,那么最终的求值结果也是左值

类型转换

算术转换

  1. 整型提升
  2. 无符号类型的运算对象
  3. 理解算数转换

其他隐式类型转换

  1. 数组转换成指针
  2. 指针的转换
    • 整数值0或者字面值nullptr能转换成任意指针类型
    • 指向任意非常量的指针能转换成void
    • 指向任意对象的指针能转换成const void*
  3. 转换成布尔类型
  4. 转换成常量
int i;
const int &j=i; //非常量转换成const int的引用
const int *p=&i; //非常量的地址转换成const的地址
int &r=j,*q=p; //错误,不允许const转换成非常量
  1. 类类型定义的转换

显式转换

  1. 命名的强制类型转换,形式:
cast-name<type>(expression)
  • 其中,cast-name是:static_cast、dynamic_cast、const_cast、reinterpret_cast

(1)static_cast

double slope=static_cast<double>(j) / i;
void* p=&d;
double *dp=static_cast<double*>(p);

(2)const_cast
- 只能改变运算对象的底层const

const char *pc;
char *p=const_cast<char*>(pc);

(3)reinterpret_cast
- 为运算对象的位模式提供较低层次上的重新解释

int *ip;
char 8pc=reinterpret_cast<char*>(ip);
  1. 旧的强制类型转换
    • type(expr); //函数形式的强制类型转换
    • (type)expr; //C语言风格的强制类型转换
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值