C 语言中的段位操作
1.位段结构中位段的定义格式为
unsigned :
例如
struct bytedata
{unsigned a:2; /*位段a占2位*/
unsigned:6; /*无名位段占6位但不能访问*/
unsigned:0; /*无名位段占0位表下一位段从下一字边界开始*/
unsigned b:10; /*位段b占10位*/
int i; /*成员i从下一字边界开始*/
}data;
2.
(1)一个位段必须存储在同一存储单元(即字)之中不能跨两个单元。如果其单元空间不够则剩余空间不用从下一个单元起存放该位段。
(2)可以通过定义长度为0的位段的方式使下一位段从下一存储单元开始。
(3)可以定义无名位段。
(4)位段的长度不能大于存储单元的长度。
(5)位段无地址不能对位段进行取地址运算。
(6)位段可以以%d%o%x格式输出。
(7)位段若出现在表达式中将被系统自动转换成整数。
拷贝2C语言中的结构是有实现位段的能力的噢你问它到底是什么形式是吧这个问题呆会给你答案。让我们先看看位段的作用位段是在字段的声明后面加一个冒号以及一个表示字段位长的整数来实现的。这种用法又被就叫作“深入逻辑元件的编程”如果你对系统编程感兴趣那么这篇文章你就不应该错过
我把使用位段的几个理由告诉大家1、它能把长度为奇数的数据包装在一起从而节省存储的空间2、它可以很方便地访问一个整型值的部分内容。
首先我要提醒大家注意几点1、位段成员只有三种类型int ,unsigned int 和signed int这三种(当然了int型位段是不是可以取负数不是我说了算的因为这是和你的编译器来决定的。位段位段它是用来表示字段位长(bit)的它只有整型值不会有7.2这种float 类型的如果你说有那你就等于承认了有7.2个人这个概念当然也没有char这个类型的)2、成员名后面的一个冒号和一个整数这个整数指定该位段的位长(bit);3、许多编译器把位段成员的字长限制在一个int的长度范围之内4、位段成员在内存的实现是从左到右还是从右到左是由编译器来决定的但二者皆对。
下面我们就来看看它到底是什么东西(我先假定大家的机器字长为32位)
Struct WORD
{
unsigned int chara: 6:
unsigned int font : 7;
unsigned int maxsize : 19;
};
Struct WORD chone;
这一段是从我编写的一个文字格式化软件摘下来的它最多可以容纳64(既我说的unsigned int chara :6; 它总共是6位)个不同的字符值可以处理128(既unsigned int font : 7 ;既2的7次方)种不同的字体和2的19次方的单位长度的字。大家都可以看到 maxsize是19位它是无法被一个short int 类型的值所容纳的我们又可以看到其余的成员的长度比char还小这就让我们想起让他们共享32位机器字长这就避免用一个32位的整数来表示maxsize的位段。怎么样还要注意的是刚才的那一段代码在16位字长的机器上是无法实现的为什么提醒你一下看看上面提醒的第3点你会明白的
你是不是发现这个东西没有用啊如果你点头了那你就错了这么伟大的创造怎么会没有用呢(你对系统编程不感兴趣相信你会改变这么一个观点的)磁盘控制器大家应该知道吧软驱与它的通信我们来看看是怎么实现的下面是一个磁盘控制器的寄存器
│←5→│←5→│←9→│←8→│←1→│←1→∣←1→∣←1→∣←1→∣
上面位段从左到右依次代表的含义为5位的命令5位的扇区9位的磁道8位的错误代码1位的HEAD LOADED,1位的写保护1位的DISK SPINNING1位的错误判断符还有1位的READY位。它要怎么来实现呢你先自己写写看
struct DISK_FORMAT
{
unsigned int command : 5;
unsigned sector : 5;
unsigned track : 9 ;
unsigned err_code : 8;
unsigned ishead_loaded : 1;
unsigned iswrit_protect : 1;
unsigned isdisk_spinning : 1;
unsigned iserr_ocur : 1;
undigned isready :1 ;
};
注代码中除了第一行使用了unsigned int 来声明位段后就省去了int 这是可行的详见ANCI C标准。
如果我们要对044c18bfH的地址进行访问的话那就这样
#define DISK ((struct DISK_FORMAT *)0x044c18bf)
DISK->sectorfst_sector;
DISK->trackfst_track;
DISK->commandWRITE;
当然那些都是要宏定义的哦
我们用位段来实现这一目的是很方便的其实这也可以用移位或屏蔽来实现你尝试过就知道哪个更方便了
测试代码:
i nclude int main()
{
struct
{
unsigned short s1 : 4;
unsigned short s2 : 3;
unsigned short s3 : 2;
}x;
char c 0x7A; // 0111 1010 b
x.s1 c;
printf( "%x\n", x.s1 );
return 0;
}
根据编译器的不同可能出现大端和小端的问题小端就是从低位开始取值大端就是从高位取值。
常见为小端模式。
阅读(432) | 评论(0) | 转发(0) |