目录
二.算术运算符
三.自增自减运算符
四.赋值运算符
五.关系运算符
六.逻辑运算符
七.三元运算符
九.运算符的优先级
一.前言
c语言的运算符可以分为六种,分别是:1.算术运算符;2.自增自减运算符;3.赋值运算符;4.关系运算符;5.逻辑运算符;6.三元运算符。
下面我们来深入学习了解它们。
二.算术运算符
算术运算符里面主要包括加减乘除以及取余运算。对于加减乘除,想必大家早就不陌生了。但在c语言里面值得注意的是在进行算术运算的时候,所得的结果还需要考虑参与运算数据的数据类型。我在这里列举出来四种:
1)两个整数计算,得到的结果一定是整数。
2)两个小数计算,得到的结果一定是小数。
3)整数和小数计算,得到的结果也一定是小数。
4)这里两个小数直接参与计算,结果是有可能不精确的。所以不建议使用小数进行运算。
如下所示:
#include<stdio.h>
int main(){
//整数与整数的计算
printf("%d\n", 2 + 4);
//整数与小数的运算
printf("%lf\n", 3 * 6.0);//小数与小数直接运算,结果可能不准确
printf("%lf\n", 3.33333333333 + 6.666666666666);return 0;
}
分别对上述情况展开运算,得到的结果如下:
可以看到,第三个结果是两个小数计算后的结果,数据发生了改变,并没有输出正确的结果。
除此之外,我们在使用运算符进行计算的时候,还可能会遇到当我们参与运算的两个数据的数据类型不一致的时候,就会出现隐式转换的情况,或者需要强制转换的情况。
这里我来介绍下什么是隐式转换:隐式转换就是把一个取值范围小的数据类型转换为取值范围更大的数据类型。其中特殊的有short和char类型首先会提升为int类型,再进行运算。
这里涉及取值范围的问题,我们就可以了解下几种数据类型的取值范围排序了:
char<short<int<long<long long<float<double.
下面我们来看一个案例:
int i = 1;
double s = 3.2;
printf("%zu", sizeof(i * s));
输出的结果如下:
这里我们发现,i的数据类型是int类型,而我们的s数据类型是double,根据取值范围排序,我们就知道这里会进行隐式转换,并且最后的结果会转换double类型,所以在使用sizeof()来进行字节大小判断的时候,结果才会是8个字节,而不是4个字节。
而我们的强制转换则恰恰相反,是把一个取值范围大的赋值给取值范围小的。它的格式如下:
目标数据类型 变量名=(目标数据类型)被强转的数据。
但一般我们不推荐使用,因为会有可能造成数据的丢失。
三.自增自减运算符
关于这个,我们只需要了解下面的原则即可:
首先是自增自减的前缀优先级要高于后缀的优先级。
然后前缀会统一自增自减,再把结果拿来用。而后缀则是会统一先用,等整个表达式中的变量用完了,再进行自增自减操作。
下面我们来看一个案例:
int a = 10;
//前缀统一先加,再把结果相加
int k1 = ++a + ++a; //12+12=24 a=12
//后缀统一先用,等整个表达式中的变量用完后,再进行自增操作
int k2 = a++ + a++; //12+12=24 a=14int k3 = ++a + a++; //15+15=30 a=16int k4 = a++ + ++a; //16+18=34 a=18
printf("%d\n", k1);
printf("%d\n", k2);
printf("%d\n", k3);
printf("%d\n", k4);
通过程序我们可以发现,k1表达式中都是前缀自增,所以我们先进行自加,两个++a,a的值也就从10变为了12,所以最后k1=12+12=24。k2表达式则都是后缀自增,因此我们先用,也就是k2=12+12=24,但是这里a的值也变为了14。 而k3表达式有前缀也有后缀,我们遵循前缀优于后缀的原则,所以先进行++a,所以a=15;后缀则是先用,因此k3=15+15,在进行完计算后,a的值还会进行自加,也就是变为了16.同理,k4=16+18=34.
综上所述,所以最后的结果也就是:
四.赋值运算符
简而言之,就是在赋值的操作上,简化其代码。
例如,a=a+b,通过使用加后赋值的方法,可以简化为a+=b,二者是相互等同的。
五.关系运算符
关系运算符是用来判断等式两边数据大小,相等关系的。它的运算结果只有两者情况,一种要是关系成立,则会返回结果1。否则会返回结果0。
例如:
int a=12;
int b=30;
printf("%d\n",a>b);
a>b自然是不成立的,因此最后的结果也就是0
六.逻辑运算符
逻辑运算符主要有三种:1.&&是与(而且),只有当两边都为真的时候,结果才是真。
2.|| 是或(或者),只有当两边都为假的时候,结果才为假。
3.! 是非(取反),起到一个取反的作用。
值得注意的是,逻辑运算符一般具有短路的效果:也就是当左边的表达式能够确定整个表达式的结果的时候,右边表达式就不再参与运算。
例如 我们来看下面这段代码:
int a = 1;
int b = 2;
if (a < b && b + 1) {printf("%d\n", a);printf("%d\n", b);
}
运行结果为:
因此我们可以看到&&左边的表达式是a<b,是成立的,因此右边表达式也就不再执行,所以b的值还是2,并没有加1。
然后我们来看另外一段相似的代码:
int a = 1;
int b = 2;
if (a > b || b++) {printf("%d\n", a);printf("%d\n", b);
}
运行的结果是:
这里我们可以看到,b的值发生了改变,原因就是因为||左边的表达式不成立,因此会执行右边表达式,也就是b++。
七.三元运算符
三元运算符的格式为:关系表达式?表达式1:表达式2;
也就是首先会进行关系表达式的判断,要是结果为真,则执行表达式1,否则执行表达式2。
八.逗号运算符
关于逗号运算符,我们只需要知道,它的优先级最低,可以对变量的各个操作放在同一行代码当中实现,如上图所示。
九.运算符的优先级
我们在学习了所以运算符之后,我们来了解一下各个运算符的优先级。在这里我已经帮大家做成了一个表格,如下,下次只需要参照这个表格就可以了。