【问题标题】:Counting number of ones and zeros inside char array计算 char 数组中 1 和 0 的数量
【发布时间】:2017-01-14 14:11:45
【问题描述】:

在将元素转换为二进制形式后,我正在尝试制作自定义代码来计算 char 类型数组的每个元素中的零和一的数量。这是我的代码。如果有更好的写法,请提出来。这项工作适用于嵌入式系统。提前致谢。

void counter(unsigned short bits_num, short sizeof_array, char array[]) {

    unsigned char zero = 0, one = 0;

    while (bits_num && sizeof_array) {
        if (array[sizeof_array - 1] & 1)
            one++;
        else
            zero++;
        array[sizeof_array - 1] = array[sizeof_array - 1] >> 1;
        bits_num--;

        if (!bits_num) {
            bits_num = 8;
            printf("zeros number is %i, ones number is %i in element: %x\n",
                   zero, one, sizeof_array - 1);
            sizeof_array--;
            zero = 0;
            one = 0;
        }
    }
}

【问题讨论】:

  • while (bits_num&&sizeof_array){ 是什么意思?还有这个参数bits_num是什么意思?
  • @YasserMohamed 它是已知的并且等于 CHAR_BIT 。此外,char 类型的表示不包含填充位。
  • @Olaf 你错了。来自 C 标准“...signed char 不应有任何填充位”
  • @VladfromMoscow 好的,找到了。谢谢。 (他们为什么不把它和 unsigned char 备注放在一起。
  • @YasserMohamed——你可能会觉得this selection of methods for counting set bits很有趣。

标签: c customization


【解决方案1】:

你的代码有问题:

  • bits_num 参数应该代表什么?它似乎是每个数组元素的位数,但您在第一个字节之后将其强制返回到 8
  • 为什么sizeof_arrayshort 类型?数组可能有更大的尺寸,尤其是在现代系统上。
  • 右移有符号类型会带来麻烦:您应该使用unsigned char,因为char 类型可能在某些架构上默认签名,并且负值右移是实现定义的。
  • 修改数组以计算位数是一个不好的副作用。

这是一个更简单的版本:

void counter(int bits_num, size_t array_size, const char *array) {

    for (size_t i = 0; i < array_size; i++) {
        unsigned char x = (unsigned char)array[i];
        int bits = 0;

        for (int j = 0; j < bits_num; j++) {
            bits += x & 1;
            x >>= 1;
        }    
        printf("zeros number is %d, ones number is %d in element %x\n",
               bits_num - bits, bits, i);
    }
}

【讨论】:

  • 左移负数未定义:右移负数是实现定义的。
  • 我会在您的答案中补充一点,您可以使用以下方法消除分支:“one += (x & 1);”然后将零计算为 "zero = bits_num - one;"
  • @Mehdi:我试图保留 OP 的逻辑,但确实只计算 ` 位要简单得多。
  • 我正在准备答案,然后我刷新并看到了你的答案,然后我想为它做出贡献,如果我冒犯了你,对不起。在更多的事情上,您必须将 x & 1 包裹在括号内,因为 + 在 & 之前执行
  • @EOF:确实如此,如果我们正在寻找原始性能,将会有更多的想法需要开发,但我试图保持上述代码的可移植性和简单性,以便新手学习来自。
猜你喜欢
  • 2015-04-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
相关资源
最近更新 更多