关于C语言中表达式运算顺序(优先级、结合性、副作用、序列点)的讨论以及c语言未定义行为

什么是优先级

到底什么是c语言的优先级?
我以前看了国内的很多教程,对于优先级的描述大多都是这样说的“优先级是用来决定当多个运算符出现在同一个表达式中时,先执行哪个运算符”。其实这是个错误的认知
比如以下的c代码

#include<stdio.h>
int main() 
{
   
  int a = 3, b = 2;
  b = a < 0 && a++ > 3;
  printf("a1 = %d , b1 = %d", a, b);
  a = 3, b = 2;
  b = 1 || (a = 1) && (a += 1);
  printf("a2 = %d , b2 = %d", a, b);
  return 0;
}

提示: 优先级 && > || > =/+=
按照国内教程所说的意思,最后的运行结果肯定是 a1 = 4,b1 = 0,a2 = 2, b2 = 1 但是编译器实际输出 a1 = 3,b1 = 0, a2 = 3, b2 = 1
我刚刚开始遇到这个问题的时候也很懵逼???到底为什么会这样???如果编译器是对的那么它的执行思路到底是什么样的?

想要解决这个问题,这就涉及c语言的标准了

C语言标准规定:表达式的结合次序取决于表达式中各种运算符的优先级,其中优先高的运算符优先结合,优先级低的运算符后结合

其次“优先级实际上体现的是一种在运算正式开始之前的预处理,即在预处理阶段会把优先级较高的运算符以及其左右操作符俩边加括号”
例如表达式a+b*c由于 * 优先级比 + 高,所以表达式在预处理阶段被处理成这样 a + (b * c):


显然c语言标准中,优先级只描述的是运算符和操作对象结合的方式(分组方式),并没有规定他先运算什么后运算什么,这取决于编译器的具体优化策略。一条表达式的运算先后顺序只是结合方式的附加产物而已。

看完了标准我们再对 1 | |(a = 1) && (a += 1) ;进行讨论

1.首先由于优先级  && > ||   所以&&左右俩边的操作数会优先结合成为一 个子表达式(在这里我只对=右边的表达式进行讨论,因为等号不会对表达式求值造成影响,具体原因请看关于C语言中a[i] = i++;和a[i++] = i;为什么是未定义行为的讨论)

int b = 1 ||((a = 1) && (a += 1));

2.其次由于   || > =/+=   所以 = 和 += 左右俩边的表达式要结合

int b &#
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值