操作符优先级(详细说明+表格+问题表达式)

目录

前言

优先级

结合性

是否控制求值顺序

问题表达式

一、

二、

三、


前言

复杂表达式的求值有三个影响的因素。

  1.  操作符的优先级
  2.  操作符的结合性
  3.  是否控制求值顺序

     两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。

优先级

相邻的两个操作符才考虑优先级!

此处我们(下表)知道" * "优先级大于" + ":

 所以此处是" + "与" * "相邻," * "优先级高,先算" * "。


结合性

相邻的两个操作符的优先级一样时,先算什么就是结合性说的算!

 此处我们(下表)知道加法的结合性,是从左到右:

此处二者优先级相同,所以是从左到右计算,先" a "再" b "再" 2 "。


 当相邻操作符的优先级不同的情况下,优先级先起作用;优先级相同的情况下,那这个时候的结合性起作用。


是否控制求值顺序

这个是十分特殊的,只有少部分几个为是。(以" && "与" || "为例)

 我们按照心中常理分析,会感觉应该输出为a = 1 b = 3 c = 3 d = 5。但是其真实的输出为:

这就是因为其是会控制求值顺序的!

我们知道" && "是错一个即为错," || "是对一个即为对。此处的" && "的第一个是为后置++,先使用时a = 0,即为错,既然已经有一个错误了,那后面为什么都已经没有了必要,所以后面将不会再进行计算,这也就只是执行了" a++ "。这控制了求值顺序!


注:优先级和结合性,只决定运算符和哪些操作数结合和求值顺序毫无关系。

建议:

       我们这地方也没有必要特别刻意的把这个优先级啊,全部背下来,没什么大问题,没什么用啊,实际上呢,我们正在写的过程,实在没法拿捏的准时,查一下表,实在是懒了,都不想查的时候,你把它给括号一下,括号明确的时候就可以解决优先级问题。

从上到下优先级,由高到低

     操作符    描述           用法示例   结果类型     结合性是否控制求值顺序
( )聚组( 表达式 )与表达式同
( )函数调用函数名 (形参表)表达式左到右
[ ]下标引用数组名 [常量表达式]变量左到右
.访问结构成员对象 . 成员名变量左到右
->访问结构指针成员对象指针 -> 成员名变量左到右
++后缀自增变量名 ++表达式右到左
--后缀值减变量名 --表达式右到左
 !逻辑反! 表达式表达式右到左
~按位取反~ 表达式表达式右到左
+单目,表示正数+ 表达式表达式右到左
-单目,表示负数- 表达式表达式右到左
++前缀自增++ 变量名表达式右到左
--前缀自减-- 变量名表达式右到左
*间接访问* 指针变量变量右到左
&取地址& 变量名表达式右到左
sizeof取其长度,以字节表示sizeof (表达式)表达式右到左
(类型)类型转换(数据类型) 表达式表达式右到左
*乘法表达式 * 表达式表达式左到右
/除法表达式 / 表达式表达式左到右
%整数取余整型表达式 % 整型表达式表达式左到右
+加法表达式 + 表达式表达式左到右
-减法表达式 - 表达式表达式左到右
<<左位移变量 << 表达式表达式左到右
>>右位移变量 >> 表达式表达式左到右
>大于表达式 > 表达式表达式左到右
>=大于等于表达式 >= 表达式表达式左到右
<小于表达式 < 表达式表达式左到右
<=小于等于表达式 <= 表达式表达式左到右
==等于表达式 == 表达式表达式左到右
!=不等于表达式 != 表达式表达式左到右
&位与表达式 & 表达式表达式左到右
^位异或表达式 ^ 表达式表达式左到右
|位或表达式 | 表达式表达式左到右
&&逻辑与表达式 && 表达式表达式左到右
||逻辑或表达式 || 表达式表达式左到右
? :条件操作符

表达式 ?表达式2 :  表达式 3

表达式
=赋值变量 = 表达式表达式右到左
+=以…加变量 += 表达式表达式右到左
-=以…减变量 -= 表达式表达式右到左
*=以…乘变量 *= 表达式表达式右到左
/=以…除变量 /= 表达式表达式右到左
%=以…取模变量 %= 表达式表达式右到左
<<=以…左移变量 <<= 表达式表达式右到左
>>=以…右移变量 >>= 表达式表达式右到左
&=以…与变量 &= 表达式表达式右到左
^=以…异或变量 ^= 表达式表达式右到左
|=以…或变量 |= 表达式表达式右到左
逗号表达式 , 表达式 , …表达式左到右

       但是,即使具有优先级,结合性,是否控制求值顺序。表达式是无法确定唯一的计算路径的!于是就会出现一些问题表达式!


问题表达式

无法确定所写的代码的唯一计算路径的,那这个代码就是问题代码!

       在计算的时候,由于" * "比" + "的优先级高,只能保证," * "的计算是比" + "早,但是优先级并不能决定第三个" * "比第一个" + "早执行(他们之间是不相邻的,无法利用优先性)。当abcdef为表达式时,不确定的多路径计算会带来不同的答案!(例如:分别都引用了一个变量" x ",就会导致谁先引用," x "先变为什么,然后再被引用。)


       " c + --c "就是一个问题代码,虽然我们知道" 前置-- "与" + "优先级是前者大于后者,但是,这还是一个问题代码,因为我们根本无法知道前者c是什么时候准备好的,很可能减后猜准备,有可能还未减时才准备。(这就是随编程器所定的了,所以,其并不是只有一个计算路径。)

类似于上者的代码(资料来源与《C与指针》)

 如此多的编译器答案都大大不同!


      我们能通过操作符的优先级得知:先算乘法, 再算减法。但是,函数的调用先后顺序无法通过操作符的优先级确定。

如果,按照顺序调用函数:

  1. (2——3——1)那就是:4 - 2 - 3 = -2;
  2. (1——2——3)那就是:2 - 3 * 4 = -10;
  3. ……

这是无法确定唯一路径的。(毕竟,函数什么时候调用是没有标准的。)

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

川入

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值