ToB企服应用市场:ToB评测及商务社交产业平台
标题:
C语言操作符(下)
[打印本页]
作者:
张春
时间:
2025-1-24 15:07
标题:
C语言操作符(下)
上一篇文章传送门:操作符上
前言:上期我们介绍了C语言的操作符的利用方法,这期我们重要偏重讲当我们已经相识了操作符的基本知识后怎样样来看待运算路径的问题。
一,优先级和结合性
上期我们介绍了很多操作符,包括像算数操作符,位操作符,移位操作符等。但还有一个问题就是我们虽然已经知道这些操作符怎么用但却不知道它们是按照什么顺序来运算的。这就要讲到操作符的2个属性——
优先级和结合性
,优先级和结合性就是用来解决这一问题的。
1,优先级
举个例子:
3+4*5
看到这段代码我们天然而然的就会想到先算乘除再加减,这是基于我们在数学上学过这个优先级才知道的。但C语言操作符有很多是我们没学过的怎么办呢?别担心,我有一张表可以让你一览无余:
这个表格能很清晰的告诉我们优先级的顺序,优先级很明显就是在一个表达式中谁优先级高谁就先运算。
但是这又会产生一个问题,就是如果表达式中全部操作符的优先级都相同那怎么看呢?
这就要看结合性了。
2,结合性
前面我们说了,当一个表达式中全部的操作符的优先级都同等的时间是无法判断先算哪个了;
这时间就要看结合性了,看是左结合(从左到右执行)还是右结合(从右向左执行)。
列如:
3 * 5 / 2
我们知道乘除的优先级是相同的这时间看结合性,我们通过观察上面的表格就会发现他们都是左结合的以是是从左到右去盘算。
下面是部分优先级的结合顺序(从高到低)注意大概记住就行,实在记不住可以查表:
• 圆括号( () )
• ⾃增运算符( ++ ),⾃减运算符( – )
• 单⽬运算符( + 和 - )
• 乘法( * ),除法( / )
• 加法( + ),减法( - )
• 关系运算符( < 、 > 等)
• 赋值运算符( = )
实在不行的话读者可以在写代码的时间直接用括号就行,括号的优先级最高。
这里我们给出C语言关于优先级的参考:C语言的优先级。
看完了优先级和结合性紧接着我们就可以来看表达式了:
二,表达式求值
1,整型提升
各位读者第一次看到这个概念可能回比力的懵,我们直接拿出一段代码来举例:
#include<stdio.h>
int main()
{
char a = 10;
char b =120;
char c = a+b;
printf("%d",c);
}
复制代码
我i们来看结果为什么输出的-126呢?按照常理120+10应该130才对啊,怎么会出现个-126呢?要回答这两个问题就要涉及到整型提升了。我们来看看整型提升的概念
整型提升说的是在C语言中整型算术运算总是至少以缺省(默认)整型范例的精度来进⾏的。 为了获得这个精度,表达式中的字符和短整型操作数在利用之前被转换为普通整型,这种转换称为整型提升。
好比上面代码中char a和char b 在运算的时间直接被提升为普通整型, 然后再举行加法盘算,盘算的结果被阶段存在c中。
那如何举行整形提升呢?
负数的整形提升
:
char a=-1
变量a的二进制位(补码)只有8个比特位
因为char范例占1个字节8比特位。 11111111
因为char a为有符号的char,以是再整形提升的时间在剩余的24个字节中
补充符号位
即1
整形提升后为:11111111 11111111 11111111 11111111
正数的整形提升
:
char b=1
变量a的二进制位(补码)只有8个比特位
因为char范例占1个字节8比特位。 00000001
因为char a为有符号的char,以是再整形提升的时间在剩余的24个字节中
补充符号位
即0
整形提升后为: 00000000 00000000 00000000 00000001
相识完正负数的整形提升之后我们回过头来分析上面代码的结果。
首先我们用的是%d占位符是打印10进制整数的占位符,其次从图不丢脸出char范例的取值范围为-128~127,以是10+120是不可能得到130的。这就解决了我们上面的疑问。
这时又要有人问了如果用的是不同范例运算呢?会怎么样?那就要涉及算术转换了。
2,算术转换
算术转换说的是如果某个操作符的各个操作数属于不同的范例,那么除⾮此中⼀个操作数的转换为另⼀个操作数的类 型,否则操作就⽆法进⾏。
下⾯的条理体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int
复制代码
如果某个操作数的范例在上面这个列表中排名靠后,那么首先要转换为另外⼀个操作数的范例后执行 运算。好比
int a=10 double b =20.0 那么a+b运算时由于double排名靠前以是int a 会被转化成double a。然后再举行盘算
。
当我们相识这些基本的知识以后我们就可以来看一些表达式了。
三,表达式解析
表达式1:
a*b+c*d+e*f
这个表达式的运算路径是什么呢?
首先因为我们知道表达式的求值部分由优先级来决定,以是我们只知道先乘再加是不知道哪个乘法先算,以是造成运算循序有很多种。好比
这里就不一一枚举。
表达式2:
c + --c;
这段代码歧义就是我们不知道第一个c是利用 - - c后的值还是 - - c之前的值来盘算。好比c=5
c+ -- c
可能是5加4也可能是4加4以是这就存在歧义。
表达式3:
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
复制代码
这种其实就是错误代码,因为其在不同的编译器下有不同的结果,一定要制止写出这种代码!
表达式4:
#include <stdio.h>
int fun()
{
static int count = 1;
return ++count;
}
int main()
{
int answer; answer = fun() - fun() * fun();
printf( "%d\n", answer);//输出多少?
return 0;
}
复制代码
但是上述代码 answer = fun() - fun() * fun(); 中我们只能通过操作符的优先级得知:先 算乘法,再算减法,函数的调用先后顺序无法通过操作符的优先级确定。
表达式5:
#include <stdio.h>
int main()
{
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0;
}
复制代码
ret为12为什么会得到12我们来看看反汇编代码就明白了
这段代码的反汇编代码现实上就一直在执行++i这个操作当每个i加到4后再去执行三次加法,以是4+4+4=12结果就是这么得到的。
但现实大将这段代码复制到devc++上运行结果也是不同的,各人可以试试。
这段代码中的第⼀个 + 在执行的时间,第三个++是否执行,这个是不确定的,因为依靠操作符的优先级和结合性是无法决定第⼀个 + 和第三个前置 ++ 的先后顺序。
以是这种代码也是有争议的各人要制止写出这种代码!
注意:有关结构的操作符将在结构章节举行介绍!
以上就是操作符的全部内容啦!
感谢能够看到这里的读者,如果我的文章能够帮到你那我甚是荣幸,文章有任何问题都欢迎指出!制作不易还望给一个免费的三连,你们的支持就是我最大的动力!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4