《C++ Primer》读书笔记第四章-1-基础 And 运算符

笔记会持续更新,有错误的地方欢迎指正,谢谢!

前言:
1. C++ 提供了一套丰富的运算符,可以用于内置类型对象的操作。即便运算对象是自定义的类类型,C++也允许程序员指定这些运算符的含义(真的给了程序员很大的自由和挑战,第十四章才讲这个,等着吧23333)。
2. 本章主要介绍用于内置类型运算对象的运算符,简单介绍几种标准库定义的运算符。

基础

基本概念

C++定义了两个概念:
一元运算符:作用于一个运算对象,如取地址符&。
二元运算符:作用于两个运算对象,如乘法运算符,一些符号两种都行,比如*作为乘法是二元,作为解引用是一元。

左值右值

  1. C++的表达式要么是左值,要么就是右值;
  2. 当一个对象被用作右值的时候,用的是对象的值(所含的内容);当对象被用作左值的时候,用的是对象的身份(内容在内存中的地址)。

求值顺序

例1:
int i = f1() * f2();
我们不知道f1和f2哪个先调用
例2:
int i = 0;
cout << i << " " << ++i << endl;
cout << ++i << " " << i << endl;
都输出:1 1

黄金法则:不确定的时候用括号啊~

运算符

算术运算符

特殊1:
bool b = true;
bool b2 = -b //b2还是true,因为-b=-1,只要非零都是true,所以不要用布尔值参与计算。

特殊2:
int a = b % pi; //报错,必须对整型求余。
求余还有些注意的地方: m%(-n) = m%n; (-m)%n = -(m%n) 简单来说,就是n的符号省略,m的符号放括号外面。

逻辑和关系运算符

逻辑运算符:

逻辑运算符功能
!逻辑非
&&逻辑与
||逻辑或

&&和||都是短路求值,比如求a&&b,如果a为假,编译器就不会去判断b的真假。

关系运算符:
因为关系运算符的求值结果是布尔值,所以将几个关系运算符连写在一起会产生意向不到的错误结果:

int i = 0, j = 5, k = 2;
if(i<j<k) //错误写法,这里为真。因为i<j为真,值为1,又1<k。
if(i<j && j<k) //正确写法,这里为假。

另外,再强调一遍,true的值:
例子:
if(val) //只要val不是零,都是true。

赋值运算符

易混淆题型:
int i = 0, j = 0, k = 0;
k = {3.14}; //错误:因为列表初始化不允许损失精度。
i = j = 1; //正确:i和j都被赋值为1。
int ival, *pval;
ival = pval = 0; //错误:不能把指针的值赋值给int。(地址是一种标识,而这种标识和整数没有关系。不能因为地址看起来像数字就认为它是整型。)

递增和递减运算符

我们推荐++i,因为++i将对象本身作为左值(内容在内存中的地址)返回,节省资源,i++则将对象原始值的副本作为右值(内容)返回。即左值可代替右值的一种体现:左值根据地址去获得右值的内容进行+1,但它还是左值!

递增运算符和解引用同时存在:
cout << *beg++ << endl; //按照优先级先解引用,再+1。

成员访问运算符

点运算符、箭头运算符都可用于访问成员,如下:

string s = "hi", *p = &s;
//以下三个n等价:
auto n1 = s.size();//点运算符的应用。另外,容器的性质string基本都有。
auto n2 = (*p).size(); //点运算符的应用。括号不能少哦,因为解引用的优先级低!
auto n3 = p->size();//箭头运算符的应用。

条件运算符

唯一的一个三目运算符。
string res = grade < 60 ? “abc” : “def”;

位运算符

作用于整型类型的运算对象,并把对象看成是二进制。

运算符功能
~求反
<<左移
>>右移
&位与:都为1才为1
|位或:一个为1就是1
^位亦或:不同才为1
移位运算符
  1. a << 3;)左移运算符<<在右侧插入值为0的二进制位;
  2. a >> 3;)右移运算符>>的行为依赖于运算对象的类型,如果运算对象是无符号类型,左侧插入0即可,如果是带符号类型,正数用0填补,负数用1填补。注:不同的环境填补方式可能不同。

使用位运算符:超级省内存空间!(应多用位运算符!)

unsigned long quiz = 0; //初始化,全班都没过,用long是为了至少有32位。
//题目1:怎么记录27号(编号从0开始)学生通过了?
//解答:设value是unsigned long的1,然后左移27位(从第0位开始的,第0位在最右边),1就到第27位来了。
quiz = quiz | (value<< 27)//(value<< 27)的值并未保存到value中。
//题目2:假设后来检查的时候发现27号挂科了,那怎么修改呢?
quiz &= ~(value<< 27);//quiz 只有27号学生的成绩,并且只有通过位与运算解决之。
//查看27号有没有过?
bool status = quiz & (value<< 27);

sizeof运算符

它只根据类型返回一条表达式或一个类型名称所占的字节数。
例子:

Book *book;//book是指向Book类型对象的指针。
sizeof *p;//p所指类型的空间大小,即sizeof(Book)。

运算符优先级表

在P147,我的建议是:用到的时候去查,反正你也记不住这么多,实在不行就用括号呗。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值