c语言复合赋值,v+=e和v=v+e有何不同?
在《C编程:现代方法》第二版第4章复合赋值一节中说: 注意,我一直很小心,没有说v+=e与v=v+e“等价”。一个问题是运算符优先级:i*=j+k与i=i*j+k不同 我写了一个程序来比较I*=j+k和I=I*j+k。 但结果是一样的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(
#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的评估没有排序,但在每个函数调用之前都有一个序列点。所以,是的,这是未指明的行为。我可能应该补充一点,谢谢 .