1

大家好,这是我第二次尝试解释 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,next->node[0]并将next->node[1]XOR 运算符应用于它们的位值?并使用结果作为参考作为Node*回报?提前感谢您的帮助:)

4

4 回答 4

2

是的。(虽然你也忽略了三元和这个的演员表)

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

于 2012-08-21T23:00:20.397 回答
1

我最好的猜测是它Edge代表两个Nodes 之间的边缘,定义如下

struct Edge {
    Node *node[2];
    // perhaps other fields
}

node必须填写其中的两个元素。它们可能指向不同的节点,或者至关重要的是,可能指向同一个节点。

更重要的是,Node::NextNode()必须只传递一个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;

尽管正如 Antimony 所指出的那样,它实际上是有问题的,因为它int在指针大于 int 的任何架构上都将表现不正确。当然,如果您不满足不变量(例如,您传入一个Edge不包含节点作为其两个nodes 中的任何一个的节点),该函数的行为当然会不正确。

于 2012-08-21T23:08:08.070 回答
0

你的解释是正确的。这是非常奇怪的代码。通常不会将某些整数异或在一起并将结果视为指针。

查看声明附近的头文件node,看看该字段编码的内容。如果没有这样的注释,请尽快远离此代码!

于 2012-08-21T23:01:24.047 回答
0
(int)next->node[0] ^ (int)next->node[1] ^ (int)this

鉴于 next->node[0] 和 [1] 显然是指针,在隔离中看到它们的 XOR 提供了一个无意义的值(除了在它们相等的平凡情况下),但是考虑到 XORingthis产生有意义的东西的期望,我假设已知 node[] 值之一是this,这样我们就剩下不是 的this。换句话说,对于这种情况,代码可能等同于:

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

(或者如果这有点神秘,您可能更喜欢next->node[next->node[0] == this ? 1 : 0]; 在 C++中,当需要一个数字时true转换为 1 和false0)

源代码“获取边缘的其他端点”中的注释似乎支持这一点:显然知道这this是一个端点,并且代码找到了“其他”端点......

另一种会产生有效指针的情况是当两者node[0]node[1]相同时,在这种情况下this返回。如果打算支持这种情况(而不仅仅是实现的巧合),那么上面建议的简化将失败。你可以试试:

next->node[0] == next->node[1] ? this : next->node[next->node[0] == this]

如果对运行时数据是否可以包含两个相同的节点值有任何疑问,那么这种替换会更安全。

正如其他人指出的那样,代码假定指针的大小与 相同int,这非常讨厌!我不会讨论它,因为它在其他地方已经死了,但请记住它。

于 2012-08-22T00:14:50.970 回答