对象在按位操作上进行int转换 嗨,各位,这是我第二次尝试解释C++代码(我是新手),我只想确认下面的C++代码的含义: //| Get other endpoint of an edge | //+--------------------------------+ inline Node *Node::NextNode( Edge *next) { return (Node *) ((!next) ? NULL : ( (int)next->node[0] ^ (int)next->node[1] ^ (int)this ) ); }

对象在按位操作上进行int转换 嗨,各位,这是我第二次尝试解释C++代码(我是新手),我只想确认下面的C++代码的含义: //| Get other endpoint of an edge | //+--------------------------------+ inline Node *Node::NextNode( Edge *next) { return (Node *) ((!next) ? NULL : ( (int)next->node[0] ^ (int)next->node[1] ^ (int)this ) ); },c++,casting,bit-manipulation,xor,C++,Casting,Bit Manipulation,Xor,代码是否意味着将next->node[0]和next->node[1]中保留的对象转换/强制转换为int,并对其位值应用异或运算符?并使用结果作为对节点*的引用作为回报? 提前感谢您的帮助:)是的。(尽管你忽略了三元结构和演员阵容) 请记住,除非您非常小心,否则此类代码可能具有未定义的行为且不可移植(例如,在x86-64上,指针大于int)。您的解释是正确的。这是非常奇怪的代码。人们通常不会将一些整数进行异或运算,并将结果视为指针 查看节点声明附近的头文件,查看该字段的编码说明。如果没有这样的注

代码是否意味着将
next->node[0]
next->node[1]
中保留的对象转换/强制转换为int,并对其位值应用异或运算符?并使用结果作为对
节点*
的引用作为回报? 提前感谢您的帮助:)

是的。(尽管你忽略了三元结构和演员阵容)


请记住,除非您非常小心,否则此类代码可能具有未定义的行为且不可移植(例如,在x86-64上,指针大于int)。

您的解释是正确的。这是非常奇怪的代码。人们通常不会将一些整数进行异或运算,并将结果视为指针


查看
节点
声明附近的头文件,查看该字段的编码说明。如果没有这样的注释,请尽快逃离此代码

我最好的猜测是,
Edge
表示两个
节点之间的边,定义如下

struct Edge {
    Node *node[2];
    // perhaps other fields
}
必须填写节点
中的两个元素。它们可能指向不同的节点,或者,至关重要的是,可能指向同一节点

此外,
Node::NextNode()
只能传递一个
Edge
对象,该对象将节点本身作为Edge上的两个
Node
元素之一(或者可以传递为NULL)

鉴于此,该函数基本上等价于

if (next) {
    if (next->node[0] == next->node[1]) return this;
    if (next->node[0] == this) return next->node[1];
    return next->node[0];
}
return NULL;
尽管正如锑所指出的,它实际上是有缺陷的,因为它正在转换到
int
,这将在指针大于int的任何体系结构上表现不正确。当然,如果不满足不变量,函数将表现不正确(例如,传入一个
,该边不包含作为其两个
节点之一的节点)

假设next->node[0]和[1]都是明确的指针,从中可以看出,它们的异或提供了一个无意义的值(除了它们相等的小情况),但是假设使用
this
进行异或产生了一些有意义的结果,我假设其中一个node[]值已知为
this
,这样我们就剩下了不是这个的。换句话说,对于这种情况,代码可能相当于:

next->node[next->node[0] == this]

(或者如果有一点含糊,您可能更喜欢<代码> NeX-NOTEN[NET->NoD[1]=这个(1:0)< /代码>;在C++ <代码>真< /代码>转换为1,并且<代码> false < /代码>当数字为0时,

源代码“Get other endpoint of a edge”中的注释似乎支持这一点:
this
显然是一个端点,代码找到了“other”端点

另一种生成有效指针的场景是当
节点[0]
节点[1]
都相同时,在这种情况下会返回
。如果打算支持此场景(而不仅仅是实现的巧合),那么上面建议的simplifaction将失败。你可以试试:

next->node[0] == next->node[1] ? this : next->node[next->node[0] == this]
如果对运行时数据是否可以包含两个相同的节点值有任何疑问,那么这种替换更安全


正如其他人所指出的,代码假设指针的大小与
int
相同,这是非常糟糕的!我不会讨论这一点,因为它在其他地方已经死了,但请记住。

您对这段代码有什么期望?在我看来,将3个节点指针转换为int、XOR并将它们转换回一个节点指针只会给你一个junkunless节点是以一种非常特殊的方式分配的。。如果你真的是一个初学者,你不应该消化这段代码。如果指针是数组的成员,这可能是有效的,而且这是一种计算偏移量的倾斜方式。如果是这样,有更好的方法来做,初学者可能应该避免这类代码!附加inf,Edge的构造函数是:
node[2]
->Edge端点处的节点,
Edge*pself[2]
->指向端点处节点的Edge[]条目,
Edge*next->接下来的两个字段用于包含在双链接列表中(移动[]、链[],等等)
Edge*prev
边缘*父级->指向父链边缘。同时节点类的构造为
Edge*Edge[4]->PTR到连接边缘,
节点*相邻[4]->PTR发送给邻居。主要代码是关于一个网格包含一个由4条边构成的框n的数组,我想知道哪个节点是一条边的下一个节点是节点[0]还是节点[1]?它看起来像一个XOR链表,问题是不能保证
int
足够大来存储指针。我同意。但是,我们没有看到这样的保证,比如在
节点
构造函数中断言
sizeof(int)==sizeof(intptr\t)
。是的,您的解释是正确的,边缘构造函数是
Node*Node[2]
->edge端点处的节点,
edge*pself[2]
->指向端点处节点的edge[]条目,
edge*next->接下来的两个字段用于包含在双链接列表中(移动[]、链[],等等)
Edge*prev
边缘*父级->指向父链边缘。同时类edge():
edge*edge[4]->PTR到连接边缘,'Node*neigh[4];'->向邻居发送PTR。代码主要是关于一个网格包含由4条边构成的框n的数组,我想知道哪个节点是一条边的
nextNode
,是节点[0]还是节点[1]?对不起,我对
这个
有点困惑,是
节点[0]
还是
节点[1]
?@ignisc3:任何一个。这就是它的美妙之处。如果
节点[0]
节点[1]
中的一个包含
,则
此^node[0]^node[1]
将生成非
此节点的值next->node[0] == next->node[1] ? this : next->node[next->node[0] == this]