C 引用/取消引用标识

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 所以当两个恒等式都成立时,你可以说,从数学上来说,*和-,是彼此的反函数

当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编译时),我猜结果将是随机的,或者可能是堆栈地址。