我的任务是编写一个宏来检查INT数组中有多少元素已经激活了5位。
我知道宏是一种非常冒险的方式,但这是一些考试中出现的问题。
这是我的代码:
#include <stdio.h>
#define RESULT 5
#define SIZE 8
#define BITW(arr, length, counter)\
int mask=0b00000001, bits=0, i=0, j=0;\
for (i=0; i<length; i++){\
for (j=0; j<sizeof(arr[i])*SIZE; j++){\
if(mask&arr[i]>>j)\
bits++;\
}\
if (bits==RESULT)\
counter++;\
}
int main(void){
int arr[4]={0b11111000,0b11100011,0b11001100,0b11000000};
int res=0; int counter=0;
BITW(arr, 4, counter);
printf("%d",counter);
}
宏的问题是我无法调试我的代码。我去了几次没有成功,但我意识到我得到的结果是1而不是2。
计数器变量是计算有多少元素有5位的计数器变量。位变量在某个元素中计算有多少位。
感谢您的帮助。
答案 0 :(得分:7)
如果你真的想要一个宏,我可能会做这样的事情:
static const int bits_per_nibble[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
#define BITS_PER_U8(x) (bits_per_nibble[(x) & 0xf] + bits_per_nibble[((x) >> 4) & 0xf])
#define BITS_PER_U16(x) (BITS_PER_U8((x) & 0xff) + BITS_PER_U8(((x) >> 8) & 0xff))
#define BITS_PER_U32(x) (BITS_PER_U16((x) & 0xffff) + BITS_PER_U16(((x) >> 16) & 0xffff))
如果需要,定义BITS_PER_U64
应该是一个明显的扩展。
然而,将其作为一个小型内联函数来做会更安全,更好的解决方案......
还有this,其中有关于如何以各种方式获得“人口数量”的整个部分......
答案 1 :(得分:2)
在计算每个数组元素中的位之前,宏无法将bits
设置为零。它仅在整个数组上的循环之前将bits
设置为零。
答案 2 :(得分:1)
我说
if(mask&arr[i]>>j)\ bits++;\
是错误的,因为它测试结果中是否设置了任何位,而不是全部 他们是设定的。我重写代码来计算1中的位数 字节到
bits=0; for (mask=0b10000000; mask!=0; mask=mask>>1) if (arr[i]&mask) bits++; if (bits==5) ...
注意这仅适用于掩码是无符号或超过8位的情况,因此char不会>做(你的int是好的)。
但这是错误的。
然而,
#define BITW(arr, length, counter)\
int mask=0b00000001, bits=0, i=0, j=0;\
for (i=0; i<length; i++){\
bits=0; //<---- This line is missing from your code
for (j=0; j<sizeof(arr[i])*SIZE; j++){\
if(mask&arr[i]>>j)\
bits++;\
}\
if (bits==RESULT)\
counter++;\
}
不会为每个字节重置位计数器。
要调试宏,首先编写一个可以调试的函数;然后,当你确定它有效时,将函数转换为宏。
答案 3 :(得分:0)
Eric回答了主要问题。
宏的问题在于我无法调试我的代码。
您可以在宏中使用printf,或者您可以将宏调用替换为宏中的代码段。