1.1运算符
用算术运算符将运算对象
(
也称操作数)连接起来的、符合C语法规则的式子,称为C算术表达式运算对
象包括常量、变量、函数返回值等
例如
:
a
* b / c
-1
.5
+
'a'
1.2算术运算符
+ - * / % += -= *= /= %=
1.2.1/的取整
如果
/
的所有运算对象都是整数
/
的功能就是取整
5/3 == 1 5/2 == 2
1.2.2 /的除法运算
如果
/
有一个运算对象是实型
/
的功能就是除法运算
5/2.0 == 2.5
1.2.3 %取余运算符
5%2 == 1 3%5==3
n%3 == 0,1,2
data%n == 0,1,2,......n-1
1.3 复合运算符
+= -= *= /= %=
a+=b;//a=a+b;
a*=b;//a=a*b;
a/=b;//a=a/b;
a%=b;//a=a%b;
注意:一定要将
=
号的右边看成一个整体
int a = 3;
a*=4+5;//a = a*(4+5)
a的值是:27
案例
1
:以下表达式执行完
a
的值是
int a = 12;
a+= a-= a*=a;
1.4 关系运算符
>、<、==、>=、<=、!=
1.5 逻辑运算符
&& || !
1.5.1 &&逻辑与:
A && B A
为真 且
B
为真 整个表达式结果才为真。
A && B A
或
B
只要有一个为假
整个表达式结果才为假。
注意:逻辑与
&&
的短路特性:
如果
A
为假
整个表达式为假, 那么
B
的真假决定不了整个表达式的结果,所以不会再判断
B
的真假,就叫“
短路特性
1.5.2 ||逻辑或:
A || B A
和
B
只要有一个为真 整个表达式结果为真。
A || B A
和
B
同时假 整个表达式结果为假。
注意逻辑或
||
的短路特性:
如果
A
为真
整个表达式为真, 那么
B
的真假决定不了整个表达式的结果,所以不会再判断
B
的真假, 就叫“
短路特性
”
1.5.3 !逻辑非:
!
真
==
假
!假
==
真
在
c
语言中 除了
0
为假 其他都为真
!10 == 0 !-10 == 0 !0 == 1
1.6 位运算(二进制位运算)
1.6.1 & 按位与
语法:全
1
为
1
有
0
为
0
特点:和
1
相与保持不变
和
0
相与为
0
场景
:
将指定位 清
0
1100 0011
& 1111 0000
--------------------
1100 0000
案例
1
:
data
为
1
字节
将
data
的第
3,4
为清
0
其他位保持不变
unsigned char data;
data = data & 1110 0111;
data = data & 0xe7;//ok
data &= 0xe7;//ok
1.6.2 | 按位或
语法:有
1
为
1
全
0
为
0
特点:和
1
或置
1
, 和
0
或 保持不变
场景:将指定位 置
1
1100 0011
| 1111 0000
--------------------
1111 0011
案例
1
:
data
为
1
字节
将
data
的第
5,6
为置
1
其他位保持不变
data = data | 0110 0000
data = data | 0x60;//ok
data |= 0x60;//ok
1.6.3 ~按位取反
语法:
0
变
1 1
变
0
~1100 0011 == 0011 1100
1.6.4 ^按位异或
语法:相同为
0
不同为
1
特点:和
1
异或取反
和
0
异或保持不变
场景:将指定位 发生翻转
1100 0011
^ 1111 0000
--------------------
0011 0011
^ 1111 0000
--------------------
1100 0011
1.6.5 左移<<:左边丢弃 右边补0
移动的位数 不要超过 自身位的宽度
如果:data=0000 0001 data=data<<0; data=0000 0001 == 1==data*2^0
如果:data=0000 0001 data=data<<1; data=0000 0010 == 2==data*2^1
如果:data=0000 0001 data=data<<2; data=0000 0100 == 4==data*2^2
如果:data=0000 0001 data=data<<3; data=0000 1000 == 8==data*2^3
......
如果:data=0000 0001 data=data<<6; data=0100 0000 == 64==data*2^6
1.6.6 右移>>:右边丢弃 左边补0(补1)
算术右移、逻辑右移 都是编译器决定,用户无法确定。
无符号数:右边丢弃 左边补
0
有符号数:
正数:右边丢弃 左边补
0
负数:右边丢弃 左边补
0
(逻辑右移)
负数:右边丢弃 左边补
1
(算术右移)
编写代码测试 编译器为那种右移:
如果:data=1000 0000 data=data>>0; data=1000 0000 == 128==data除以2^0
如果:data=1000 0000 data=data>>1; data=0100 0000 == 64==data除以2^1
如果:data=1000 0000 data=data>>2; data=0010 0000 == 32==data除以2^2
如果:data=1000 0000 data=data>>3; data=0001 0000 == 16==data除以2^3
......
如果:data=1000 0000 data=data>>6; data=0000 0010 == 2==data除以2^6
1.7 三目运算符?:
表达式
1
? 值
1:
值
2
如果表达式
1
为真 整个表达式的值为值
1
(引用)
如果表达式
1
为假 整个表达式的值为值
2
(引用)
cout<<(10>20? 10:20);
int data1 = 10;
int data2 = 20;
//(data1>data2?data1:data2) 结果等价于data2
(data1>data2?data1:data2) = 200;
cout<<"data1 = "<<data1<<endl;//10
cout<<"data2 = "<<data2<<endl;//200
1.8 运算符优先级
优先级别数值越小,优先级越高,同一优先级 看结合性
1.9 自增自减运算符
1.9.1 自增自减独立作为一条语句
不管是
i++ i-- ++i --i
如果是独立的一条语句
那么
i++
和
++i, i--
和
--i
没区别
int i = 3;
//i++;//i=i+1
++i;//i=i+1
cout<<i<<endl;//4
1.9.2 ++在右边 先使用 后加减
int i=3;
int j = 0;
j = i++;//j=i; i++;
cout<<i<<" "<<j<<endl//4 3
1.9.3 ++在左边 先加减 后使用
int i=3;
int j = 0;
j = ++i;//i++; j=i;
cout<<i<<" "<<j<<endl;//4 4