c语言复合赋值,v+=e和v=v+e有何不同?

c语言复合赋值,v+=e和v=v+e有何不同?,c,operator-precedence,C,Operator Precedence,在《C编程:现代方法》第二版第4章复合赋值一节中说: 注意,我一直很小心,没有说v+=e与v=v+e“等价”。一个问题是运算符优先级:i*=j+k与i=i*j+k不同 我写了一个程序来比较I*=j+k和I=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(

在《C编程:现代方法》第二版第4章复合赋值一节中说:

注意,我一直很小心,没有说v+=e与v=v+e“等价”。一个问题是运算符优先级:i*=j+k与i=i*j+k不同

我写了一个程序来比较I*=j+k和I=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=12k=12

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

谢谢你的回复。我误解了复合赋值运算符。我写了一个误导性的测试。
我想说的是,你们很乐意讨论技术问题,一起学习。在中国,我找不到像你这样伟大的网站和人们。

如果你感到困惑,请看看

就你而言

i *= j + 10;

i *= (j + 10);
i = i * (j + 10);
k = (k * j) + 10;
这和

i *= (j + 10);
i = i * (j + 10);
k = (k * j) + 10;
但是,

k = k * j + 10;

i *= (j + 10);
i = i * (j + 10);
k = (k * j) + 10;
根据输出:尝试不同的值

例如,如果我选择I和k作为2,那么输出将是

i=24k=14


如果您感到困惑,请查看

就你而言

i *= j + 10;

i *= (j + 10);
i = i * (j + 10);
k = (k * j) + 10;
这和

i *= (j + 10);
i = i * (j + 10);
k = (k * j) + 10;
但是,

k = k * j + 10;

i *= (j + 10);
i = i * (j + 10);
k = (k * j) + 10;
根据输出:尝试不同的值

例如,如果我选择I和k作为2,那么输出将是

i=24k=14

简短答复:

很明显,它们指的是运算符优先级。即:

表达式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;给出一个数组13,但FOO=FOO+1;可以给出一个数组1 4 3 1。这是因为在后一种情况下会产生额外的副作用

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

简短回答:

很明显,它们指的是运算符优先级。即:

表达式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;给出一个数组13,但FOO=FOO+1;可以给出一个数组1 4 3 1。这是因为在后一种情况下会产生额外的副作用


1左FOO和右FOO之间的求值顺序未指定,因此可能会给出不同的结果-这是未指定的行为。

操作顺序。陈丽:尝试不同的值!而且,j=2。你把你的i和j混淆了,i*=j+k;与i=i*j+k相同@讲故事者:这就是为什么我倾向于用质数来测试:I=7;j=13;k=11。。。无论如何,关闭投票撤回并评论删除操作。陈丽:尝试不同的价值观!而且,j=2。你把你的i和j混淆了,i*=j+k;与i=i*j+k相同@讲故事者:这就是为什么我倾向于用质数来测试:I=7;j=13;k=11。。。无论如何,close vote收回,comment deletedFOO=FOO+1有未指定的结果,否?@StoryTeller left FOO vs right FOO的评估没有排序,但在每个函数调用之前都有一个序列点。所以,是的,这是未指明的行为。我可能应该补充一点,谢谢。FOO=FOO+1有未指定的结果,没有?@StoryTeller左FOO和右FOO的评估没有排序,但在每个函数调用之前都有一个序列点。所以,是的,这是未指明的行为。我可能应该补充一点,谢谢 .