目录
一元运算符 > 二元运算符 > 三元运算符
1、赋值运算符
将运算符右侧的值赋值给左侧的变量(赋值运算符是二元运算符,赋值运算符的优先级最低---低于三元运算符)
赋值运算符: = += -= *= /= %= &= |= >>= <<= ~= ^=
简单赋值运算符: =
将右侧的值赋值给左侧的变量
int a = 34;
int a;
a = 34;
int b;
b = a;
/*
一般情况:数据类型相同的变量就可以互相赋值
*/
复合赋值运算符:+= -= *= /= %= &= |= >>= <<= ~= ^=
左右两侧操作完毕后,赋值给左侧的变量
int a = 2;
a += 3; //等效 a=a+3;
a %= 2; //等效 a=a%2; //a=>1
注意:
1.在运算时,不能将单等号(=)写成双等号(==); 单等号是赋值运算符, 双等号是关系运算符
2.赋值运算符的优先级最低(仅高于逗号运算符)
int a = 3 > 4 && 5 < 6 + 1
算法运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符
2、关系运算符
主要包含:> < >= <= == !=
1.所有的关系运算符都是二元运算符,左侧和右侧可以是变量也可以是常量,还可以是表达式
2.关系运算符运算的结果要么为真(1),要么为假(0)
说明:
1.标准C中没有布尔类型:非0代表真,0代表假
while(0); //循环一次都不执行
while(34); //死循环
2.真在输出是结果为1, 假在输出是结果为0
printf("%d\n", 3<2); // 结果为0,代表假
printf("%d\n", 2<3); // 结果为1,代表真
3.浮点数进行关系运算的特点:
1.浮点数是近似存储,在关系运算时,建议数据类型要相同;
2.浮点数如果要精确比较:
将两个浮点数相减的结果如果在某个极小范围内,我们能够接受,就人为这两个数相等
3、逻辑运算符
包括:! && ||
逻辑运算符的运算结果要么为真(1), 要么为假(0)
!非(逻辑非):是单目运算符,并且只能放在操作数的左侧;非真结果为假,非假结果为真
对一个数或表达式取非偶数次,结果和原来相同
int a = 3; printf("%d\n", !!!!a); //1代表真
对一个数或表达式取非奇数次,结果和原来相反:
int a = 3; printf("%d\n", !!!a); //0代表假
&&与(逻辑与/双与): 是双目运算符,当左右两侧的数据都为真时,最终结果才为真 (有假则为假)
&&有短路效果:它的左侧如果为假,右侧的结果不会影响最终的结果,右侧压根也不会执行,这种现象称为短路效果
||或(逻辑或/双或): 是双目运算符,当左右两侧的数据都为假时,最终结果才为假 (有真则为真)
||有短路效果:它的左侧如果为真,右侧的结果不会影响最终的结果,右侧压根也不会执行,这种现象称为短路效果
4、位运算符
会将数据转换成二进制后,按位运算
包括:& | ^ ~ >> <<
&位与:会将数据转换成二进制后,按位运算;有0则为0
| 位或:会将数据转换成二进制后,按位运算;有1则为1
^ 位异或:会将数据转换成二进制后,按位运算;相同为0,不同为1(磁铁关系,男女朋友)
^ 用法的扩展:使用 ^ 可以在进行两个变量进行值交换时,不需要引用第三个标量仅能实现
//将变量a和b进行值交换,不引入第三个变量
#include<stdio.h>
int main()
{
int a = 100,b = 101;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d\tb = &d\n",a ,b);
return 0;
}
~按位取反:是单目运算符,只能放在操作数的左侧;会将数据转换成二进制后,按位运算;0变1,1变0
<<左移 :会将左侧数据转换成二进制后,按位运算;将转换后的二机制数向左移动右侧数据次, 右侧补0
结论:
在不越界的前提下:将m左移n位的公式: m * 2 ^ n
>>右移 :会将左侧数据m转换成二机制后,移动右侧数据n次,最高位补0或者1
根据系统平台确定是算数右移还是逻辑右移(多数系统都是算数右移)
如果是算数右移:如果是正数,最高位补0,如果是负数最高位补1
如果是逻辑右移:不论是正数还是负数,最高位都补0
结论:
在不越界前提下,正数右移的公式: 将m右移n次: m / 2^n
5、三元运算符(? :)
格式:表达式1?表达式2?表达式3
三元运算符表达式的应用场景:
1.将三元运算表达式赋值给一个变量
变量的数据类型应该和冒号左右两侧的数据类型一致;建议冒号左侧和右侧的数据类型要一样;
如果冒号左侧和右侧的数据类型不一样,应该用什么类型的变量接收呢?
选择数据类型优先级高的数据类型
2.将三元运算表达式的结果直接输出
//三元运算符
#include<stdio.h>
int main()
{
int a,b,c;
scanf("%d%d",&a,&b);
c = a > b ? a : b;
printf("%d",c);
//判断偶数,偶数输出1,奇数输出0
int num =5;
int result = (num % 2 == 0)?1:0;
printf("%s\n", result);
return 0;
}
注:三元运算符可以进行多层嵌套,可以达到比较大小的效果
6、逗号运算符
int a, b; //这是一句话定义两个int类型的变量
int a=2, b=3; //一句话定义两个变量,并分别给他们赋值
int a, b, *c; //c变量的数据类型是 int* ---int类型的指针
int* a, b, *c; //a,b的数据类型int*, c变量的数据类型int** ---int类型的二级指针类型
//以上案例都说明,号的作用是并列关系
int a = 9, int b = 10; //错误格式
int a = 9; int b = 10; //正确格式
//逗号作为运算符
int y;
int z;
int x = (3, y+=4, z=6); //小括号整体的值就是最后一个逗号后面数据的值
7、运算符的优先级
1.不用刻意记忆;因为在编写程序时,可以加小括号提升优先级
2.分类分层记忆:
2.1:括号的优先级最高 --- (), []; 结构体的成员访问符的优先级和括号一样
2.2:单目运算符 :! ~ ++ -- * sizeof 等
2.3:双目运算符
算数运算符 > 关系运算符 > 逻辑运算符
位运算符在关系运算符的前后分布:移位运算在前,其他位运算符在后
2.4:三目运算符 ?:
2.5: 赋值运算符的优先级最低
3.运算顺序:除过赋值运算符,其他的运算符都是从左向右运算