律师网络推广,seo整站优化外包公司,开封网站开发公司,具有口碑的柳州网站建设哪家便宜上一篇文章传送门#xff1a;操作符上 前言#xff1a;上期我们介绍了C语言的操作符的使用方法#xff0c;这期我们主要侧重讲当我们已经了解了操作符的基本知识后怎样样来看待运算路径的问题。 操作符 一#xff0c;优先级和结合性1#xff0c;优先级2#xff0c;结合性…上一篇文章传送门操作符上 前言上期我们介绍了C语言的操作符的使用方法这期我们主要侧重讲当我们已经了解了操作符的基本知识后怎样样来看待运算路径的问题。 操作符 一优先级和结合性1优先级2结合性 二表达式求值1整型提升2算术转换 三表达式解析 一优先级和结合性 上期我们介绍了很多操作符包括像算数操作符位操作符移位操作符等。但还有一个问题就是我们虽然已经知道这些操作符怎么用但却不知道它们是按照什么顺序来运算的。这就要讲到操作符的2个属性——优先级和结合性优先级和结合性就是用来解决这一问题的。 1优先级
举个例子34*5看到这段代码我们自然而然的就会想到先算乘除再加减这是基于我们在数学上学过这个优先级才知道的。但C语言操作符有很多是我们没学过的怎么办呢别担心我有一张表可以让你一览无余 这个表格能很清晰的告诉我们优先级的顺序优先级很明显就是在一个表达式中谁优先级高谁就先运算。 但是这又会产生一个问题就是如果表达式中所有操作符的优先级都相同那怎么看呢 这就要看结合性了。
2结合性 前面我们说了当一个表达式中所有的操作符的优先级都一致的时候是无法判断先算哪个了这时候就要看结合性了看是左结合从左到右执行还是右结合从右向左执行。 列如3 * 5 / 2 我们知道乘除的优先级是相同的这时候看结合性我们通过观察上面的表格就会发现他们都是左结合的所以是从左到右去计算。 下面是部分优先级的结合顺序(从高到低)注意大概记住就行实在记不住可以查表 • 圆括号 () • ⾃增运算符 ⾃减运算符 – • 单⽬运算符 和 - • 乘法 * 除法 / • 加法 减法 - • 关系运算符 、 等 • 赋值运算符 实在不行的话读者可以在写代码的时候直接用括号就行括号的优先级最高。 这里我们给出C语言关于优先级的参考C语言的优先级。
看完了优先级和结合性紧接着我们就可以来看表达式了
二表达式求值
1整型提升
各位读者第一次看到这个概念可能回比较的懵我们直接拿出一段代码来举例
#includestdio.h
int main()
{char a 10;char b 120;char c ab;printf(%d,c);
}我i们来看结果为什么输出的-126呢按照常理12010应该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 b1 变量a的二进制位补码只有8个比特位 因为char类型占1个字节8比特位。 00000001 因为char a为有符号的char所以再整形提升的时候在剩余的24个字节中补充符号位 即0 整形提升后为 00000000 00000000 00000000 00000001 了解完正负数的整形提升之后我们回过头来分析上面代码的结果。 首先我们用的是%d占位符是打印10进制整数的占位符其次从图不难看出char类型的取值范围为-128~127所以10120是不可能得到130的。这就解决了我们上面的疑问。 这时又要有人问了如果用的是不同类型运算呢会怎么样那就要涉及算术转换了。
2算术转换
算术转换说的是如果某个操作符的各个操作数属于不同的类型那么除⾮其中⼀个操作数的转换为另⼀个操作数的类 型否则操作就⽆法进⾏。 下⾯的层次体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int如果某个操作数的类型在上面这个列表中排名靠后那么首先要转换为另外⼀个操作数的类型后执行 运算。比如 int a10 double b 20.0 那么ab运算时由于double排名靠前所以int a 会被转化成double a。然后再进行计算 。 当我们了解这些基本的知识以后我们就可以来看一些表达式了。
三表达式解析
表达式1a*bc*de*f 这个表达式的运算路径是什么呢 首先因为我们知道表达式的求值部分由优先级来决定所以我们只知道先乘再加是不知道哪个乘法先算所以造成运算循序有很多种。比如 这里就不一一列举。
表达式2 c --c; 这段代码歧义就是我们不知道第一个c是使用 - - c后的值还是 - - c之前的值来计算。比如c5 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后再去执行三次加法所以44412结果就是这么得到的。 但实际上将这段代码复制到devc上运行结果也是不同的大家可以试试。 这段代码中的第⼀个 在执行的时候第三个是否执行这个是不确定的因为依靠操作符的优先级和结合性是无法决定第⼀个 和第三个前置 的先后顺序。 所以这种代码也是有争议的大家要避免写出这种代码
注意有关结构的操作符将在结构章节进行介绍
以上就是操作符的所有内容啦 感谢能够看到这里的读者如果我的文章能够帮到你那我甚是荣幸文章有任何问题都欢迎指出制作不易还望给一个免费的三连你们的支持就是我最大的动力