操作符优先级
算数操作符
有加+
、减-
、乘*
、除/
、求余%
五种算数操作符。
【注意】
%
操作符的两个操作数必须为整数,返回的是整除之后的余数。
对于/
操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
例如:10/3=3
,10/3.0=3.333333
,10.0/3=3.333333
移位操作符
移位操作符有两个,分别是:左移操作符和右移操作符。
左移操作符(<<)
左边抛弃,右边补0。
int main()
{
int a = 1; //定义一个整型变量a并赋初值为1
a = a << 1; //将变量a左移一位
printf("%d",a); //输出2
return 0;
}
移位运算符会首先将值转换为二进制,例如上面代码中,1的补码为0000 0000 0000 0000 0000 0000 0000 0001
,左移一位,就会变成0000 0000 0000 0000 0000 0000 0000 0010
,再转换为十进制就是2。
右移操作符(>>)
右边丢弃,左边补原符号位(正数补0,负数补1)
int main()
{
int a = -4;
a = a >> 1; //右移1位
printf("%d",a); //输出-2
return 0;
}
【拓展】
负数的反码 = 原码符号位不变,其他数值位取反。
负数的补码 = 反码 + 1
正数的原码、反码、补码相同
-4的二进制原码为 1000 0000 0000 0000 0000 0000 0000 0100
-4的二进制反码为 1111 1111 1111 1111 1111 1111 1111 1011
-4的二进制补码为 1111 1111 1111 1111 1111 1111 1111 1100
右移一位后为:1111 1111 1111 1111 1111 1111 1111 1110
(即-2的补码)
位操作符
&
按位与:有0为0。
|
按位或:有1为0。
^
按位异或:相同为0,不同为1。
【注意】位操作符的操作数必须都是整数。
按位与(&)
int main()
{
int x = 5; //0000 0000 0000 0000 0000 0000 0000 0101
int y = 7; //0000 0000 0000 0000 0000 0000 0000 0111
int num = x & y; //0000 0000 0000 0000 0000 0000 0000 0101
printf("%d",num); //输出5
return 0;
}
按位或(|)
int main()
{
int x = 5; //0000 0000 0000 0000 0000 0000 0000 0101
int y = 7; //0000 0000 0000 0000 0000 0000 0000 0111
int num = x | y; //0000 0000 0000 0000 0000 0000 0000 0111
printf("%d",num); //输出7
return 0;
}
按位异或(^)
int main()
{
int x = 5; //0000 0000 0000 0000 0000 0000 0000 0101
int y = 7; //0000 0000 0000 0000 0000 0000 0000 0111
int num = x ^ y; //0000 0000 0000 0000 0000 0000 0000 0010
printf("%d",num); //输出2
return 0;
}
赋值操作符
=
+=
-=
*=
/=
%=
<<=
>>=
&=
|=
^=
【注意】运算符和等号之间是不能有空格的。
int a = 10; //将后面的值赋予给前面的变量。
a += 1; //等同于(a = a + 1)
a -= 1; //等同于(a = a - 1)
a *= 1; //等同于(a = a * 1)
a /= 1; //等同于(a = a / 1)
a %= 2; //等同于(a = a % 2)
a <<= 2; //等同于(a = a << 2),即a左移2位
a >>= 2; //等同于(a = a >> 2),即a右移2位
a &= 2; //等同于(a = a & 2),即变量a的值和2按位与。
a |= 2; //等同于(a = a | 2),即变量a的值和2按位或。
a ^= 2; //等同于(a = a ^ 2),即变量a的值和2按位异或。
单目操作符
只有一个操作数的操作符就被成为单目操作符
!
-
+
&
sizeof
~
--
++
*
(类型)
逻辑反操作(!)
加上!
与之形成相反的逻辑。例如=
,加上!
变为不等于!=
。
对于整型变量,只要不为0,使用!取反后均为1,0取反后为1。(等同于bool类型只有真和假一样,在进行判断时,非0为真,0为假)
负值(-)
正值(+)
取地址(&)
scanf()函数输入时就用到&符号帮我们找到变量的地址,然后在变量地址的内存中存储数据。
int main()
{
int x;
scanf("%d",&x);
return 0;
}
sizeof
sizeof可以计算操作数的类型长度(以字节为长度)。
【注意】不是计算操作数本身长度,而是操作数的类型长度。
int main()
{
int x;
printf("%d", sizeof(x));
return 0;
}
位取反(~)
对于整型变量,转换为二进制,对每一位二进制取反,0变1,1变0。
int main()
{
int i = 1;
printf("%d",~i); //输出-2
//0000 0000 0000 0000 0000 0000 0000 0001 1的补码
//1111 1111 1111 1111 1111 1111 1111 1110 ~1(使1的补码,0变1,1变0)的值,补码形式
//1111 1111 1111 1111 1111 1111 1111 1101 反码(负数的反码 = 补码 - 1)
//1000 0000 0000 0000 0000 0000 0000 0010 原码(负数的原码 = 反码除符号位0变1,1变0),即为-2
return 0;
}
++和--
前置++和--
++i
int main()
{
int i = 10;
printf("%d",++i); //输出11
/*
* ++i
* 先对i自增,然后使用i
* 可以分解为两步
* i = i + 1;
* printf("%d",i); //此时i为11
*/
return 0;
}
--i
int main()
{
int i = 10;
printf("%d",--i); //输出9
/*
* --i
* 先对i自减,然后使用i
* 可以分解为两步
* i = i - 1;
* printf("%d",i); //此时i为9
*/
return 0;
}
后置++和--
i++
int main()
{
int i = 10;
printf("%d",i++); //输出10
/*
* i++
* 先使用i,再i自增
* 可以分解为两步
* printf("%d",i); //此时i为10
* i = i + 1;
*/
return 0;
}
i--
int main()
{
int i = 10;
printf("%d",i--); //输出10
/*
* i--
* 先使用i,再i自减
* 可以分解为两步
* printf("%d",i); //此时i为10
* i = i - 1;
*/
return 0;
}
间接访问操作符(*)
后续指针章节会讲。
强制转换
强制转换类型,将float转换为int
int main()
{
int a = (int)3.14; //将浮点数3.14转换为整型3赋值给整型
printf("%d",a);
return 0;
}
关系操作符
大于>
、大于等于>=
、小于<
、小于等于<=
、不相等!=
、相等==
关系操作符都是用来判断的。
逻辑操作符
逻辑与(&&)
/*
* 如果年龄大于等于18岁,小于等于24岁即可以不用认证享受大学生受惠
*/
int main()
{
int age;
scanf("%d",&age);
if(age >= 18 && age <= 24){ //如果年龄大于等于18岁并且年龄小于等于24岁
printf("您无需大学生认证");
}else{ //否则
printf("您需要先进行大学生认证");
}
return 0;
}
逻辑或(||)
/*
* 如果年龄在小于等于12岁,大于等于60岁,进入动物园免费
*/
int main()
{
int age;
scanf("%d",&age);
if(age <= 12 || age >= 60){ //如果年龄小于等于12岁或者年龄大于等于60岁
printf("无需买票");
}else{ //否则
printf("请先买票");
}
return 0;
}
条件操作符(三元运算符)
语法:条件表达式1 ? 表达式2 : 表达式3;
先判断条件表达式1是否为真,为真执行表达式2,为假执行表达式3。
int main()
{
int a = 10,b = 20;
a > b ? ++a : ++b;
printf("%d %d",a,b); //输出10 21
return 0;
}
首先判断a>b为假,执行++b。所以输出a的值为10,b的值为21。
int main()
{
int a = 10,b = 20,c = 0;
c = a > b ? ++a : ++b;
printf("%d",c); //输出21
return 0;
}
首先判断a>b为假,式子等同于c = ++b;
。所以输出c的值为21。
逗号表达式
它将两个及其以上的式子联接起来,从左往右逐个计算表达式,整个表达式的值为最后一个表达式的值。
如:(3+5,6+8)称为逗号表达式,其求解过程先表达式1,后表达式2,整个表达式值是表达式2的值。
int main()
{
int a = 1,b = 0;
b = (a = 3,a * 4);
printf("%d",b); //输出12
return 0;
}
先将3的值赋值给a,再将a和4相乘,最后赋值给b。输出12。
【注意】以下两个代码结果并不相同
int main()
{
int x = 1,y = 1,z;
z = x++,y++,++y;
printf("%d %d %d",x,y,z); //输出2 3 1
return 0;
}
int main()
{
int x = 1,y = 1,z;
z = (x++,y++,++y);
printf("%d %d %d",x,y,z); //输出2 3 3
return 0;
}
因为逗号表达式优先级最低,所以第一个代码其实上是:(z = x++),y++,++y;
使用逗号表达式时应该特别注意操作符的优先级问题。