c语言里对位相加,C语言中对位段的理解

C语言中对位的操作有两种方法,一种是采用位操作符直接对位进行操作,另外一种是使用位字段对位进行操作。对位字段的接触源于这样一段代码:

typedef struct{

unsigned int

raw1:16;

unsigned int raw2:16;

} dataraw0;

最初的代码其实是这样的:

typedef struct{

char

raw1:16;

char

raw2:16;

} dataraw0;

很不幸,上面这样的代码是无法通过编译的,错误的原因并不在于位段的类型是char类型,而是在于位段位数16超出了char的位数范围。代码报错为:

type of bit field too small for number of

bits。实际上char是int类型,因为char存储的是整数而不是字符。

同时,对于位字段 float raw3:32 也会出现错误,代码报错为:bit

field must have type 'int', 'signed int', or 'unsigned int'。

同时,对于位字段 long raw4:32 或 long long

raw5:64 却不会出现错误。

也就是说声明的位字段应是unsigned int 或 signed

int。显然对位字段类型否是short或long、long long 并没有做出明确的规定。

若将上述代码修改为:

typedef struct{

unsigned int

raw1:16;

unsigned int raw2:16;

char

flag:1;

} dataraw1;

我们声明变量

dataraw0 data1;

dataraw1 data2;

通过sizeof()函数查看结构dataraw0与dataraw2的大小:

the size of dataraw0 is 4 byte.

the size of

dataraw1 is 8 byte.

可见,位字段是一个signed int或unsigned

int中一组相邻的位。变量data1完整的使用了unsigned

int类型中的一个存储单元,即4个byte。变量data2使用了两个unsigned

int类型的存储单元,即8个byte;其中一个存储单元的位被完全使用,而第二个存储单元仅仅使用了2位,剩余的30位没有被使用。

需要注意的两点是:

一、不允许一个字段跨越两个unsigned int或singed

int之间的边界。编译器自动地移位一个这样的字段定义,使字段按unsigned int或singed

int边界对齐。发生这样的情况,会在第一个unsigned

int中留下一个未命名的“洞”。可以使用未命名的字段进行填充未命名的洞。使用一个宽度为0的未命名字段迫使下一个字段与下一个整数对齐。如:

typedef struct{

unsigned

int raw1:1;

unsigned

int raw2:2;

unsigned

int :0;

unsigned int

raw3:1;

} dataraw2;

通过sizeof()函数查看结构dataraw2大小为8个字节。可见,宽度为0的未命名字段使得下一个字段raw3与一个整数对齐。

二、一个重要的依赖性是字段放置在int中的顺序,有的机器是从左到右,有的是从右到左。另外,不同机器在两个字段间边界的位置也有区别。因此,位字段往往难以移植。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值