我正在编写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中最小的类型。
有没有办法做得更好?
谢谢!
答案 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;
}
<强>参考强>
<http://www.rightcorner.com/code/CPP/Basic/union/sample.php>
<https://stackoverflow.com/questions/8584577/access-bits-in-a-char-in-c>
<http://cboard.cprogramming.com/c-programming/10029-struct-bit-fields.html>
答案 1 :(得分:1)
除非你在嵌入式平台上工作,否则我不会太担心你的网络占用的大小,只需使用unsigned char
来存储1或0。
要解决您的具体问题:char
是C data types中最小的一个。 char
,signed char
和unsigned char
每个只占用1个字节。
如果要使代码更小,可以使用位域来规定占用的空间量,但这会增加代码的复杂性。
对于像这样的简单练习,我更关心可读性而不是大小。一种方法是,您可以更明显地切换到bool
而不是char
。
#include <stdbool.h>
typedef struct {
int rows;
int cols;
bool *vec;
} net_t;
然后,您可以使用true
和false
,IMO会让您的代码更容易阅读和理解,只需1
和0
。
至少占用的空间与你现在的方式一样多,但就像我说的那样,考虑你为平台编写的程序中真正重要的是什么?重新写它...它可能不是那么大。
答案 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次操作。了解其工作原理(及其原因)至关重要。谷歌这个词用于获取更多资源。这使用每个单元格的八分之一内存,所以我当然不会认为它过早优化。