为什么++ * ++ ++可以在++ ++ ++中工作? [英] Why ++*p++ works while ++i++ does not?

查看:86
本文介绍了为什么++ * ++ ++可以在++ ++ ++中工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设 p 是一个整数指针, i 是一个整数:



* p ++ 给出一个整数值,对应于 p

i ++ 给出一个整数的值加1



由于通过行为,上述两者都产生整数, ++ * p ++ ++ i ++ 不应该有相同的错误报告?但为什么 ++ * p ++ 可以工作,而 ++ i ++ 会给编译器提供错误?

  int main()
{
int a [10] = {0};

int * p =(int *)& a;
int i = 0;

// printf(%d,++ i ++); - FAILS错误:所需的左值为增量操作数
printf(%d \ n,++ * p ++); //打印1
返回0;
}

编辑

++ i ++分解如下:

$ $ $ $ $ $ $ $ $
++ b $ b

这正是我困惑的地方:
以同样的方式我们可以分解++ * p ++ as

  * p ++ 
++(结果)。

* p ++返回一个值(rvalue),而不是指针。那么为什么差异呢?

解决方案

后增加的结果是一个右值。你不允许修改它。 ++ i ++ 会尝试修改该编译器拒绝的右值。



p ++产生一个右值,但它是指针类型。您不允许修改它,但您可以对其进行解除引用。 * p ++ 取消引用右值。这会为您提供它所指向的值,作为左值。前增量然后修改它指向的左值,而不是后增量产生的右值。



编辑:我也许应该再添加一点:即使编译器允许 ++ i ++ ,结果也是未定义的行为,因为它试图修改 i 两次,没有中间的顺序点。在 ++ * p ++ 的情况下,这也不会发生 - 后增量修改指针本身,而预增量修改指针指向的内容(在递增之前)。由于我们正在修改两个完全不同的位置,所以导致了不确定的行为。



如果您想足够糟糕,可以通过将指针初始化为指向自己,在这种情况下,两个增量都会尝试修改指针。委员会并没有很努力地预防这种情况,可能是因为只有真正的迂腐者才会甚至想到这样一种疯狂的事情。



底线:在这种情况下,编译器主要是为了保护你免受自己的伤害,尽管如果你足够努力的话,你仍然可以在脚下自己射击。


Assume p is a integer pointer and i is an integer:

*p++ gives an integer value corresponding to p.

i++ gives an integer value incremented by 1

Since by behavior, both the above yields integer, ++*p++ and ++i++ shouldn't have same error reported? But why ++*p++ works while ++i++ gives compiler error?

int main()
{
int a[10] = {0};

int *p = (int*)&a;
int i = 0;

// printf("%d", ++i++); -- FAILS error: lvalue required as increment operand   
printf("%d\n", ++*p++ ); // Prints 1
return 0;
}

EDIT

++i++ is decomposed as following:

i++
++(result)

This is exactly where I am confused : In the same way we can decompose ++*p++ as

*p++ 
++(result).

*p++ returns a value (rvalue) , not a pointer. So why the difference ?

解决方案

The result of post-increment is an rvalue. You're not allowed to modify it. ++i++ attempts to modify that rvalue, which the compiler rejects.

p++ produces an rvalue, but it's of pointer type. You're not allowed to modify it, but you are allowed to dereference it. *p++ dereferences that rvalue. This gives you the value it points at, as an lvalue. The pre-increment then modifies the lvalue it points at, not the rvalue that was produced by the post-increment.

Edit: I should probably also add one more point: even if ++i++ was allowed by the compiler, the result would be undefined behavior, because it attempts to modify i twice without an intervening sequence point. In the case of ++*p++, that doesn't happen either -- the post increment modifies the pointer itself, while the pre-increment modifies what the pointer pointed at (before it was incremented). Since we're modifying two entirely different locations, the result in not undefined behavior.

If you wanted to badly enough, you could still get undefined behavior by initializing the pointer to point at itself, in which case both increments would attempt to modify the pointer. The committee didn't work very hard at preventing this, probably because only the truly pedantic would be at all likely to even think of such an insane thing.

Bottom line: in this case, the compiler is mostly trying to protect you from yourself, though you can still shoot yourself in the foot if you try hard enough.

这篇关于为什么++ * ++ ++可以在++ ++ ++中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆