可能重复:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
#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值必需的错误,我可以理解。即使我打算做同样的事情,该语句2如何不产生错误?有人可以光明吗?
答案 0 :(得分:3)
预增量和后增量产生的rvalues和rvalues都无法修改。
所以++x++
(语句1)显然是违反约束而编译器会出错。
但是声明2的情况并非如此。虽然p++
产生的rvalue值无法修改,但可以取消引用。或者,如果您执行++p++
,这将等同于++x++
情况,并会出错。因为这里指针本身被修改了。
所以它相当于:++(*p++)
。
(请注意,括号仅供理解而且不是必需的。表达式++*p++
定义明确。)
会发生什么:
p++
评估为p
的旧值,在此示例中为&a[0]
,并且p
的存储值会增加。*p++
给出了在增量之前指向的值p
,在此示例中为a[0]
。a[0]
变为I
(可能是EBCDIC计算机上的其他内容)。如果未指定存储p
和a[0]
的递增值,则两者必须已存储在下一个序列点(终止;
)。
答案 1 :(得分: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
postfix ++
具有更高的优先级,前缀++
和*
具有相同的优先级和right to left
关联性。这意味着在第一步它增加指针而不是它的值。
因此它会为您提供type
的下一个地址。然后value (which is actually *p)
递增。所以,在这种情况下没有constraint violation
。
它与++(*(p++))
相同。
对于下面的其他情况:
int x=10;
++x++; //Statement 1
在上面的变量(非指针)++
(后缀或前缀增量或减量)的情况下,为您提供rvalue
,然后应用++
或--
rvalue
为constraint violation
。++
或--
操作数应为lvalue
。请参阅上面的标准报价。因此给出错误。
答案 2 :(得分: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;
}
//由于同时的前后增量,此代码将获取相同的错误。 因为它不能同时分配和增加它需要一个值来执行增量。