㈠ c语言是怎样实现位段的
C语言提供了位域。
摘自<谭书>
位域
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:
struct 位域结构名
{ 位域列表 };
其中位域列表的形式为: 类型说明符 位域名:位域长度
例如:
struct bs
{
int a:8;
int b:2;
int c:6;
};
位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:
struct bs
{
int a:8;
int b:2;
int c:6;
}data;
说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明:
1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:
struct bs
{
unsigned a:4
unsigned :0 /*空域*/
unsigned b:4 /*从下一单元开始存放*/
unsigned c:4
}
在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。
3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:
struct k
{
int a:1
int :2 /*该2位不能使用*/
int b:3
int c:2
};
从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。
二、位域的使用位域的使用和结构成员的使用相同,其一般形式为: 位域变量名·位域名 位域允许用各种格式输出。
main(){
struct bs
{
unsigned a:1;
unsigned b:3;
unsigned c:4;
} bit,*pbit;
bit.a=1;
bit.b=7;
bit.c=15;
printf("%d,%d,%d\n",bit.a,bit.b,bit.c);
pbit=&bit;
pbit->a=0;
pbit->b&=3;
pbit->c|=1;
printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);
}
上例程序中定义了位域结构bs,三个位域为a,b,c。说明了bs类型的变量bit和指向bs类型的指针变量pbit。这表示位域也是可以使用指针的。
程序的9、10、11三行分别给三个位域赋值。( 应注意赋值不能超过该位域的允许范围)程序第12行以整型量格式输出三个域的内容。第13行把位域变量bit的地址送给指针变量pbit。第14行用指针方式给位域a重新赋值,赋为0。第15行使用了复合的位运算符"&=", 该行相当于: pbit->b=pbit->b&3位域b中原有值为7,与3作按位与运算的结果为3(111&011=011,十进制值为3)。同样,程序第16行中使用了复合位运算"|=", 相当于: pbit->c=pbit->c|1其结果为15。程序第17行用指针方式输出了这三个域的值。
㈡ C语言变量定义
这个表示的是位域,表示变量所占得位数位结构是c51语言中的一种特殊结构,可以用于访问一个字节或字的多个位。位结构一般形式如下。
struct
位结构名
{
数据类型
变量名:
整形常数;
数据类型
变量名:
整形常数;
}位结构变量;
其中,struct为关键字,位结构数据类型必须是整型int(unsigned或signed);整形常熟必须是非负的整数,范围是0~15,用于表示有多少位,即表示二进制位的个数,变量名是可选项,可以省略。位结构的定义,实例如下。
struct
{
unsigned
lbit
:
8;
//lbit
占用低字节0~7共八位。
unsigned
hbit0
:
4;
//hbit0
占用高字节0~3共4位。
unsigned
hbit1
:
3;
//hbit1
占用高字节4~6共3位。
unsigned
hbit2
:
1;
//hbit2
占用高字节第7位。
}bit;
位结构成员的访问与结构成员的访问相同,例如访问上列位结构中的lbit成员可写成如下形式
bit.lbit
在使用位结构时,应注意以下几点。
1、位结构中的成员必须是int,但可以定义为unsigned或者signed。
2、当位结构成员长度为1时,c51语言将其认为是unsigned类型。
3、位结构总长度(位数)是各个位成员定义的位数之和,可以超过两个字节。
4、位结构中的成员不能使用数组和指针,但位结构变量可以是数组和指针。如果是指针,其成员访问方式同结构指针。
5、位结构可以成为嵌套式结构的成员,与其他结构成员一起使用,示例如下。
struct
student
{
char
*name;
int
num;
int
age;
char
*sex;
float
score;
unsigned
reister:1;
unsigned
pay:1;
};
㈢ c语言的bit类型
C语言中bit类型是“位”数据类型,一般在嵌入式软件中应用较多,用于IO口的控制,可以是单独申明位变量,也可以申请位结构数据类型,比如:
structst_flash{/*structFLASH*/
union{/*FLMCR1*/
unsignedcharBYTE;/*ByteAccess*/
struct{/*BitAccess*/
unsignedcharFWE:1;/*FWE*/
unsignedcharSWE1:1;/*SWE1*/
unsignedcharESU1:1;/*ESU1*/
unsignedcharPSU1:1;/*PSU1*/
unsignedcharEV1:1;/*EV1*/
unsignedcharPV1:1;/*PV1*/
unsignedcharE1:1;/*E1*/
unsignedcharP1:1;/*P1*/
}BIT;
}FLMCR1;
union{/*FLMCR2*/
unsignedcharBYTE;/*ByteAccess*/
struct{/*BitAccess*/
unsignedcharFLER:1;/*FLER*/
unsignedcharSWE2:1;/*SWE2*/
unsignedcharESU2:1;/*ESU2*/
unsignedcharPSU2:1;/*PSU2*/
unsignedcharEV2:1;/*EV2*/
unsignedcharPV2:1;/*PV2*/
unsignedcharE2:1;/*E2*/
unsignedcharP2:1;/*P2*/
}BIT;
}FLMCR2;
union{/*EBR1*/
unsignedcharBYTE;/*ByteAccess*/
struct{/*BitAccess*/
unsignedcharEB7:1;/*EB7*/
unsignedcharEB6:1;/*EB6*/
unsignedcharEB5:1;/*EB5*/
unsignedcharEB4:1;/*EB4*/
unsignedcharEB3:1;/*EB3*/
unsignedcharEB2:1;/*EB2*/
unsignedcharEB1:1;/*EB1*/
unsignedcharEB0:1;/*EB0*/
}BIT;
}EBR1;
union{/*EBR2*/
unsignedcharBYTE;/*ByteAccess*/
struct{/*BitAccess*/
unsignedcharEB15:1;/*EB15*/
unsignedcharEB14:1;/*EB14*/
unsignedcharEB13:1;/*EB13*/
unsignedcharEB12:1;/*EB12*/
unsignedcharEB11:1;/*EB11*/
unsignedcharEB10:1;/*EB10*/
unsignedcharEB9:1;/*EB9*/
unsignedcharEB8:1;/*EB8*/
}BIT;
}EBR2;
};
㈣ C语言中位段结构体移位问题
t,r都是结构变量,C语言规定只能引用结构体成员而不能直接用结构体变量赋值,所以不能这样.
t=t>>1; //要把t整体移动一位怎么移,移了过后又是什么
此结构体最小长度是一个unsigned,如是char 就有8位,int就有16位,而t只占最右一位,右移一位就是把t值清零.
㈤ C语言中如何将16位结构体定义为4位和12位两部分
没法定义,只是在使用的时候可以实现4位与12位的效果。可以将A与B分别定义成16位的,按两个成员来用。或定义成一个16位成员,然后在读、写时分别处理高四位与低12位。
㈥ C语言什么是位段,位段的定义求答案
位段(bit-field)是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。
位段的定义格式为:
type [var]:digits
其中type只能为int,unsigned int,signed int三种类型(int型能不能表示负数视编译器而定)。位段名称var是可选参数,即可以省略。digits表示该位段所占的二进制位数。
那么定义一个位段结构可以像下面这段代码去定义:
structnode
{
unsignedinta:4;//位段a,占4位
unsignedint:0;//无名位段,占0位
unsignedintb:4;//位段b,占4位
intc:32;//位段c,占32位
int:6;//无名位段,占6位
};
使用位段需注意一下几点:
1)位段的类型只能是int,unsigned int,signed int三种类型,不能是char型或者浮点型;
2)位段占的二进制位数不能超过该基本类型所能表示的最大位数,比如在VC中int是占4个字节,那么最多只能是32位;
3)无名位段不能被访问,但是会占据空间;
4)不能对位段进行取地址操作;
5)若位段占的二进制位数为0,则这个位段必须是无名位段,下一个位段从下一个位段存储单元(这里的位段存储单元经测试在VC环境下是4个字节)开始存放;
6)若位段出现在表达式中,则会自动进行整型升级,自动转换为int型或者unsigned int。
7)对位段赋值时,最好不要超过位段所能表示的最大范围,否则可能会造成意想不到的结果。
8)位段不能出现数组的形式。
㈦ c语言中位段和结构体
由右至左指的是位在一个unsigned里的存储位置,如果这里的unsigned是16位
那么a占低2位,b占低3位,c占低4位
高 ——> 低
|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|
所以data.a = 8,由于a只占2位,最大能保存3,所以溢出,data.a = 0,最后结果是输出2
㈧ C语言中的位字段结构
因为你定义的位字段只能有两位二进制位
3的二进制是11
4的二进制是100
所以赋值4的话就会超出一位,出错
㈨ C语言的结构体位定义问题
1.我认为uint16_t这是你定义的一个新类型
typedef unsigned short uint16_t; /*就是定义无符号短整型为 uint16_t*/
typedef unsigned char uint8_y; /*定义无符号char型为 uint8_t*/
两个结构体中只有这地方不同,对于第二个结构提,因为char型,只有8位,当超过8bit时,会自动的申请新的字节进行存储,因此第二个字节使用2个1字节存储,而第一个结构体使用1个2字节存储。
2.对于冒号,这是C语言中位域的用法,有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。
例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示
具体例子如下:
#include <stdio.h>
typedef unsigned char u8;
/*定义新类型,这个新类型由4部分组成,每部分只占无符号char型8bit
中的几bit*/
typedef struct _my_bit_
{
u8 one:1;
u8 two:2;
u8 three:3;
u8 four:2;
}mybitfiled;
int main()
{
mybitfiled mybit;
/*注意位域分配的位个数,例如one只分配了1bit,那么mybit.one只能为1或0,
如果输入2的话,那么会提示将多余部分给删掉的,意思只能取最后1bit的信息*/
mybit.one = 1;
mybit.two = 2;
mybit.three = 3;
mybit.four = 1;
printf("sizeof(mybit) = %d,%d %d %d %d\n",sizeof(mybit),mybit.one,mybit.two,mybit.three,mybit.four);
return 0;
}
㈩ C语言中,如何读取位结构体中的bit位的偏移量和bit数
2812里的寄存器都是这么设置成共用体的吧,你是结构体和共用体的引用没有学明白,可以看看C语言书本上关于这部份的内容。可以直接定义每个位,比如UNINPUTS.bit2.bCurrent
=5,那么对应的那3个位就变成了101