C 引用/取消引用标识
当x是一个L值(比方说一个变量)时,则以下恒等式成立: x==*(&x) 这很容易解释,因为&x是指向x的指针,应用于&x的解引用运算符*当然会返回x 现在我想知道这个相反的说法是否有意义。确切地说,我想知道 p==&(*p) 当p是非悬挂指针时。 这似乎是有道理的,因为*p本身就是一个L值(一个有地址的值),因为我们已经有了指向它的指针(=地址)p。所以您只需要知道,这样的指针是唯一的,因为&(*p)没有其他机会成为p 所以当两个恒等式都成立时,你可以说,从数学上来说,*和-,是彼此的反函数C 引用/取消引用标识,c,pointers,reference,dereference,inverse,C,Pointers,Reference,Dereference,Inverse,当x是一个L值(比方说一个变量)时,则以下恒等式成立: x==*(&x) 这很容易解释,因为&x是指向x的指针,应用于&x的解引用运算符*当然会返回x 现在我想知道这个相反的说法是否有意义。确切地说,我想知道 p==&(*p) 当p是非悬挂指针时。 这似乎是有道理的,因为*p本身就是一个L值(一个有地址的值),因为我们已经有了指向它的指针(=地址)p。所以您只需要知道,这样的指针是唯一的,因为&(*p)没有其他机会成为p 所以当两个恒等式都成立时,你可以说,从数学上来说,*和-,是彼此的反函数
我说得对吗?此所谓规则是否有任何可能的例外情况?当
p
是对象指针时,&*p
相当于p
。不会对*p
进行评估,这由C标准保证
char *q, *p = NULL;
q = &*p; // equivalent to q = p;
以下是本标准的相关段落:
(C99,6.5.3.2p3)“如果操作数是一元*运算符的结果,则不会对该运算符和&运算符求值,并且结果就像两者都被省略一样,除非对运算符的约束仍然适用,并且结果不是左值。”
编辑:在@ldav1s注释之后,我将单词指针更改为对象指针。实际上,如果
p
属于void*
类型,则&*p
无效。作为参考,C委员会在缺陷报告#102中讨论了这一点:如果p
不是指针,你就不能做&(*p)
…但问题已经指出,“当p是非悬挂指针时。”也许“伴随函子”比“逆”更好,因为这两个词对不同的事物进行操作。+1。但是p
不能是void*
,因为它不允许取消引用void*
@ldav1s agree,p
不能是void*
我为对象指针而不是指针编辑了答案。答案很好。我发现有趣的是&*p本身不是一个L值,所以你不能做像q=&(&*p)这样的事情;但q=&p;没问题。这背后的原理可能是,至少在理论上*p可以是p后面的值的副本,所以这个副本的地址不同于p本身?还是我想得太多了,没有任何意义?@Anthales,&
运算符的结果实际上从来都不是左值,因此有意义的是,&*p
不是左值,即使p
是左值。@哎呀,你是对的,我的评论很混乱-我真的在想如果没有&*p到p的等价性会发生什么(例如,当使用不符合C99的MSVC编译时),我猜结果将是随机的,或者可能是堆栈地址。