使用位操作来关闭"指针的二进制数字

时间:2014-07-23 14:36:24

标签: c bit-manipulation bit bitwise-operators

我能够使用位操作来关闭"数字的二进制数字。

例如:
x = x&amp; 〜(1 <<;&小于0)
x = x&amp; 〜(1 <<;&。1)
(并重复,直到从右边开始的所需位数变为0)

我想将此技术应用于指针的地址。

不幸的是,&amp;运算符不能与指针一起使用。使用与上面相同的代码行,其中x是指针,编译器将&#34;无效的操作数称为二进制和&amp; (有int和int)。&#34;

我试图将指针强制转换为整数,但这并不起作用,因为我认为整数太小(我只是意识到我不允许投射)。

(注意:虽然这是家庭作业问题的一部分,但我已经解释了为什么我需要在几个小时之后关闭一些数字,所以我在这方面很好。我&# 39;我只是试图看看我是否能得到一种聪明的技巧来做我想做的事情。)

限制:我不能使用循环,条件,任何特殊函数,大于255的常量,除法,mod。

(编辑:添加了对底部的限制)

3 个答案:

答案 0 :(得分:4)

使用<stdint.h>中的uintptr_t。你应该总是使用无符号类型来进行比特翻转,并且(u)intptr_t是专门选择的,以便能够保存指针的值。

但请注意,手动调整指针并取消引用它是未定义的行为,因此请注意您的步骤。在执行此操作之前,您应该能够恢复指针(或其他有效指针)的确切原始值​​。

您的评论中的

编辑我知道您根本不打算取消引用twiddled指针,因此您没有未定义的行为。以下是如何检查指针是否共享相同的64字节块:

uintptr_t p1 = (uintptr_t)yourPointer1;
uintptr_t p2 = (uintptr_t)yourPointer2;
uintptr_t mask = ~(uintptr_t)63u; // Shave off 5 low-order bits

return (p1 & mask) == (p2 & mask);

答案 1 :(得分:2)

C语言标准库包括(可选的)类型intptr_t,其中保证&#34;任何有效的指向void的指针都可以转换为此类型,然后转换回指向void的指针,并且结果将等于原始指针&#34;。

当然,如果对整数执行按位运算,则结果是未定义的行为。

答案 2 :(得分:2)

编辑:

  

多么不幸啊哈哈。我需要一个函数来显示两个指针   相同的64字节内存块。只要每一个都是如此   数字,但二进制的最低6位数   表示是平等的。通过确保最后6位数字全部   相同(例如:0),如果两个指针相等,我可以返回true。好,   至少我希望如此。

你应该能够通过以下方式检查它们是否在同一个64块内存中:

if ((char *)high_pointer - (char *)low_pointer < 64) {
    // do stuff
}

Edit2:这可能是克里斯指出的未定义行为。

原帖:

你可能正在寻找intptr_t or uintptr_t。标准表示您可以将这些类型转换为指针并使其值与原始值相等。

然而,尽管它是标准类型,但它是可选的,因此一些库实现可能选择不实现它。有些架构甚至可能不会将指针表示为整数,因此这种类型没有意义。

它仍然优于来自intlong的转换,因为它可以保证在提供它的实现上工作。否则,至少你会在编译时知道你的程序会破坏某个实现/架构。

(哦,正如其他答案所述,在转换为整数类型时手动更改指针并取消引用它是未定义的行为)