C 增量算子中的左值问题
可能重复:C 增量算子中的左值问题,c,post-increment,pre-increment,C,Post Increment,Pre Increment,可能重复: #包括 int main() { 字符a[]=“你好”; char*p=a; 而(*p) ++*p++;//语句2 printf(“%s”,a); int x=10; ++x++;//语句1 返回0; } 当我编译这段代码时,我在语句1中得到一个l值必需的错误,我可以理解。为什么即使我打算做同样的事情,语句2也不会产生错误?有人能发光吗?引用ISO C99标准: 6.5.2.4 Postfix increment and decrement operators 约束条件 1 后
#包括
int main()
{
字符a[]=“你好”;
char*p=a;
而(*p)
++*p++;//语句2
printf(“%s”,a);
int x=10;
++x++;//语句1
返回0;
}
当我编译这段代码时,我在语句1中得到一个l值必需的错误,我可以理解。为什么即使我打算做同样的事情,语句2也不会产生错误?有人能发光吗?引用ISO C99标准:
6.5.2.4 Postfix increment and decrement operators
约束条件
1
后缀递增或递减运算符的操作数应具有限定或
非限定实数或指针类型,应为可修改的左值。
在这种情况下:
++*p++; //Statement 2
后缀++
具有较高的优先级,前缀++
和*
具有相同的优先级和从右到左的关联性。这意味着在第一步,它增加的是指针,而不是它的值。
因此,它将为您提供该类型的下一个地址。然后增加值(实际上是*p)
。因此,在这种情况下,没有约束冲突。
它与++(*(p++)
相同
对于以下其他情况:
int x=10;
++x++; //Statement 1
在上述变量(非指针)的情况下,++
(后缀或前缀递增或递减)为您提供rvalue
,然后在rvalue
上应用++
或--
是约束冲突++
或--
操作数应该是lvalue
。请参阅上面的标准引用。因此给出了错误 增量前和增量后都会生成右值,右值不能修改
所以++x++
(语句1)显然是违反了约束,编译器给出了错误
但声明2并非如此。虽然p++
生成了一个不能修改其值的右值,但它可以被取消引用。或者,如果执行++p++
操作,这将等同于++x++
案例,并将给出一个错误。因为这里指针本身被修改了
所以它相当于:++(*p++)
(请注意,括号仅用于理解,不是必需的。表达式++*p++
定义良好。)
发生的情况是:
- 后增量
p++
计算为p
的旧值,在本例中&a[0]
,并且p
的存储值递增
*p++
给出增量前指向的值p
,在本例中为a[0]
- 最后的预增量增加该值,因此
a[0]
变为I
(可能是EBCDIC机器上的其他内容)
存储p
和a[0]
的增量值时未指定,但这两个值必须都存储在下一个序列点(终止的;
)。包括
int main()
{
字符a[]=“你好”;
char*p=a;
而(*p)
++*p++;//语句2
printf(“%s”,a);
int x=10;
++x=x++;//语句1
返回0;
}
//由于同时进行前增量和后增量,此代码将获取相同的错误。
因为它不能同时赋值和递增,所以需要一个值来对其执行递增 p在序列点之间被修改两次,所以这是未定义的行为。@Lundin不,不是++*p++
是++(*(p++)
,p
只修改一次,没有UB。好的,一个问题:为什么要编写这样一个没有括号的代码?使用合适的括号&行为将是可预测且可读的。@DanielFischer Oops我是说x++x++是未定义的行为。@Lundin如果它编译的话,确实是这样。后缀++的优先级高于一元*和前缀+。你似乎把这个弄糊涂了。不管怎样,代码是未定义的行为,因此,试图弄清楚它将做什么并没有任何意义。@Lundin:不太确定未定义的行为,但++
和*
具有相同的优先级…@Lundin:C编程由K&R
在第2章2.12优先级和求值顺序中给出的运算符表。以及++(*(p++)
表达式有问题,请解释一下好吗?有3种不同的运算符,后缀++、前缀++和一元数*。它们的优先级在C11 6.5/3中指定:运算符和操作数的分组由语法
指示。这意味着,C标准第6.5章中的操作员出现顺序说明了操作员的优先级。后缀++出现在6.5.2中,因此它的优先级高于前缀++和一元数*,后两者出现在6.5.3中,具有相同的优先级,但彼此之间是从右向左计算的。++(*(p++)
:p++是下一个地址,然后*(p++)
将是该地址的值,然后++(*(p++)
将为您提供递增的值。我是这样分析的,我错了吗?你有一个很糟糕的公式,“它被后增量解引用了”。我知道你的意思是正确的,我也不知道该怎么说,但那是错的。(我投了赞成票,期待一个更好的公式。)@DanielFischer当我写这篇文章时,我有一种感觉。我真的不知道该怎么说。它看起来更好吗?我已经试着解释得更好了,如果你一点都不喜欢,滚回去。@DanielFischer谢谢。看起来比我拥有的要清楚得多。没想到用通俗易懂的英语写表达式++*p++
会这么难:)
int x=10;
++x++; //Statement 1
#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;
}