C语言操作符简单介绍
一、操作符定义
指令系统的每一条指令都有一个操作符,它表示该指令应进行什么样性质的操作。不同的指令用操作符这个字段的不同编码来表示,每个编码代表一种指令。现对C语言中的操作符进行简单介绍。
二、分类
C语言中操作符具体可分为:
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
以下为具体介绍:
(1)算术操作符:+ 、- 、* 、/ 、%
假设A的值是5,B的值是10。
算术操作符 | 描述 | 实例 |
+ | 把两个操作数相加 | A+B得到15 |
- | 从第一个操作数中减去第二个操作数 | A-B得到-5 |
* | 把两个操作数相乘 | A*B得到50 |
/ | 分子除以分母 | B/A得到2 |
% | 取模运算符,整除后取余数 | B%A得到0 |
注意:
1. 除了%操作符之外,其他的几个操作符可以作用于整数和浮点数。
2. 对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3. %操作符的两个操作数必须为整数。返回的是整除之后的余数。
(2)移位操作符:<< 左移操作符、>> 右移操作符
假设A的值是2。
移位操作符 | 描述 | 实例 |
<< (左移一位结果相当于乘2) | 二进制左移符号。左操作数的值向左移动右操作数指定的位数 | A<<1得到4,即 0100(简写) |
>> (右移一位结果相当于除2) | 二进制右移符号。左操作数的值向右移动右操作数指定的位数 | A>>1得到1,即 0001(简写) |
左移操作符移位规则:左边抛弃、右边补0
右移操作符移位规则分两种:
1. 逻辑移位:右边丢弃,左边补0
2. 算术移位:右边丢弃,左边补符号位(正数补0,负数补1)
根据编译器的不同,右移的规则不同,在VS环境下基本属于算术右移,移位操作符是对一个数的二进制数补码进行移位。
警告⚠:对于移位运算符,不要移动负数位,这个是标准未定义的。
例如:
int num = 10;
num>>-1; //这种是错的,可以写成num<<1;
(3)位操作符:&、|、^
假设A的值是6,B的值是11。
位操作符 | 描述 | 实例 |
& | 按位与 | A&B得到2,即 0010(简写) |
| | 按位或 | A|B得到15,即 1111(简写) |
^ | 按位异或 | A^B得到13,即 1101(简写) |
注:他们的操作数必须是整数。
(4)赋值操作符:
赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。其中包括复合操作符。
赋值操作符 | 描述 | 实例 |
= | 简单的赋值运算符,把右边操作数的值赋给左边 | C=A+B将A+B的值 赋给C |
+= | 加且赋值运算符 | C+=A相当于C=C+A |
-= | 减且赋值运算符 | C-=A相当于C=C-A |
*= | 乘且赋值运算符 | C*=A相当于C=C*A |
/= | 除且赋值运算符 | C/=A相当于C=C/A |
%= | 求模且赋值运算符 | C%=A相当于C=C%A |
<<= | 左移且赋值运算符 | C<<=1相当于C=C<<1 |
>>= | 右移且赋值运算符 | C>>=1相当于C=C>>1 |
&= | 按位与且赋值运算符 | C&=1相当于C=C&1 |
^= | 按位异或且赋值运算符 | C^=A相当于C=C^1 |
|= | 按位或且赋值运算符 | C|=A相当于C=C|1 |
比如:
int x = 10;
x = x+10;
x+=10; //复合赋值
(5)单目操作符:
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
假如a的值是1。
单目操作符 | 描述 | 实例 |
! | 逻辑反操作,用来逆转操作数逻辑状态 | !a为假 |
& | 返回变量的地址 | &a;给出变量实际地址 |
sizeof() | 操作数的类型长度 返回变量的大小 | sizeof(a)将返回4,其中a是整数 |
~ | 对一个数的二进制按位取反 | ~a的值是0 |
* | 间接访问操作符 指向一个变量 | *a;将指向一个变量 |
++ | 自增运算符 | a++得到2 |
-- | 自减运算符 | a--得到0 |
++ 前置、后置++区别:
++i(在使用i之前,先使i的值加1)
i++(在使用i之后,再使i的值加1)
注意:
1、sizeof()不是函数,在求变量大小时可去掉括号,但求类型大小时一定要加括号。
2、放在在sizeof()内部表达式不参与运算。
3、数组名单独放在sizeof()内部,数组名表示整个数组。
4、&数组名—数组名表示整个数组。
5、指针++取决于指针的类型。
(6)关系操作符:
>
>=
<<=
!= 用于测试“不相等”
== 用于测试“相等”
注意一些运算符使用时候的陷陷。比如:
x = get_value();
if(x = 5)
我们将判断的 == 搞成了赋值的 = ,这样的话无论x是多少都会被执行,所以切记不要写错了。
(7)逻辑操作符:
&& 逻辑与
|| 逻辑或
区分逻辑与和按位与,逻辑或和按位或:
1&2----->0
1&&2---->1
1|2----->3
1||2---->1
(8)条件操作符:
exp1 ? exp2 : exp3
如果条件为真则看exp2 ;如果条件为假,则看exp3
(9)逗号表达式:
exp1, exp2, exp3, …expN
注意:
1、逗号表达式,就是用逗号隔开的多个表达式。
2、逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
(10)下标引用、函数调用和结构成员:
1. [ ]下标引用
操作数:一个数组名 + 一个索引值
int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符
[ ]的两个操作数是arr和9。
2. ()函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
3. 访问一个结构的成员
. 结构体.成员名
-> 结构体指针->成员名
三、优先级
由高到低:初等操作符>单目操作符>算术操作符>关系操作符>逻辑操作符>条件操作符>逗号表达式
优先级 | 运算符 | 含 义 | 要求运算 对象的个数 | 结合方向 |
1 | () [] -> . | 圆括号 下标运算符 指向结构体成员运算符 结构体成员运算符 |
| 自左至右 |
2 | ! | 逻辑非运算符 | 1 (单目运算符) | 自右至左 |
~ | 按位取反运算符 | |||
++ | 自增运算符 | |||
-- | 自减运算符 | |||
- | 负号运算符 | |||
(类型) | 类型转换运算符 | |||
* | 指针运算符 | |||
& | 地址与运算符 | |||
sizeof | 长度运算符 | |||
3 | * / % | 乘法运算符 除法运算符 求余运算符 | 2 (双目运算符) | 自左至右 |
4 | + - | 加法运算符 减法运算符 | 2 (双目运算符) | 自左至右 |
5 | << >> | 左移运算符 右移运算符 | 2 (双目运算符) |
|
6 | < <= > >= | 关系运算符 | 2 (双目运算符) | 自左至右 |
7 | == != | 等于运算符 不等于运算符 | 2 (双目运算符) | 自左至右 |
8 | & | 按位与运算符 | 2 (双目运算符) | 自左至右 |
9 | ^ | 按位异或运算符 | 2 (双目运算符) | 自左至右 |
10 | | | 按位或运算符 | 2 (双目运算符) | 自左至右 |
11 | && | 逻辑与运算符 | 2 (双目运算符) | 自左至右 |
12 | || | 逻辑或运算符 | 2 (双目运算符) | 自左至右 |
13 | ? : | 条件运算符 | 3 (三目运算) | 自右至左 |
14 | = += -= *= /= %= >>= <<= &= ^= |= | 赋值运算符 | 2 | 自右至左 |
15 | , | 逗号运算符 |
| 自左至右 |