启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情
c++提供了一套丰富的运算符,并定义了这些运算符的基于内置类型运算对象的操作,当然也允许用户在自定义类型当中定义这些运算符基于自定义类型的操作,所以我们来总体看一下c++的运算。
基础
在聊C++表达式之前,还是聊聊常见的一些概念:
运算符
谈到表达式,就需要有运算,有运算,就会涉及到运算符,顾名思义,就是运算的符号,按照参数运算对象的个数划分:在c++当中,常见的运算符有一元运算符和二元运算符,当然不常见的有三元运算符,这里的元指的是参与运算符计算的对象数量,比如:
取地址符(&)
解引用符(*)
就是一元运算符
数值比较 (==)
乘法运算(*)
就是二元运算符
但是大家也可以发现,*作为解引用符是一元运算符,但是作为乘法运算就是二元,所以大家在描述运算符是几元的时候,还是要看具体情况的。而且从这个角度上来看,函数就是特殊的多元运算符了,因为函数是基于几个对象进行运算时不定的。
优先级和结合律
谈到运算,除了运算符,要研究的就是优先级和结合律了,在工作当中很多时候是多种运算在一个表达式当中的,那么这个时候就需要了解不同运算符的优先级和他们的结合律。举个小学的例子:
22+8*2/4
这个表达式当中显然是由优先级和集合率的,先乘除后加减,当然和大家想的一样也可以通过小括号来指定优先级。
尽管这个概念很简单,但是还是要刻意注意,因为再编程过程当中,除了算术运算还会包括其他的运算,比如:逻辑,异或,按位,函数等等。
常见的运算类型
上面说了一些运算的基本的概念,那么接下来聊聊c++表达式当中常见的运算类型:
算术运算
算术运算符:
| 运算符 | 描述 |
|---|---|
| + | 一元运算符 正号 或者 加法 |
| - | 一元运算符 负号 或者 减法 |
| * | 乘法 |
| / | 除法 |
| % | 取余 |
这里的+和-就具有两种不同的含义,需要大家在使用的时候具体分析,比如:
int b = 10;
-b //这里就是负号
b-3 //这里就是减肥运算
关于算术运算还是需关注几个点的:
1、c++当中的算术运算可以是运算对象转换,比如,小整数类型(short)会被变成大整数类型(int)
2、要注意对象类型的范围,比如short类型最大数值是32767,那么:
short num = 32767;
num += 1;
这个时候就会导致溢出,可以编译,但是值变成了一个不可以预知的数。
当然算术运算的优先级和结合律和数学上的是类似的。
逻辑运算
| 运算符 | 描述 | ||
|---|---|---|---|
| ! | 逻辑非,取反 | ||
| && | 逻辑与 | ||
| 逻辑或 |
和好多编程语言一样:
!代表取反,是一个一元运算符
&& 是一个二元运算符,需要两边的条件都成立才可以,这里的成立可以是布尔值的true
|| 也是一个二元运算符,只要两边的条件有一个成立就可以,这里的成立可以是布尔值的true
当然也包含了另外一种逻辑:
&& 运算符,左侧运算值位true才会进行右侧运算
|| 运算符,左侧运算值位false才有进行右侧运算
并且他们的优先级是:
非(!) > 与(&&) > 或(||)
比较运算
比较运算和数学上的类似
| 运算符 | 描述 |
|---|---|
| 大于 | |
| < | 小于 |
| == | 等于 |
| >= | 大等于 |
| <= | 小等于 |
| != | 不等于 |
这里有两个点需要注意:
1、对于新手小伙伴来说,一定要注意比较的等于是两个等于号,不是一个,这个很容易犯错,需要刻意练习。
2、在编写代码的时候经常使用变量==true,这里的true和数值1是一样的。
赋值运算
就是基于等于号的赋值,也是优先级比较低的一种运算,这种运算很常见,但是有些点还是要注意的:
1、区别初始化和赋值运算
int i = 0, j=0, k=0; //初始化
i = 10 //赋值
2、赋值运算等号左边是要被赋值的对象,右边是表达式,所以:
int i;
5+2=i; //错误写法
3、赋值的时候要注意变量的类型,比如:
int i;
i = {3.14} //错误写法,窄化转换 相对于原始数据的长度,转换后的长度变短了;就不能完全表达转换之前的数值,也叫变窄了。
4、赋值运算支持链式的赋值,但是还是要注意类型:
int i,j;
i = j = 1;
递增(减)运算
| 运算符 | 描述 |
|---|---|
| ++ | 递增运算符 |
| -- | 递减运算符 |
就是对对象进行+1(-1)的简单写法,一个经常让大家讨论,也必须注意的点:
int i = 0,j;
j = ++i;
++i 代表先进行自增,然后返回结果,所以i是1,j是1
int i = 0,j;
j = i++;
i++代表,先返回结果,然后进行自增,所以j是0,i是1
尽管我们在聊到自增(减)运算的时候先想到的是i++这样运算符后置的写法,但是编程的时候尽量不要这样写,因为他是在返回结果后再次进行运算,返回的结果就是没有修改的结果,如果想要修改后的结果得等他返回后接收,如果想要没有修改的结果,那么运算就没有意义了。所以,嘿嘿嘿。
位运算
这个运算是在日常生活当中接触步到的,因为他正对的是二进制操作,分为两种:
移位运算
| 运算符 | 描述 |
|---|---|
| >> | 左移,一元运算符 |
| << | 右移,一元运算符 |
a<<b表示把a的二进制位向左移动b位,低位用0补上。 a>>b就是把a的二进制位向右移动b位,溢出的舍去。
比如:
二进制 10011011 >> 8
10011011 00000000
位运算
| 运算符 | 描述 | |
|---|---|---|
| ~ | 位取反,一元运算符 | |
| & | 位与,二元运算符 | |
| 位异或,二元运算符 | ||
| 位或,二元运算符 |
位取反
顾名思义就是将二进制位上的数据0改为1,1改为0的运算
10011011
~
01100100
位与 是一个二元的运算符,两个二进制数相同位上都为1结果位上为1,否则为0
10011011 & 11000011
10011011
11000011
10000011 //结果
位或 是一个二元的运算符,两个二进制数相同位上只要有一个为1结果位上为1,否则为0
10011011 | 11000011
10011011
11000011
11011011 //结果
位异或 是一个二元的运算符,两个二进制数相同位上有且只有一个为1结果位上为1,否则为0
10011011 | 11000011
10011011
11000011
01011000 //结果
相较上面的运算位运算会难一点,结合之前的进制转换来看会连贯很多。