我通过Kochan的C语言编程学习C.其中一个练习如下:
编写一个名为
bitpat_search()
的函数,用于查找unsigned int
内指定的位模式的出现。该函数应该有三个参数,应该这样调用:
bitpat_search (source, pattern, n)
该函数从最左边的位开始搜索整数
source
,以查看pattern
中最右边的n位是否出现在source
中。如果找到模式,则让函数返回模式开始的位数,其中最左边的位为数字0.如果找不到模式,则使函数返回-1。所以,例如,电话
index = bitpat_search (0xe1f4, 0x5, 3);
导致
bitpat_search()
函数搜索数字0xe1f4(= 1110 0001 1111 0100二进制)以查找三位模式0x5(= 101二进制)的出现。该函数返回11
以指示在source
中以位号11开头找到该模式。确保该函数不对
int
的大小做出假设。
这是我实现该功能的方式:
#include <stdio.h>
int bitpat_search(unsigned int source, unsigned int pattern, int n);
int int_size(void);
int main(void)
{
printf("%i\n", bitpat_search(0xe1f4, 0x5, 3));
return 0;
}
int bitpat_search(unsigned int source, unsigned int pattern, int n)
{
int size = int_size();
pattern <<= (size - n);
unsigned int compare = source;
int bitnum = 0;
while (compare)
{
compare >>= (size - n);
compare <<= (size - n);
if (compare & pattern)
{
return bitnum;
}
else
{
source <<= 1;
bitnum++;
compare = source;
}
}
return -1;
}
// Calculates the size of an integer for a particular computer
int int_size(void)
{
int count = 0;
unsigned int x = ~0;
while (x)
{
++count;
x >>= 1;
}
printf("%i\n", count);
return count;
}
首先,我计算一个整数的大小(不能使用sizeof()
)。然后,我调整我们正在寻找的模式,以便它从MSB开始。我创建了一个临时变量compare
并为其赋值source
,我还将变量bitnum
初始化为0;它将跟踪我们正在比较的位的位置。
在循环内,我将compare
向右和向左移动(在位与位模式比较的位的右侧和左侧添加0&#39;)然后我比较值:if是,返回位数,否则,源向左移动一次,然后分配给compare
(这实际上将我们在compare
中比较的位的位置向右移动) bitnum
递增。如果在pattern
中找不到source
并且根据说明返回-1
,则循环停止执行。
然而,我的节目输出结果是14,而不是11 ..我通过铅笔和纸张跟踪程序,并没有理解出了什么问题......帮助?
答案 0 :(得分:4)
您的测试不正确:(compare & pattern)
仅检查compare
和pattern
是否至少有一个共同位。您应该使用掩码并写下if ((compare & mask) == pattern)
。
以下是更正后的版本:
int bitpat_search(unsigned int source, unsigned int pattern, int n) {
int i, bitcount;
unsigned int mask = (1U << n) - 1;
pattern &= mask; /* mask off the n rightmost bits */
for (bitcount = 0; (source >> bitcount) != 0; bitcount++)
continue;
for (i = 0; i <= bitcount - n; i++) {
if (((source >> (bitcount - n - i)) & mask) == pattern)
return i;
}
return -1; /* not found */
}