在Bitset中设置单个位会导致设置几个位

时间:2016-11-22 23:47:32

标签: c bitset

我是C和Stackoverflow的新手。在向表示ASCII表的位集添加元素时,我遇到了问题。我传递的字符应该设置bitset的位对应于它们的十进制值(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;
}

1 个答案:

答案 0 :(得分:1)

您的代码中存在一些问题:

  • 您无法在一个步骤中设置unsigned数组中的位,您必须确定要修改的数组元素以及该元素的哪个位。

  • 您不应硬编码8位字符,请使用CHAR_BIT

  • 中的<limits.h>
  • 使用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] != '\0'; 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;
}