zook0k 发表于 2008-8-7 11:42:43

21*21二维数组如何定义比较好(都是bit型,定义成char型太浪费空间了)

21*21二维数组如何定义比较好(都是bit型,定义成char型太浪费空间了)
感觉这样太浪费空间了unsigned char a,毕竟取值都是0或者1,定义成什么样的结构体比较好呢?

mingyuexin1981 发表于 2008-8-7 12:54:34

typedef struct
        {
                unsigned long int a:1;
                unsigned long int b:1;
                        .
                        .
                      依次类推       
                        .
                unsigned long int u:1;
                unsigned long int :11;
        }A;
       
        A data;
         引用时data.e就是你所说的a

xielihong 发表于 2008-8-7 13:00:41

1 楼的方法不错
不过把abcd...改为 L0 L1 L2 L3 ...可能会更直观

不过如果是我的话,我可能定义一个一维数组,然后通过宏,或者函数来读写

mingyuexin1981 发表于 2008-8-7 13:35:24

实际上如果我做

也会用2楼的方法

xielihong 发表于 2008-8-7 15:17:53

贴上代码,如果_id值是常数的话,由于编译器的优化,一般可以产生比较好的代码,当然如果是变量的话,也是支持的
#define BIT_SET(_buf,_id) \
{ ((char *)(buf))[(_id)/(sizeof(char)<<3)] |= 1<<(_id)%(sizeof(char)<<3); }

#define BIT_CLR(_buf,_id) \
{ ((char *)(buf))[(_id)/(sizeof(char)<<3)] &= ~(1<<(_id)%(sizeof(char)<<3)); }

#define BIT_GET(_buf,_id) \
(((char *)(buf))[(_id)/(sizeof(char)<<3)] >> ((_id)%(sizeof(char)<<3))        & 0x01)

#define BIT_ROW_MAX   21
#define BIT_SET2(_buf,_max,_x,_y) BIT_SET((_buf),((_x)*(_max)+(_y)))
#define BIT_CLR2(_buf,_max,_x,_y) BIT_CLR((_buf),((_x)*(_max)+(_y)))
#define BIT_GET2(_buf,_max,_x,_y) BIT_GET((_buf),((_x)*(_max)+(_y)))

int main(int argc, char* argv[])
{
        char buf={0};
        int s=5;;
        BIT_SET(buf,25);
        s = BIT_GET(buf,25);
        printf("25=%d\n",s);
        BIT_CLR(buf,25);
        s = BIT_GET(buf,25);
        printf("25=%d\n",s);

        BIT_SET2(buf,21,3,2);
        BIT_CLR2(buf,21,2,3);
        s = BIT_GET2(buf,21,3,2);
        printf("2,3=%d\n",s);
        BIT_CLR2(buf,21,2,3);
        s = BIT_GET2(buf,21,2,3);
        printf("2,3=%d\n",s);
        printf("Hello World!\n");
        return 0;
}

sjzd 发表于 2008-8-7 18:56:44

问下 【1楼】 mingyuexin1981
      typedef struct
      {
                unsigned long int a:1;
                unsigned long int b:1;
                        .
                        .
                      依次类推         
                        .
                unsigned long int u:1;
                unsigned long int :11;
      }A;

把 里面的unsigned long int   换成unsigned char 有什么区别

davecater 发表于 2008-8-7 20:03:26

typedef struct   
      {
                unsigned long int a:1;
                unsigned long int b:1;
                        .
                        .
                      依次类推         
                        .
                unsigned long int u:1;
                unsigned long int :11;
      }A;
是位段定义,unsigned long int用于表定义一个32位的位段,而unsigned char则定义一个8位的位段,而上面是访问21位

sjzd 发表于 2008-8-7 20:41:54

明白非常感谢

FlashNuk 发表于 2008-8-7 21:13:06

不错

wangxiaoacc 发表于 2008-8-8 11:12:18

学习了~!~

34480016 发表于 2008-8-8 11:18:58

顶一顶

78057812 发表于 2008-8-8 18:14:23

这些东西 咋在书上都没有介绍的啊,唉~

huanxian 发表于 2008-8-8 23:11:49

顶一顶

xiaoxu191 发表于 2008-8-9 01:56:35

不算不知道,一算吓一跳。

一楼的方法已经很节省空间了,可是2楼的方法还可以进一步节省空间。例如,21×21,一楼的方法是84字节,二楼的方法是56字节,节约28个字节。很可观呀。

方法      字节占用
2维数组   n×n
1楼       4n
2楼       (n×n + 7)/8,取整

而且2楼的方法可以任意扩展数组的大小。妙得很啊。

zy473551 发表于 2008-8-9 23:41:42

学习了

yaya001 发表于 2008-8-10 00:26:34

学习了 谢谢

shupeng_avr 发表于 2008-8-19 08:13:18

不错.

zook0k 发表于 2008-8-19 09:10:23

4的代码谁看懂了,分析下,只能看懂个大概方向.

mtheory 发表于 2008-8-19 09:20:56

顶一下,以后应该会用到。。。

xielihong 发表于 2008-8-19 10:18:13

回17楼的,<<3 相当于 *8 即一个字节的大小,这样也许能帮助理解

zook0k 发表于 2008-8-19 10:59:51

谢谢,
#define BIT_SET(_buf,_id) \
{ ((char *)(buf))[(_id)/(sizeof(char)<<3)] |= 1<<(_id)%(sizeof(char)<<3); }

char buf={0};
BIT_SET(buf,25);
你这个是针对buf整个数组操作,还是数组的前几个操作,为什么定义那么长的数组,只能领悟到数组置1置0,体会不到13楼感受到的那么的美妙.
还期望蚂蚁详细分下下.我有2个地方不大明白,只是能猜出什么意思,不大透彻
1 BIT_SET(buf,25); 传递的参数是什么意思,是buf指向的数组区第25个置1?
2 ((char *)(buf))这个不大明白,类型转换为指向char的指针?
3 上面有的是buf 有的是_buf,通用?

因为这个我没用过,所以不怎么明白,谢谢了.

xk2yx 发表于 2008-8-19 11:04:51

不错。

xielihong 发表于 2008-8-19 11:13:15

1 BIT_SET(buf,25); 传递的参数是什么意思,是buf指向的数组区第25个置1?
如果将buf,看成是bit型缓冲区的话,是第25个
如果是将buf看成char型缓冲区的话,是第25/8个的第25%8位

2.缓冲区指针的强制转换

3.不通用,你真眼尖,我犯了一个错误,正确的应该为
#define BIT_SET(_buf,_id) \
{ ((char *)(_buf))[(_id)/(sizeof(char)<<3)] |= 1<<(_id)%(sizeof(char)<<3); }

#define BIT_CLR(_buf,_id) \
{ ((char *)(_buf))[(_id)/(sizeof(char)<<3)] &= ~(1<<(_id)%(sizeof(char)<<3)); }

#define BIT_GET(_buf,_id) \
(((char *)(_buf))[(_id)/(sizeof(char)<<3)] >> ((_id)%(sizeof(char)<<3))        & 0x01)

#define BIT_ROW_MAX   21
#define BIT_SET2(_buf,_max,_x,_y) BIT_SET((_buf),((_x)*(_max)+(_y)))
#define BIT_CLR2(_buf,_max,_x,_y) BIT_CLR((_buf),((_x)*(_max)+(_y)))
#define BIT_GET2(_buf,_max,_x,_y) BIT_GET((_buf),((_x)*(_max)+(_y)))

zook0k 发表于 2008-8-19 11:22:39

明白了,谢谢蚂蚁.

xielihong 发表于 2008-8-19 11:50:50

再说几句,
在一个应用中,应该这么用
#define BUFSIZ 4
uchar buf={0};
#define SET(_id) BIT_SET(buf,_id)
#define CLR(_id) BIT_CLR(buf,_id)
#define GET(_id) BIT_GET(buf,_id)

#define LIGHT0   (1<<0)
#define LIGHT1   (1<<1)
...
#define LIGHTn   (1<<n) /* n < BUGSIZ*8*/


函数中调用
uchar lightState;
SET(LIGHT0);
CLR(LIGHT3);
lightState = GET(LIGHT9);

在51中可以这样优化
uchar data buf={0};
{ ((char data * data)(_buf))[(_id)/(sizeof(char)<<3)] |= 1<<(_id)%(sizeof(char)<<3); }

bad_fpga 发表于 2008-8-19 12:37:26

很好的思路,顶下

haosheng 发表于 2008-9-1 10:58:55

记号

xorX 发表于 2010-11-12 15:21:56

一维的咋搞?没明白

ag_wang 发表于 2010-11-28 23:46:36

好方法,记下!

yiminglei 发表于 2010-11-29 00:16:01

学习了

zhenke 发表于 2010-11-29 00:21:27

Mark!

liangyurongde 发表于 2010-11-29 08:17:15

mark

worldly_guest 发表于 2010-11-29 09:27:58

mark一下

maomaomao007 发表于 2011-8-10 20:57:01

学习了

liusoldier 发表于 2011-8-10 21:26:52

我跟随挖坟的做个标记

bolimao101 发表于 2011-8-23 21:32:47

谢谢,已经基本领悟,收藏一下,用的时候复习一下

xizi 发表于 2011-8-24 04:59:37

既然有人挖出来了,就标记下。

首先看懂了4楼的前几句:
#define BIT_SET(_buf,_id) \
{ ((char *)(buf))[(_id)/(sizeof(char)<<3)] |= 1<<(_id)%(sizeof(char)<<3); }

#define BIT_CLR(_buf,_id) \
{ ((char *)(buf))[(_id)/(sizeof(char)<<3)] &= ~(1<<(_id)%(sizeof(char)<<3)); }

#define BIT_GET(_buf,_id) \
(((char *)(buf))[(_id)/(sizeof(char)<<3)] >> ((_id)%(sizeof(char)<<3)) & 0x01)

20楼问道:((char *)(buf))这个不大明白,类型转换为指向char的指针?

我理解这里做强制类型转换有一点好处:buf数组元素可以是任何整数类型,只要字节数量足够就可。比如楼主的问题可以定义
char buf;//21*21=441, 56*8=448 > 441.
也可以定义
int buf;//21*21=441, 14*32=448 > 441.

两个buf都可以直接使用4楼方法
BIT_SET(buf, 20);

以及
BIT_SET2(buf, 21, 0, 20);

wjf0509 发表于 2011-8-24 08:59:37

受教!

enric_lee 发表于 2012-6-4 16:57:24

很不错,研究下

Q28182900 发表于 2012-12-6 10:20:55

页: [1]
查看完整版本: 21*21二维数组如何定义比较好(都是bit型,定义成char型太浪费空间了)