C 中的运算符结合性特别是前缀和后缀递增和递减
-
25-09-2019 - |
题
在 C 运算中,结合性是指递增、递减和赋值。
2. postfix ++ and --
3. prefix ++ and --
16. Direct assignment =
完整列表可以在这里找到 C 中的维基百科运算符
我的问题是当我们有
int a, b;
b = 1;
a = b++;
printf("%d", a); // a is equal to 1
b = 1;
a = ++b;
printf("%d", a); //a is equal to 2
当后缀增量运算符应该发生在直接赋值之前时,为什么 b++ 中的 a 等于 1?
为什么前缀增量运算符与后缀都在赋值之前不同?
我很确定在操作关联性方面我不明白一些非常重要的事情。
解决方案
后缀运算符 a++
将增加 a
然后返回原始值,即与此类似:
{ temp=a; a=a+1; return temp; }
和前缀 ++a
将返回新值,即
{ a=a+1; return a; }
这与运营商无关 优先级.
(结合性决定是否 a-b-c
等于 (a-b)-c
或者 a-(b-c)
.)
其他提示
运算符优先级和结合不告诉你会发生什么的前的和会发生什么的之后的。运算符优先级/关联性无关,用它做。在像C语言的时间关系“前”或“后”是由所谓的定义序列点和仅由序列点(这是一个完全独立的故事)。
运算符优先级/结合性简单地告诉你哪些操作数属于哪个运营商。例如,所述表达a = b++
可以正式解释为(a = b)++
和a = (b++)
。运算符优先级/结合性是这种情况下,简单地告诉你,后者的解释是正确的,前者是不正确的(即++
适用于b
而不是a = b
的结果)。
也就是说,再次,并不意味着b
应首先递增。运算符优先级/关联性,再一次,已注意到有什么“第一”碰巧做,会发生什么“下一步”。它只是告诉你,b++
表达式的结果分配给a
。根据定义,b++
(后缀增量)的结果是原始 b
的值。这就是为什么a
将获得的原始的b
的价值,这是1.当变量b
将获得递增是完全不相干的,只要a
获得分配b
的的原始的值。编译器可在任何时间来评估以任何顺序和增量b
这个表达式:任何事情都会发生,只要a
莫名其妙地得到的原始的b
(没有人的价值真正关心怎么说“莫名其妙”的作品内部)。
例如,编译器可以评估a = b++
为初等运算的以下序列
(1) a := b
(2) b := b + 1
,或者它可以评估它如下
(1) b := b + 1
(2) a = b - 1
注意,在第一种情况下b
在端部实际递增,而在第二种情况下b
先增加。但是,在这两种情况下a
获取相同的正确值 - b
的原始值,这是它应该得到的。
但是,我要重申的是,以上的两个例子在这里只是为了说明的目的。在现实中,像a = ++b
和a = b++
表情都没有序列点内,这意味着,从您的视图这些表达式一切发生点的同时的。有没有“前”,“后”,“第一”,“下一步”或“最后一个”。这种表达在某种意义上它们不能有意义地分解为更小的步骤的序列“原子”。
由于AndreyT已经指出的,优先级和结合不告诉你关于评价的顺序。他们只告诉你关于分组。例如,优先级就是告诉使用该a*b+c
被归纳为(a*b)+c
而不是a*(b+c)
。编译器是免费的,以评估它认为合适的那些表情或者任何顺序a
,b
和c
。关联告诉你,当你有相同的优先级的运营商分组,通常,同一运营商。例如,它就是告诉你,a-b-c
相当于(a-b)-c
,不a-(b-c)
(另有说明,减法是左结合)。
评价的顺序由顺序点来定义。有在充分表达结束序列点(除其他事项外)。在序列点,所有的先前评价必须有发生,并且没有后续评估的可以都发生爱好。
看你的具体的例子,在a=b++;
,结果是大多来自后增量本身的定义。一个后增量产生变量的前值,而下一个序列点之前的某个时候,该变量的值会增加。预增量产生施加有增量的变量的值。在两种情况下,然而,这是否意味着该变量在任何特定的相对于所述分配顺序来递增。例如,在您的预增量例如,编译器是完全免费的做等价的东西:
temp = b+1;
a = temp;
b = b + 1;
同样地,在后增量的版本,变量可以被前或递增赋值后:
a = b;
b = b + 1;
或:
temp = b;
b = b + 1;
a = temp;
无论哪种方式,但是,分配给a
值必须它的递增之前是b
的值。