C变量小于8位

时间:2014-04-07 16:48:11

标签: c memory-management types

我正在编写Conway's Game of Life的C实现并且几乎完成了代码,但我想知道在程序中存储网络的最有效方法是什么。 网是二维的并且存储单元(x,y)是活的(1)还是死的(0)。目前我正在使用unsigned char这样做:

结构:

typedef struct {
    int rows;
    int cols;
    unsigned char *vec;
} net_t;

分配:

n->vec = calloc( n->rows * n->cols, sizeof(unsigned char) );

填充:

i = ( n->cols * (x - 1) ) + (y - 1);
n->vec[i] = 1;

搜索:

if( n->vec[i] == 1 )

但我真的不需要0-255个值 - 我只需要0-1,所以我觉得这样做是浪费空间,但据我所知8- bit char是C中最小的类型。

有没有办法做得更好?

谢谢!

4 个答案:

答案 0 :(得分:3)

您可以寻址/使用的最小可声明的 / 可寻址内存单位是一个字节,在您的情况下实现为unsigned char

如果你想真正节省空间,可以使用屏蔽字符中的各个位,或通过联合使用位字段。权衡的是你的代码执行速度会慢一点,而且肯定会更复杂。

#include <stdio.h>
union both {
   struct { 
      unsigned char b0: 1;
      unsigned char b1: 1;
      unsigned char b2: 1;
      unsigned char b3: 1;
      unsigned char b4: 1;
      unsigned char b5: 1;
      unsigned char b6: 1;
      unsigned char b7: 1;
   } bits; 
   unsigned char byte;
};

int main ( ) {
   union both var;
   var.byte = 0xAA;
   if ( var.bits.b0 ) {
      printf("Yes\n");
   } else {
      printf("No\n");
   }
   return 0;
}

<强>参考


  1. 联盟和位字段,已访问2014-04-07,<http://www.rightcorner.com/code/CPP/Basic/union/sample.php>
  2. 访问C中的字符位,访问次数2014-04-07,<https://stackoverflow.com/questions/8584577/access-bits-in-a-char-in-c>
  3. 结构 - 位字段,已访问2014-04-07,<http://cboard.cprogramming.com/c-programming/10029-struct-bit-fields.html>

答案 1 :(得分:1)

除非你在嵌入式平台上工作,否则我不会太担心你的网络占用的大小,只需使用unsigned char来存储1或0。

要解决您的具体问题:charC data types中最小的一个。 charsigned charunsigned char每个只占用1个字节。

如果要使代码更小,可以使用位域来规定占用的空间量,但这会增加代码的复杂性。

对于像这样的简单练习,我更关心可读性而不是大小。一种方法是,您可以更明显地切换到bool而不是char

#include <stdbool.h>

typedef struct {
    int rows;
    int cols;
    bool *vec;
} net_t;

然后,您可以使用truefalse,IMO会让您的代码更容易阅读和理解,只需10

至少占用的空间与你现在的方式一样多,但就像我说的那样,考虑你为平台编写的程序中真正重要的是什么?重新写它...它可能不是那么大。

答案 2 :(得分:0)

我知道C上的最小类型是char(-128,127),signed char(-128,127),unsigned char(0,255)类型,所有这些类型占用整个字节,所以如果你在不同的变量上存储多个位值,您可以使用unsigned char作为一组位。

unsigned char lives = 128;

此时,生命有一个128十进制值,它是二进制的10000000,所以现在你可以使用一个按位运算符从这个变量中获取一个值(就像一个位数组)

if((lives >> 7) == 1) {

    //This code will run if the 8 bit from right to left (decimal 128) it's true
}

这有点复杂,但最后你会得到一个位数组,所以你可以使用一个unsigned char变量来存储8个TRUE / FALSE值,而不是使用多个变量来存储单个TRUE / FALSE值。

注意:由于我有一些时间不在C / C ++世界,我不是100%确定它是“生命&gt;&gt; 7”,但是它与'&gt;'有关符号,对它的一点研究,你就准备好了。

答案 3 :(得分:0)

你是正确的char是最小的类型 - 它通常是(8)位,尽管这是最低要求。 sizeof(char)(unsigned char)(1)(unsigned) char(8)char's。因此,请考虑使用(cols / 8)来表示int byte_cols = (cols + 7) / 8;列。

每行需要多少int byte_cols = (cols + 7) >> 3; ?它是net_t,但我们必须将向上舍入为整数值:

calloc(n->rows * n->byte_cols, 1)

或:

(x, y)

您可能希望将其存储在n->vec[y * byte_cols + (x >> 3)] |= (1 << (x & 0x7)); 数据结构中。然后:

n->vec[y * byte_cols + (x >> 3)] &= ~(1 << (x & 0x7)); 足以连续位向量


分别按x和y对列和行进行地址处理。设置if (n->vec[y * byte_cols + (x >> 3)] & (1 << (x & 0x7))) /* ... (x, y) is set... */ else /* ... (x, y) is clear... */ (相对于0):

{{1}}

清算:

{{1}}

搜索:

{{1}}

这些是bit manipulation次操作。了解其工作原理(及其原因)至关重要。谷歌这个词用于获取更多资源。这使用每个单元格的八分之一内存,所以我当然不会认为它过早优化。