【问题标题】:Reference/Dereference Identities引用/取消引用身份
【发布时间】:2012-03-23 07:37:43
【问题描述】:

当 x 是 L 值(假设是变量)时,以下恒等式成立:

x == *(&x)

这很容易解释,因为 &x 是一个指向 x 的指针,应用于 &x 的解引用运算符 * 当然会返回 x。

现在我想知道反过来是否有意义。确切地说,我想知道是否

p == &(*p)

当 p 是非悬空指针时。 这似乎是有道理的,因为 *p 本身就是一个 L 值(一个具有地址的值),因为我们已经有了指向它的指针 (=adress) p。所以你只需要知道,这样的指针是唯一的,因为 &(*p) 没有其他机会成为 p。

因此,当两个恒等式都为真时,您可以说,在数学上,* 和 & 是彼此的反函数。

我说的对吗?此所谓的规则是否有任何可能的例外情况?

【问题讨论】:

  • 如果p不是指针,你不能做&(*p)
  • ...但问题已经说明,“当 p 是非悬空指针时。”
  • 也许“伴随函子”比“逆”更合适,因为这两者在不同种类的事物上运行。

标签: c pointers reference dereference inverse


【解决方案1】:

p 是对象指针时,&*p 等价于p*p 的评估不会发生,这是由 C 标准保证的。

char *q, *p = NULL;
q = &*p;  // equivalent to q = p;

这是标准的相关段落:

(C99, 6.5.3.2p3) "如果操作数是一元 * 运算符的结果,则该运算符和 & 运算符都不会被计算,结果就好像两者都被省略了,除了对运算符的约束仍然适用,结果不是左值。”

EDIT:在@ldav1s 评论之后,我把pointer这个词改成了object pointer。事实上,如果pvoid * 类型,那么&*p 是无效的。有关信息,C 委员会已在缺陷报告 #102 中对此进行了讨论:http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_012.html

【讨论】:

  • +1。但是p 不能是void *,因为它不允许取消引用void *
  • @ldav1s 同意,p 不能是 void * 我编辑了 object pointer 而不是 pointer 的答案。
  • 非常好的答案。我觉得有趣的是 &*p 本身不是 L 值,所以你不能做像 q = &(&*p); 这样的事情。但是 q = &p;没问题。这背后的基本原理可能是,至少在理论上 *p 可能是 p 背后的值的副本,因此该副本的地址与 p 本身不同?还是我想多了,没有任何意义?
  • @ouah 是的,你是对的,我的评论很困惑 - 我真的在想如果没有 &*p 与 p 的等价性会发生什么(例如在使用不符合 C99 的 MSVC 进行编译时)我猜结果是随机的,或者可能是一个堆栈地址。
猜你喜欢
  • 2016-11-18
  • 2014-10-12
  • 2019-10-29
  • 2017-05-13
  • 2011-01-13
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多