c语言中的求值顺序

首先弄清楚一个问题:求值顺序不是运算顺序

Q:什么是运算顺序?

A:运算顺序就是根据运算符号的优先级(结合性)来进行求值的过程

Q:什么是求值过程?

A:举个例子吧, D = A + B + C, 运算顺序是 A 先加 B 再加 C, 但是c语言并没有规定是先计算A的值还是B的值还是C的值; 这就是求值顺序。

求值顺序在某些情况下很值得注意

比如: f(), g(), h()是三个函数, 现在 a = f() + g() + h(), 运算顺序保证了f()首先与g()相加然后再加h(), 但是先计算哪个函数的值是不确定的[可能是f(), 可能是g(), 也可能是h()]。如果f(), g(), h()里面都引用了某个全局变量(不一定非要是全局变量), 那么先计算某个函数的值导致的 最后结果 a 也会不一样。比如: 你认为f()函数先调用, 然后是g(), 最后是h(); 这样在g()函数里面调用的全局变量的值就是 f()函数已经操作过的(可能已经更改), 同样h()操作的全局变量是已经经过了f()和g()函数操作的。但是事实上编译器并不一定要先计算f()函数, 相反可能会先计算h()函数, 这样 最后 a 的值就与你想象中的不是同一个数字。

c语言中有四个运算符规定了求值顺序

  • &&
  • ||
  • ?:

解释:

  • 对于&&和||运算符, 首先对做操作数进行求值, 如果这个表达式的值已经确定了, 那么不会对有操作数求值。对于三目运算符, a?b:c; 首先对操作数a求值, 根据a的值求操作数b或者c的值。对于逗号运算符, 首先对左操作数就进行求值, 然后将该值“丢弃”, 再对右操作数进行求值。

最后引用c陷阱与缺陷中的一个例子

下面这种从数组x中复制前n元素到数组y中的做法是不正确的, 因为对求值顺序进行了太多假设:


i = 0;
while(i < n)
y[i] = x[i++]

问题出在哪里呢? 上面的代码假设y[i]的地址将在i的自增操作执行之前被求值, 这一点并没有任何保证!在C语言的某些实现上, 有可能在i自增之前被求值; 而在另外的一些实现上, 有可能与此相反。同样的道理, 下面这种版本的写法与前类似, 也不正确


i = 0;
while(i<n)
y[i++] = x[i];

而另一方面, 下面这种写法却能正常工作:


i = 0;
while(i < n)
{
y[i] = x[i];
i++
}

当然这种写法可以简写为:

`for (i = 0; i < n; i++)
{
y[i] = x[i];
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值