目录
算数操作符
+ - * / %
除了%(两边的操作数必须是整数)外,其他算数操作符的操作数可以是整数和浮点数。
若 / 的两个操作数都是整数,那么计算结果就是整数,例如3/2=1;如果两个操作数中有一个是浮点数,那么结果就是浮点数。
移位操作符
<< >>
移位操作符的操作数必须是整数。
左移位操作符
将二进制数的所有位左移n位,高位抛弃,低位补0。
右移位操作符
右移分为两种:逻辑移位和算数移位,但大多数都是算数移位。
算数右移
高位补符号位,低位舍弃。
逻辑右移
高位补0,低位舍弃。
例子:
-1补码的32位全是1
注意,不要移动负数位,标准未定义。
位操作符
操作数必须是整数
& 按位与
依次根据两个二进制数相同位上的数计算,全1为1,有0为0
| 按位或
依次根据两个二进制数相同位上的数计算,全0为0;有1为u
^ 按位异或
依次根据两个二进制数相同位上的数计算,相同为0,不同为一
赋值操作符
这个很简单,就是对变量进行赋值。
例如,int n = 2;
复合赋值符
可以理解为将算数操作符、移位操作符或位操作符与赋值操作符结合,可以使代码看起来更简洁。例如+=、>>=等,这里不一一列举了。
a += b与a = a + b是等价的。
单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
sizeof
sizeof内部不参与运算
这里a+3的值并没有赋给n,可以理解为sizeof直接判断n的类型大小,不进行计算。
sizeof vs 数组
在定义数组所在的函数中使用sizeof,计算的时整个数组的大小;将定义好的数组传参传给函数时,在函数中sizeof计算的是指针的大小(32位系统中是4,64位系统中是8)。因为传给函数的只是数组的首元素地址。
++a 与 a++
前置++是先对a进行自加,再对a进行操作;后置++是先对a进行操作,再自加。
关系操作符
>
>=
<
<=
!= 不相等
== 相等
关系操作符非常简单,但注意==很容易写成=,导致错误。为了避免这些错误,我们可以改变判断条件的写法,例如a == 1,我们可以写成1 == a,当我们不小心写成=时,编译器就会报错。
逻辑操作符
&& 逻辑与
|| 逻辑或
逻辑与 vs 按位与
1 &2 = 0
1 && 2 = 1
逻辑或 vs 按位或
1 | 2 = 3
1 || 2 = 1
逻辑与左边为假,结果一定为假,右边无需计算;
逻辑或左边为真,结果一定为真,右边无需计算。
条件操作符
exp1 ? exp2 : exp3
判断第一个表达式是否为真,若为真则返回exp2;若为假返回exp3。
例如,获得两个数的最大值
int n = (a > b ? a : b)
逗号表达式
exp1, exp2,…,exp n
从左向右依次执行,最后一个表达式的结果就是整个表达式的结果。
巧妙利用逗号表达式可以使代码更简洁:
#include<stdio.h>
//要求:输入正数
int main()
{
int n = 0;
scanf("%d", &n);
while (n <= 0)
{
scanf("%d", &n);
}
printf("%d", n);
//使用逗号表达式
while (scanf("%d", &n), n <= 0)
{
;
}
printf("%d", n);
return 0;
}
下标引用、函数调用和结构体成员访问操作符
下标引用操作符[ ]
arr[9] = 10;
[ ]的操作数是arr和9。
函数调用操作符( )
strlen("abcdef");
( )的操作数是函数strlen和参数"abcdef"。
结构体成员访问操作符
. 结构体变量 . 结构体成员名
-> 结构体变量指针 -> 结构体成员名