在 Bitset 中设置单个位会导致设置多个位
Setting a single bit in a Bitset causes several bits being set
我是 C 语言和 Whosebug 的新手。我在向表示 ASCII table 的位集添加元素时遇到问题。我传递的字符应该将位集的位设置为对应于它们的十进制值 (a=97)。
但他们还设置了其他位,即 char +/- 32*a。我的意思是 "a" 会设置 97,但也会设置 225、193、161、129、97、65、33、1。
为什么代码会这样?有人能指出我正确的方向吗?
这是我的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct bitset {
unsigned *data;
int size_in_bits;
int size_in_words;
} bitset;
// create a new, empty bit vector set of 'size' items
struct bitset *new_bitset(int size) {
int word_bits = sizeof(unsigned) * 8;
struct bitset *result;
result = malloc(sizeof(struct bitset));
result->size_in_bits = size;
result->size_in_words = size / word_bits;
if (size % word_bits != 0) {
result->size_in_words++;
}
result->data = malloc(sizeof(unsigned) * result->size_in_words);
for (int i = 0; i < result->size_in_words; i++) {
result->data[i] = 0;
}
return result;
}
// check to see if an item is in the set
// returns 1 if in the set, 0 if not, and -1 if 'item' is out of bounds
int bitset_lookup(struct bitset *this, int item) {
if (item < 0 || item > this->size_in_bits) {
return -1;
}
if (*this->data & (1 << item)) {
return 1;
}
return 0;
}
// add an item, with number 'item' to the set
// (returns 0 if item is out of bounds, 1 otherwise)
// has no effect if the item is already in the set
int bitset_add(struct bitset *this, int item) {
if (item < this->size_in_bits) {
*this->data |= 1 << item;
return 1;
}
return 0;
}
int main() {
char str1 = "a";
struct bitset *src1;
src1 = new_bitset(256);
bitset_add(src1, str1);
for (int j = 0; j < src1->size_in_bits; j++) {
if (bitset_lookup(src1, j) == 1) {
int myChar = j;
printf("%d ", myChar);
} else
printf("0 ");
}
return 0;
}
您的代码中存在一些问题:
您不能一步设置unsigned
数组中的位,您必须确定要修改数组的哪个元素以及该元素的哪个位。
你不应该硬编码 8 位字符,使用 <limits.h>
中的 CHAR_BIT
使用calloc()
分配一块初始化为全零的内存块,它简化了代码。
您定义了一个全局变量bitset
。没有使用这个变量,也许你的意思是定义一个类型?
这是一个更正和简化的版本:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
struct bitset {
unsigned *data;
int size_in_bits;
int size_in_words;
};
// create a new, empty bit vector set of 'size' items
struct bitset *new_bitset(int size) {
int word_bits = sizeof(unsigned) * CHAR_BIT;
struct bitset *result = malloc(sizeof(struct bitset));
result->size_in_bits = size;
result->size_in_words = (size + word_bits - 1) / word_bits;
result->data = calloc(result->size_in_words, sizeof(unsigned));
return result;
}
// check to see if an item is in the set
// returns 1 if in the set, 0 if not, and -1 if 'item' is out of bounds
int bitset_lookup(struct bitset *this, int item) {
int word_bits = sizeof(unsigned) * CHAR_BIT;
if (item < 0 || item >= this->size_in_bits) {
return -1;
}
return (this->data[item / word_bits] >> (item % word_bits)) & 1;
}
// add an item, with number 'item' to the set
// (returns 0 if item is out of bounds, 1 otherwise)
// has no effect if the item is already in the set
int bitset_add(struct bitset *this, int item) {
int word_bits = sizeof(unsigned) * CHAR_BIT;
if (item >= 0 && item < this->size_in_bits) {
this->data[item / word_bits] |= 1U << (item % word_bits);
return 1;
}
return 0;
}
int main(void) {
char str[] = "Hello world";
struct bitset *set = new_bitset(256);
for (int i = 0; str[i] != '[=10=]'; i++) {
bitset_add(set, (unsigned char)str[i]);
}
for (int j = 0; j < set->size_in_bits; j++) {
if (bitset_lookup(set, j) == 1) {
printf("%c ", j);
}
}
printf("\n");
return 0;
}
我是 C 语言和 Whosebug 的新手。我在向表示 ASCII table 的位集添加元素时遇到问题。我传递的字符应该将位集的位设置为对应于它们的十进制值 (a=97)。
但他们还设置了其他位,即 char +/- 32*a。我的意思是 "a" 会设置 97,但也会设置 225、193、161、129、97、65、33、1。
为什么代码会这样?有人能指出我正确的方向吗? 这是我的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct bitset {
unsigned *data;
int size_in_bits;
int size_in_words;
} bitset;
// create a new, empty bit vector set of 'size' items
struct bitset *new_bitset(int size) {
int word_bits = sizeof(unsigned) * 8;
struct bitset *result;
result = malloc(sizeof(struct bitset));
result->size_in_bits = size;
result->size_in_words = size / word_bits;
if (size % word_bits != 0) {
result->size_in_words++;
}
result->data = malloc(sizeof(unsigned) * result->size_in_words);
for (int i = 0; i < result->size_in_words; i++) {
result->data[i] = 0;
}
return result;
}
// check to see if an item is in the set
// returns 1 if in the set, 0 if not, and -1 if 'item' is out of bounds
int bitset_lookup(struct bitset *this, int item) {
if (item < 0 || item > this->size_in_bits) {
return -1;
}
if (*this->data & (1 << item)) {
return 1;
}
return 0;
}
// add an item, with number 'item' to the set
// (returns 0 if item is out of bounds, 1 otherwise)
// has no effect if the item is already in the set
int bitset_add(struct bitset *this, int item) {
if (item < this->size_in_bits) {
*this->data |= 1 << item;
return 1;
}
return 0;
}
int main() {
char str1 = "a";
struct bitset *src1;
src1 = new_bitset(256);
bitset_add(src1, str1);
for (int j = 0; j < src1->size_in_bits; j++) {
if (bitset_lookup(src1, j) == 1) {
int myChar = j;
printf("%d ", myChar);
} else
printf("0 ");
}
return 0;
}
您的代码中存在一些问题:
您不能一步设置
unsigned
数组中的位,您必须确定要修改数组的哪个元素以及该元素的哪个位。你不应该硬编码 8 位字符,使用
<limits.h>
中的 使用
calloc()
分配一块初始化为全零的内存块,它简化了代码。您定义了一个全局变量
bitset
。没有使用这个变量,也许你的意思是定义一个类型?
CHAR_BIT
这是一个更正和简化的版本:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
struct bitset {
unsigned *data;
int size_in_bits;
int size_in_words;
};
// create a new, empty bit vector set of 'size' items
struct bitset *new_bitset(int size) {
int word_bits = sizeof(unsigned) * CHAR_BIT;
struct bitset *result = malloc(sizeof(struct bitset));
result->size_in_bits = size;
result->size_in_words = (size + word_bits - 1) / word_bits;
result->data = calloc(result->size_in_words, sizeof(unsigned));
return result;
}
// check to see if an item is in the set
// returns 1 if in the set, 0 if not, and -1 if 'item' is out of bounds
int bitset_lookup(struct bitset *this, int item) {
int word_bits = sizeof(unsigned) * CHAR_BIT;
if (item < 0 || item >= this->size_in_bits) {
return -1;
}
return (this->data[item / word_bits] >> (item % word_bits)) & 1;
}
// add an item, with number 'item' to the set
// (returns 0 if item is out of bounds, 1 otherwise)
// has no effect if the item is already in the set
int bitset_add(struct bitset *this, int item) {
int word_bits = sizeof(unsigned) * CHAR_BIT;
if (item >= 0 && item < this->size_in_bits) {
this->data[item / word_bits] |= 1U << (item % word_bits);
return 1;
}
return 0;
}
int main(void) {
char str[] = "Hello world";
struct bitset *set = new_bitset(256);
for (int i = 0; str[i] != '[=10=]'; i++) {
bitset_add(set, (unsigned char)str[i]);
}
for (int j = 0; j < set->size_in_bits; j++) {
if (bitset_lookup(set, j) == 1) {
printf("%c ", j);
}
}
printf("\n");
return 0;
}