将指针强制转换为左值

为什么(int*) p = &x;是无效的声明? 而*(int*) p = &x;是没有警告的有效语句吗? 我知道强制转换是 rvalue ,但是如何在没有警告的情况下编译第二条语句?

yanxianfeng_5188 回答:将指针强制转换为左值

(int*) p = &x;

这是无效的,因为强制转换的结果不是左值。它只是一个表达式,其类型是强制转换中指定的类型。

*(int*) p = &x;

这是有效的,因为取消引用运算符*的结果是一个左值。取消引用指针可以为您提供指针指向的对象。

,

从直觉上讲,左值是表示“这是诚实的对象”的表达式,而右值是表示“这不是对象的值”的表达式。 (区别稍微有些暗了,但是现在是一个合理的简化。)也就是说,一个左值是一个可以放入一些东西的盒子,而一个右值只是盒子中的值。

例如,表达式137是一个右值,因为它是一个纯数字,而不是包含数字的盒子。如果x是变量,则表达式x是左值,因为它既表示框又表示其中的数字,而表达式x + 137是右值,因为它仅表示数字,而不是装有数字的盒子。

如何将其转化为因素?假设xint。那么(float)x是一个右值,因为它纯粹表示一个值-具体来说,它是“如果您使用x并做了最糟糕的事情来将其表示为{{1} }。”这不是可以放东西的盒子。

这就是为什么

float

不起作用。 (int *)p = &x; 是一个右值-一个纯值,不是您可以分配给它的值-并且您试图将其视为可以放入某些东西的盒子。

另一方面,指针取消引用的结果是一个左值,因为它表示“在那儿看!这是可以在其中放入东西的盒子”。所以从这个意义上讲,您可以写

(int *)p

因为那意味着

  1. 计算表达式*(int *)p = x; 。好的,我们现在有了一个右值,它是指向内存中某个(int *)p的指针。
  2. 取消引用该指针以获取int。好的,我们现在有一个表示该整数的左值。
  3. *(int *)p塞入该位置。很好-x是一个盒子。

此代码可能还有其他问题:

*(int *)p

在此,此表达式的RHS具有类型*(int *)p = &x; ,它是一个指针。该表达式的LHS的类型为(int *)(您已将指针解引用为整数),因此要将指针转换为整数。因此,这意味着要么缺少演员表,要么您正在使用此代码执行错误的事情。

第二个问题是

int

表示“将*(int *)p 解释为好像告诉您可以在内存中找到p的地方,然后在其中写一些东西。”如果int不是指针,则几乎可以肯定会导致代码崩溃,因为您将在内存中随机写入某处。而且如果p是一个指针,那么最好是投射p,而不是&x

p

其中p = (T*) &x; T指向的事物的类型。

,

技术术语有时会令人困惑,尤其是当读者对事物的工作原理不太了解时。

什么是左值?有地址的东西。 在第一种情况下,您有一个指针。在第二种情况下,您将取消引用指针。

什么是指针?指针一个地址。地址本身没有地址(好吧,我们在这里不要太过专业)。在您的示例中,假设p是常数1235。它的地址是什么?没有,这只是一个常量,它可能不存在于内存中。也许在寄存器中。也许编译器完全优化了它。 而且,您的表达式是(int*)p = &x说:“获取地址1235并为其分配x的地址,可能类似于6789。”换句话说,“将地址1235更改为6789”。什么?!更改地址?!

什么是解引用指针?它是指针的内容,即指针指向的地址中的。现在,根据定义,有地址!这就是第二条语句中发生的事情。就是说“将内容设置在p指向&x的地址上”。因此,在我的示例中,它说“将内存地址1235的值设置为6789”。现在这很有意义!这就是为什么它是左值的原因。

我希望这是有道理的。

本文链接:https://www.f2er.com/2398202.html

大家都在问