1

可能重复:
谁能解释这些未定义的行为(i = i++ + ++i,i = i++ 等……)

#include<stdio.h>

int main()
{
  char a[]="Hello";
  char *p=a;
  while(*p)
    ++*p++;     //Statement 2
    printf("%s",a);
    int x=10;
    ++x++; //Statement 1
   return 0;
}

当我编译这段代码时,我在语句 1 中得到一个 l-value Required 错误,我可以理解。即使我打算做同样的事情,语句 2 怎么不会产生错误?有人可以阐明吗?

4

3 回答 3

3

前增量和后增量都会产生右值,而右值不能被修改。

所以++x++(语句 1)显然违反了约束,编译器给出了错误。

但语句 2 并非如此。虽然p++产生了一个无法修改其值的右值,但它可以被取消引用。或者,如果你这样做++p++将等同于这种++x++情况并会给出错误。因为这里指针本身被修改了。

所以它相当于:++(*p++).

(请注意,括号仅用于理解,不是必需的。表达式++*p++是明确定义的。)

会发生什么:

  • 在本例中,后增量p++计算为 的旧值,并且 的存储值递增。p&a[0]p
  • *p++给出在p增量之前指向的值,在这个例子a[0]中。
  • 最终的预增量会增加该值,因此a[0]变为I(可能是 EBCDIC 机器上的其他内容)。

p当和的递增值a[0]被存储时未指定,但两者都必须存储在下一个序列点(终止;)。

于 2012-12-13T13:40:51.307 回答
0

引用 ISO C99 标准:

6.5.2.4 Postfix increment and decrement operators

Constraints
1
The operand of the postfix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue.

对于这种情况:

++*p++;     //Statement 2

后缀++具有更高的优先级和前缀++*具有相同的优先级和right to left关联性。这意味着在第一步它增加指针而不是它的值。所以它会给你那个的下一个地址type。然后value (which is actually *p)递增。所以,在这种情况下没有 constraint violation。它与 相同++(*(p++))

对于以下其他情况:

 int x=10;
 ++x++; //Statement 1

在上述变量(不是指针)的情况下++(后缀或前缀增量或减量)给你rvalue, 然后应用++--on rvalueis constraint violation++--操作数应该是一个lvalue. 请参阅上面写的标准报价。因此给出错误。

于 2012-12-13T13:14:38.723 回答
0
#include<stdio.h>

int main()
{
  char a[]="Hello";
  char *p=a;
  while(*p)
    ++*p++;     //Statement 2
    printf("%s",a);
    int x=10;
    ++x=x++; //Statement 1
   return 0;
}

//由于同时前后递增,此代码将获取相同的错误。因为它不能同时分配和递增,所以需要一个值来对其执行递增。

于 2012-12-13T15:33:33.897 回答