0
int i=5;
printf("%d",i+++++i);

这会产生错误,但是:

printf("%d",i+++i);

给出输出 11。在这种情况下,编译器将其读取为:

printf("%d",i+ ++i);

为什么在第一个表达式中没有这样做?IE :

printf("%d",i+++++i); 
4

4 回答 4

2

因为运算符优先级i++++++i被视为(i++)++ + i). 这会产生编译器错误,因为(i++)它不是左值。

于 2013-11-12T07:27:22.363 回答
1

i+++++i被解析为i ++ ++ + i。它包含无效的子表达式i ++ ++。正式地说,这个表达式包含一个约束违反,这就是它不能编译的原因。

同时i+++i被解析为i ++ + i(而不是i + ++ i您错误地认为的那样)。它不包含任何约束违规。它会产生未定义的行为,但格式正确。

此外,相信printf("%d",i+++i)会打印是相当幼稚的11。的行为i+++i是未定义的,这意味着尝试预测输出是没有意义的。

于 2013-11-12T08:03:32.983 回答
1

根据语言规范,在两个序列点之间多次修改同一个变量是未定义的行为§6.5

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,应仅读取先验值以确定要存储的值。 (71)


71) 本段呈现未定义的语句表达式,例如

i = ++i + 1;
a[i++] = i;

同时允许

i = i + 1;
a[i] = i;
于 2013-11-12T08:08:15.940 回答
0

In printf("%d",i+++++i);, the source text i+++++i is first processed according to this rule from C 2011 (N1570) 6.4 4:

If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token…</p>

This causes the lexical analysis to proceed in this way:

  • i can be a token, but i+ cannot, so i is the next token. This leaves +++++i.
  • + and ++ can each be a token, but +++ cannot. Since ++ is the longest sequence that could be a token, it is the next token. This leaves +++i.
  • For the same reason, ++ is the next token. This leaves +i.
  • + can be a token, but +i cannot, so + is the next token. This leaves i.
  • i can be a token, but i) cannot, so i is the next token.

Thus, the expression is i ++ ++ + i.

Then the grammar rules structure this expression as ((i ++) ++) + i.

When i++ is evaluated, the result is just a value, not an lvalue. Since ++ cannot be applied to a value that is not an lvalue, (i ++) ++ is not allowed.

After the compiler recognizes that the expression is semantically incorrect, it cannot go back and change the lexical analysis. Th C standard specifies that the rules must be followed as described above.

In i+++i, the code violates a separate rule. This is parsed as (i ++) + i. This expression both modifies i (in i ++) and separately accesses it (in the i of + i). This violates C 2011 (1570) 6.5 2:

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

This rule uses some technical terms: In i ++, the effect of changing i is a side effect of ++. (The main effect is to produce the value of i.) The use of i in + i is a value computation of the scalar object i. And these two things are unsequenced, because the C standard does not specify whether producing the value of i for + i comes before or after changing i in i ++.

于 2013-11-12T15:06:22.640 回答