c语言复合赋值,v + = e与v = v + e有何不同? [关闭]

问题描述 投票:1回答:2

在第4章,本书的复合作业部分:C编程:现代方法,第2版,说:

请注意,我一直小心不要说v += ev = v + e“相当”。一个问题是运算符优先级:i * = j + ki = i * j + k不同。

我写了一个程序来比较i * = j + ki = i * j + k。但结果是一样的。

#include <stdio.h>

int main() {
    int i = 1;
    int j = 2;
    i *= j + 10;
    int k = 1;
    k = k * j + 10;
    printf("j=%d k=%d\n", i, k);
}

结果是:

j = 12 k = 12

所以我的问题是:为什么i * = j + ki = i * j + k不一样?

感谢所有的答复。我误解了复合赋值运算符。而且我写了一个误导性的测试。我想说你们很高兴讨论技术问题并一起学习。我在中国找不到这么棒的网站和像你这样的人。

c operator-precedence
2个回答
6
投票

如果你感到困惑,看看operator precedence chart

在你的情况下,

i *= j + 10;

和...一样

i *= (j + 10);

与...相同

i = i * (j + 10);

然而,

k = k * j + 10;

和...一样

k = (k * j) + 10;

根据输出:尝试不同的值。

例如,如果我选择ik作为2,输出将是

i = 24 k = 14


2
投票

简短回答:

很明显,它们引用了运算符优先级。那是:

  • 表达式i = i * j + k相当于i = (i * j) + k
  • i *= j + k相当于i = i * (j + k);

当然,如果你使用像i=1, j=1, k=1这样的错误输入,这两个表达式的结果将是相同的,运气不好。不是因为C语言而是因为小学数学。

(如果你是初学者,你可以在这里停止阅读)


有关赋值运算符等价性的高级答案:

复合赋值(*=)并不完全等同于简单赋值=。标准C17 6.5.16.2说:

形式E1 op = E2的复合赋值等效于简单赋值表达式E1 = E1 op(E2),除了左值E1仅被计算一次

这意味着如果读取操作数E1包含副作用,则复合赋值与简单赋值不同。考虑这个人为但有效的例子:

int foo (void)
{
  static int n=0;
  return ++n;
}

int array[3] = {1,2,3};
int* ptr = array;

#define FOO *(ptr + foo())

FOO += 1;给出了一个数组1 3 3FOO = FOO + 1;可以给出一个数组1 4 3 1)。这是因为在后一种情况下会产生额外的副作用。


1)左FOO和右FOO之间的评估顺序未指定,因此它可以给出不同的结果 - 它是未指定的行为。

© www.soinside.com 2019 - 2024. All rights reserved.