九联合union十数据的引用类型转换十一位域或位字段

上传人:痛*** 文档编号:179896389 上传时间:2023-01-03 格式:PPT 页数:42 大小:287.03KB
返回 下载 相关 举报
九联合union十数据的引用类型转换十一位域或位字段_第1页
第1页 / 共42页
九联合union十数据的引用类型转换十一位域或位字段_第2页
第2页 / 共42页
九联合union十数据的引用类型转换十一位域或位字段_第3页
第3页 / 共42页
点击查看更多>>
资源描述
12九、联合九、联合union1.联合的特性和定义联合的特性和定义 由关键字由关键字struct声明的数据描述称为结构类型而声明的数据描述称为结构类型而union 或或class声明的数据描述称为联合类型或类类型声明的数据描述称为联合类型或类类型,分别简称为分别简称为结构和联合或类。结构和联合或类。结构、联合、类是集合数据类型。结构、联合、类是集合数据类型。int、float等是系统预先取好的可以直接使用的类名,等是系统预先取好的可以直接使用的类名,关键字关键字struct和和union 或或class后紧跟的标识符则是用户引入后紧跟的标识符则是用户引入的类名,需要事先加以声明。的类名,需要事先加以声明。3 在程序设计中常出现非此即彼的数据,这些数据的类型在程序设计中常出现非此即彼的数据,这些数据的类型可以不同,需要将其放置在同一片内存。可以不同,需要将其放置在同一片内存。关键字关键字union 建立的数据类型为用户引入的联合类型,建立的数据类型为用户引入的联合类型,简称联合。联合一方面是节省内存空间,另一方面是特殊的简称联合。联合一方面是节省内存空间,另一方面是特殊的编程考虑。编程考虑。联合的特性和定义联合的特性和定义:联合类型定义的变量称为联合变量。指向联合变量的指联合类型定义的变量称为联合变量。指向联合变量的指针简称为联合指针。联合类型的声明和联合变量的定义采用针简称为联合指针。联合类型的声明和联合变量的定义采用与结构类似的语法,不同的是联合使用关键字与结构类似的语法,不同的是联合使用关键字union。4将前面关于结构声明复制过来略加变动并用将前面关于结构声明复制过来略加变动并用union替代替代struct得到:得到:union UnionName 联合联合 联合名联合名 type member;数据类型数据类型 成员名成员名;type2 member2;数据类型数据类型2 成员名成员名2;typen membern;数据类型数据类型n 成员名成员名n;;关键字关键字union用于声明同一片内存可以存放不同类型的用于声明同一片内存可以存放不同类型的数据,但在一个时刻只有某一类型的数据处于有效的状态。数据,但在一个时刻只有某一类型的数据处于有效的状态。5联合类型声明中的数据成员具有如下的性质:联合类型声明中的数据成员具有如下的性质:a.不同的成员占有起始地址相同的内存区域,这些成不同的成员占有起始地址相同的内存区域,这些成员以并排的方式重合在一起。员以并排的方式重合在一起。b.该内存区域的长度确定为所有成员中占有内存空间该内存区域的长度确定为所有成员中占有内存空间最长的成员所对应的长度。最长的成员所对应的长度。c.在一个具体的时刻仅包含一种数据成员有效虽然成在一个具体的时刻仅包含一种数据成员有效虽然成员可以是集合型的数据。员可以是集合型的数据。d.初始化联合变量时默认对第一个成员进行赋值亦仅初始化联合变量时默认对第一个成员进行赋值亦仅对一个成员赋值,初始值的类型属性应与第一个成员的类型对一个成员赋值,初始值的类型属性应与第一个成员的类型属性一致,否则编译器至少给出警告。属性一致,否则编译器至少给出警告。e.C+中联合不参入继承机制即联合类既不作基类也不中联合不参入继承机制即联合类既不作基类也不作派生类,不能有虚拟函数。作派生类,不能有虚拟函数。6例例 联合的内存和结构的内存大小比较联合的内存和结构的内存大小比较#include typedef struct s_a double d;char c9;A;typedef struct s_b double d;long k2;B;typedef union u_t A a;B b;U;typedef struct s_t A a;B b;S;void main(void)printf(sizeof(A)=%d,sizeof(A);printf(sizeof(B)=%d,sizeof(B);printf(sizeof(U)=%d,sizeof(U);printf(sizeof(S)=%d,sizeof(S);/输出输出:sizeof(A)=24,sizeof(B)=16,16,sizeof(U)=24,24,sizeof(S)=407 联合一经声明就可以定义联合变量、联合数组和联合指联合一经声明就可以定义联合变量、联合数组和联合指针。针。箭头运算符箭头运算符“-”与圆点运算符与圆点运算符“.”可以用来访问联合可以用来访问联合中中的成员,箭头运算符的成员,箭头运算符-的左侧是联合指针,圆点操作符的左侧是联合指针,圆点操作符.“的左侧是联合变量,右侧是联合中的成员。的左侧是联合变量,右侧是联合中的成员。这和结构变量的使用规则一致。这和结构变量的使用规则一致。不同的是结构变量拥有结构中各独立的成员所占内存之不同的是结构变量拥有结构中各独立的成员所占内存之和;和;联合变量则仅是最大成员所拥有的内存,这一片内存可联合变量则仅是最大成员所拥有的内存,这一片内存可由若干类型属性不同的成员适当索引,它们齐头地占有同一由若干类型属性不同的成员适当索引,它们齐头地占有同一块内存。块内存。8联合遵循先声明后定义再使用的次序。如下所示:联合遵循先声明后定义再使用的次序。如下所示:typedef union u_t int k4;long member;float y;U;U obj,*pobj;obj.member /联合变量名联合变量名.成员名成员名 pobj-member /联合指针名联合指针名-成员名成员名三个步骤可以合为一体,再加上初始化格式为:三个步骤可以合为一体,再加上初始化格式为:union u_t int k4;long member;float y;b=1,2,3,4;初始化只对第一个联合成员进行。该凝练的格式声明一初始化只对第一个联合成员进行。该凝练的格式声明一个名为个名为u_t的联合名,其拥有三个并置的成员,第一个是的联合名,其拥有三个并置的成员,第一个是int型的数组成员型的数组成员k4、第二个是、第二个是long型的成员型的成员member,第三,第三个是个是float型的成员型的成员y.这三个成员的内存起始地址是一样的。这三个成员的内存起始地址是一样的。9例例 联合指针入口形参和联合引用返回联合指针入口形参和联合引用返回#include inline int f(int k)return k;typedef union u_t char*s;int(*f)(int);int d;Un;Un&initial(Un*p,int n,char*s)switch(n)case 1:p-s=s;break;case 2:p-f=f;break;default:p-d=n;break;/三个成员互斥地使用同一内存三个成员互斥地使用同一内存 return*p;void main(void)Un x;for(int n=1;n4;n+)10 Un y=initial(&x,n,abcd);switch(n)case 1:printf(%s,%st,x.s,y.s);break;case 2:printf(%d,%dt,x.f(1),y.f(2);break;default:printf(%d,%dn,x.d,y.d);break;/输出:输出:abcd,abcd1,2 3,3 联合变量、联合指针和联合引用可以作为形参,联合变联合变量、联合指针和联合引用可以作为形参,联合变量可以相互赋值。量可以相互赋值。对联合变量的操作需要特别注意成员的类型属性,不同对联合变量的操作需要特别注意成员的类型属性,不同类型属性的成员应由不同的分支处理。类型属性的成员应由不同的分支处理。112.联合的内存映像联合的内存映像考虑如下初始化于一体的联合声明和联合变量的定义:考虑如下初始化于一体的联合声明和联合变量的定义:union u_t int k4;long z;float y;b=1,2,3,4,c;声明了一个联合名为声明了一个联合名为u_t的联合类型,具有三个成员,的联合类型,具有三个成员,这三个成员是这三个成员是int型数组型数组k4,long型成员型成员z,float型成员型成员y。第一个成员是数组成员第一个成员是数组成员k。同时定义了两个联合变量。同时定义了两个联合变量b和和c,在定义联合变量,在定义联合变量b的时候对其第一个成员进行了初始化的时候对其第一个成员进行了初始化处理。处理。该联合占有的内存空间是:该联合占有的内存空间是:sizeof(b)=sizeof(union u)=sizeof(int4)=sizeof(b.k)=1612 该联合在该联合在32位编程模式下的内存布局如下:位编程模式下的内存布局如下:int型数组型数组k4 long型成员型成员z 8 12 16 float型成员型成员y 4 联合的数据内存分布联合的数据内存分布 在在PC微机上数据的存放方式是低尾端形式的微机上数据的存放方式是低尾端形式的,即即short型型16位字节的低位字节的低8位存放在内存的低地址处位存放在内存的低地址处,高高8bit存放在内存放在内存的高地址处高尾端的存放方式则相反。存的高地址处高尾端的存放方式则相反。下页的例子说明数据在下页的例子说明数据在PC内存中的顺序是低尾端形式。内存中的顺序是低尾端形式。k0k1K2K313例例 强制类型转换显示低尾端的存储格式强制类型转换显示低尾端的存储格式(8位二进制数的低位二进制数的低位在右边,高位在左边位在右边,高位在左边).#includevoid main()unsigned long m=0 x87654321UL;unsigned char*p=(unsigned char*)&m;for(int i=0;isizeof(long);i+)printf(%x,*p+);14 上例低尾端的上例低尾端的PC计算上输出结果:计算上输出结果:21 43 65 87 这样这样32位整数的位整数的8个个 4位二进制数的十六进制数数码表示位二进制数的十六进制数数码表示为为:m=h7h6h5h4h3h2h1h0 =87654321 该数以字节即该数以字节即8位位bit为最小内存寻址单位的内存存储格为最小内存寻址单位的内存存储格式为式为(低地址标注在左边低地址标注在左边):16进制表示:进制表示:低地址低地址 高地址高地址 2进制表示:进制表示:低地址低地址 高地址高地址 21 43 65 87 00100001 01000011 01100101 1000011115 联合的同一片内存可以通过不同的名称索引。对一个成联合的同一片内存可以通过不同的名称索引。对一个成员的改变直接影响联合中的其它成员的数据状态,对数据的员的改变直接影响联合中的其它成员的数据状态,对数据的解释取决于数据的存储格式和模块转换。解释取决于数据的存储格式和模块转换。例例 联合的内存布局和内存数据的解释联合的内存布局和内存数据的解释#include typedef union u_t char c2;unsigned long k;U;void main()U x=3,1;/x.c0=3;x.c1=1;潜在地导致潜在地导致x.c2=0;x.c3=0;printf(%d,0 x%08xt,x.k,x.k);x.k=0 x67686162UL;printf(%c,%d,%c,%d;,x.c0,x.c0,x.c1,x.c1);printf(%c,%d,%c,%dn,x.c2,x.c2,x.c3,x.c3);16 说明:占说明:占4字节的整型数字节的整型数 (4个个8位的十六进制数位的十六进制数)存贮格存贮格式在微机上是低尾端格式式在微机上是低尾端格式,具有如下的形式(低地址标注在具有如下的形式(低地址标注在边,边,8位二进制数的低位在右边)位二进制数的低位在右边):高地址高地址 低地址低地址 k=0 x0000|0103 1*16*16+3=259 x.k=0 x67686162UL;高地址高地址 低地址低地址 d3 00000000 d2 00000000 d1 00000001 d0 000000011 0 x67 0 x68 0 x61 0 x62c0=300000011c1=100000001 c2 c3c00 x62bc10 x61a c2 c317例例浮点数和整型数内存存储格式不同浮点数和整型数内存存储格式不同#include typedef union u_fl float f;long k;Ua;typedef union u_il int f;long k;Ub;struct Sab union float f;long k;a;Ub b;s=1.0,2;void main()printf(%1.0f,%dt,s.a.f,s.b.f);Ua&x=(Ua&)s.a;x.f=10;printf(%d,%dt,(long)(x.f+s.a.f),x.k);x.k=20;printf(%d,%dt,(long)x.f,x.k+s.a.k);Ub&y=s.b;y.f=10;printf(%d,%dt,(long)y.f,s.b.k);y.k=20;printf(%d,%dn,(long)s.b.f,y.k);/输出:输出:1,2 20,1092616192 0,40 10,10 20,20 18 联合将不同类型的数据锁定在一块起始地址相同的内存联合将不同类型的数据锁定在一块起始地址相同的内存,通过不同的成员名称或别名来索引内存通过不同的成员名称或别名来索引内存,以多种方式解释同以多种方式解释同一内存数据。一内存数据。联合具有特殊的数据强制类型转换的能力。联合具有特殊的数据强制类型转换的能力。注意:注意:union float f;long k;a;是联合类型直接定是联合类型直接定义变量,此时联合是无名的。但这种格式不减少访问内层成义变量,此时联合是无名的。但这种格式不减少访问内层成员的层次员的层次。193.无名联合无名联合 无名联合在声明时不带联合名,这种声明在无名联合在声明时不带联合名,这种声明在C+语言语言中具有特殊的含义。中具有特殊的含义。在无名联合中定义的名称超出定界的一对花括号之外,在无名联合中定义的名称超出定界的一对花括号之外,不能跟同一作用范围其它的变量名冲突,不能有成员函数。不能跟同一作用范围其它的变量名冲突,不能有成员函数。在全局范围定义的无名联合必须声明为静态的,结构中的无在全局范围定义的无名联合必须声明为静态的,结构中的无名联合其成员访问控制属性是公共的,不允许存在私有的成名联合其成员访问控制属性是公共的,不允许存在私有的成员。员。a.局部的和全局的无名联合局部的和全局的无名联合 局部范围的无名联合实际上定义的是内存共享的变量,局部范围的无名联合实际上定义的是内存共享的变量,这些不同类型的变量拥有相同的起始内存地址,内存数据的这些不同类型的变量拥有相同的起始内存地址,内存数据的有效性取决于最新的二进制状态和对上下文环境的理解。有效性取决于最新的二进制状态和对上下文环境的理解。20例例 无名联合直接定义局部共享的多个变量无名联合直接定义局部共享的多个变量n,m,x,y。#include void main(void)union int n;long m;double x;double y;printf(%p,%pt,&n,&y);n=3;printf(%d,%dt,n,m);x=6;printf(%f,%fn,x,y);/输出:输出:0065FDF0,0065FDF0 3,3 6.000000,6.00000021 例例 无名联合无名联合 static union point_t z;point3d b;定定义静态全局结构变量义静态全局结构变量b和和z#include typedef struct double v3;point_t;typedef struct double x,y,z;point3d;typedef union point_t z;point3d b;Ua;point3d*CrossProduct(point3d in1,point3d&a)const point3d in2=a;a.x=in1.y*in2.z-in1.z*in2.y;a.y=in1.z*in2.x-in1.x*in2.z;a.z=in1.x*in2.y-in1.y*in2.x;return&a;22static union point_t z;point3d b;extern point_t*q;const point3d x=1,1,0;point_t*q;void main(void)b.x=0;b.y=2;b.z=1;q=(point_t*)CrossProduct(x,b);if(b.x=z.v0&b.y=z.v1&b.z=z.v2)printf(b=%4.1f,%4.1f,%4.1ft,b.x,b.y,b.z);printf(q=%4.1f,%4.1f,%4.1ft,q-v0,q-v1,q-v2);Ua a=1,2,3;printf(a=%4.1f,%4.1f,%4.1fn,a.b.x,a.b.y,a.b.z);23/输出输出:b=1.0,-1.0,2.0 q=1.0,-1.0,2.0 a=1.0,2.0,3.0 上面的无名联合定义静态全局结构变量上面的无名联合定义静态全局结构变量b和和z,b和和z 是是同一片集合内存的两个别名,相应的结构成员也一对一的彼同一片集合内存的两个别名,相应的结构成员也一对一的彼此相配。此相配。两个结构本身描述的是空间点的坐标,只是成员名称两个结构本身描述的是空间点的坐标,只是成员名称不同不同;将这样的结构变量联合在一起达到内存数据充分共享将这样的结构变量联合在一起达到内存数据充分共享.静态的全局变量可以通过外部连接属性的全局指针在不静态的全局变量可以通过外部连接属性的全局指针在不同模块中传递信息。同模块中传递信息。联合可用于接口设计,两个课题组建立了相同的数据结联合可用于接口设计,两个课题组建立了相同的数据结构例如构例如:point_t和和point3d,只是其中的成员名称不同,可,只是其中的成员名称不同,可以将其联合在一起。以将其联合在一起。24b.结构范围中的无名联合结构范围中的无名联合 可以在结构的声明中引入无名联合,无名联合包含的数可以在结构的声明中引入无名联合,无名联合包含的数据成员在内存中共享一片内存空间,无名联合中单独的成员据成员在内存中共享一片内存空间,无名联合中单独的成员直接作为结构成员的相对独立部分。联合变量可以作为结构直接作为结构成员的相对独立部分。联合变量可以作为结构的成员,这相当于嵌入的对象,对于嵌入对象需要层层访的成员,这相当于嵌入的对象,对于嵌入对象需要层层访问。无名联合减少访问成员的层次,可以直接访问无名联合问。无名联合减少访问成员的层次,可以直接访问无名联合中的成员。联合提供一种课题组之间相同数据结构中的成员。联合提供一种课题组之间相同数据结构(即成员即成员个数、类型、次序相同只是名称不同个数、类型、次序相同只是名称不同)的接口技术。设课题的接口技术。设课题组组A和和B的结构类型为:的结构类型为:typedef struct person_a int n;float f;char*s;A;typedef struct person_b int number;float income;char*name;B;25 A结构和结构和B结构是一致的。并在相关的结构上相应地开结构是一致的。并在相关的结构上相应地开发一套算法。将这两个结构通过无名联合并置在一起,则可发一套算法。将这两个结构通过无名联合并置在一起,则可以发挥各自的特点。下面的例子说明无名联合的这一用法。以发挥各自的特点。下面的例子说明无名联合的这一用法。例例 结构范围中的无名联合实现不同课题组之间的数据接口结构范围中的无名联合实现不同课题组之间的数据接口#include#includetypedef struct a_t union int n;int number;union float f;float income;union char*s;char *name;A,B;26 int SeqFind(const B s,int n,float key)for(int i=0;in;i+)if(si.income=key)return i;return-1;int SeqFind(const A s,int n,const char*key)for(int i=0;in;i+)if(strcmp(si.s,key)=0)return i;return-1;27void InitData(B b,int n,float f,char(*s)20,int num=5)for(int i=0;inum;i+)bi.number=ni;bi.income=fi;bi.name=si;void show(B&r)printf(%d,%f,%st,r.number,r.income,r.name);void show(A*s,int n)for(A*p=s;pn,p-f,p-s);printf(n);28 const int N=5;static char caN20=Hisen,Boir,Rose,Bush,Kelin;void main()static int naN=11,22,33,44,55;float xaN=88,90,70,80,60;A sa N;InitData(sa,na,xa,ca,N);show(sa,N);int k=SeqFind(sa,N,Rose);if(k!=-1)show(sak);k=SeqFind(sa,N,60);if(k!=-1)show(sak);29/输出结果输出结果:11,88.0,Hisen,22,90.0,Boir,33,70.0,Rose,44,80.0,Bush,55,60.0,Kelin,33,70.000000,Rose55,60.000000,Kelin 联合可实现内存的共用与数据的共用,更可实现不同联合可实现内存的共用与数据的共用,更可实现不同类型数据互相排斥地占用同一内存或相同内存段互异数据的类型数据互相排斥地占用同一内存或相同内存段互异数据的不共用。不共用。union在一些介绍在一些介绍C语言的中文书中被译为共用体,这语言的中文书中被译为共用体,这多少有失多少有失union原有的丰富内涵。原有的丰富内涵。术语翻译应切近原意,而其确切含义则需详细解释。术语翻译应切近原意,而其确切含义则需详细解释。30十、数据的引用类型转换十、数据的引用类型转换 基本变量之间存在类型转换关系。基本变量之间存在类型转换关系。例如:例如:float f;long l=7788;f=(float)l;l=(long)f;表达式语句表达式语句f=(float)l;意味着将意味着将long型变量型变量l的值在相的值在相应的内存单元取出,经过类型转换模块,然后将结果送入应的内存单元取出,经过类型转换模块,然后将结果送入f变量表示的存储单元中,以浮点格式存储。变量表示的存储单元中,以浮点格式存储。对于同类型的结构变量或联合变量编译器允许赋值运对于同类型的结构变量或联合变量编译器允许赋值运算。算。31 设存在两个结构的声明为:设存在两个结构的声明为:struct sb sb结构数据成员列表;结构数据成员列表;;struct sa sa结构数据成员列表;结构数据成员列表;;定义结构变量定义结构变量a,a1,b,b1分别如下分别如下:struct sa a,a1;struct sb b,b1;a=a1;b=b1;赋值表达式语句赋值表达式语句a=a1表示结构变量表示结构变量a1的数据状态赋给的数据状态赋给对应的结构变量对应的结构变量a,相当于系统进行了函数调用:,相当于系统进行了函数调用:memcpy(&a,&a1,sizeof(a);32 但不同类型的结构变量的赋值如但不同类型的结构变量的赋值如 a=b1 则是不允许的。则是不允许的。因为编译器并未提供不同类型结构变量之间赋值的缺省因为编译器并未提供不同类型结构变量之间赋值的缺省运算。运算。同样对于类型转换:同样对于类型转换:a=(struct s)b1;系统也会提出错误警告。系统对于不同结构变量的数值系统也会提出错误警告。系统对于不同结构变量的数值转换无论是隐含的或显式都没有提供缺省的保证。但转换无论是隐含的或显式都没有提供缺省的保证。但C+允允许引用形式的类型转换。许引用形式的类型转换。引用形式类型转换的一般形式为:引用形式类型转换的一般形式为:(目标类型名目标类型名&)源变量源变量 (type&)variable引用类型转换的结果为左值。引用类型转换的结果为左值。33 对于两个结构变量对于两个结构变量a,b,一个具体的引用类型转换的语,一个具体的引用类型转换的语法格式如下:法格式如下:a=(struct sa&)b;(struct sa&)b=a;上面两个类型转换赋值表达式可分别理解为:上面两个类型转换赋值表达式可分别理解为:memcpy(&a,&b,sizeof(struct sa);memcpy(&b,&a,sizeof(struct sa);赋值拷贝映射的原则是将源数据内存的状态根据目标集赋值拷贝映射的原则是将源数据内存的状态根据目标集合的长度复制给目标所占用的内存。如果合的长度复制给目标所占用的内存。如果sizeof(sb)大于大于sizeof(sa),那么转换,那么转换 b=(sb&)a将导致对集合数据将导致对集合数据a的越的越界,反之如界,反之如a=(sa&)b则对长的源数据则对长的源数据b前面的前面的sizeof(sa)个个元素进行了复制。引用形式类型转换表示了集合数据间的直元素进行了复制。引用形式类型转换表示了集合数据间的直接映射,当然也可以对简单变量进行引用的类型转换。接映射,当然也可以对简单变量进行引用的类型转换。34例例 结构变量的类型转换与复制结构变量的类型转换与复制#include typedef struct sa int m;A;typedef struct sb int x;int y;B;void show(B&b)printf(b=%d,%dt,b.x,b.y);void main()A a=1;B b=3,4;(struct sa&)b=a;show(b);a.m=8;b=(B&)a;show(b);/程序输出:程序输出:b=1,4 b=8,668421635十一、位域或位字段十一、位域或位字段 位字段位字段(bit field)是特殊之至的数据结构,该结构将整是特殊之至的数据结构,该结构将整型变量占有的内存按位进行细分,细分的位数可以大小不型变量占有的内存按位进行细分,细分的位数可以大小不等,具体的等,具体的bit位置通过若干成员来索引,成员的数据类型通位置通过若干成员来索引,成员的数据类型通过过char,int,short,unsigned short,long等整型或梅举类界等整型或梅举类界定。定。其中其中b1,b2,bn表示成员,表示成员,count1,count2,countn表示表示相应成员占有的相应成员占有的bit位的个数。位的个数。36方括号包括的项表示可以省略,格式如下:方括号包括的项表示可以省略,格式如下:struct bit_t int b1:count1;int b2:count2;int:0;.int bn:countn;t;b2不在时表示无名位域,无名位域成员的位长度用于不在时表示无名位域,无名位域成员的位长度用于填充位域的特定位。填充位域的特定位。因其无名对应的因其无名对应的bit位不可索引。位不可索引。37具体地考虑一个具体地考虑一个bitDate的结构的结构:struct bitDate unsigned int year:9;unsigned int month:4;unsigned int day:5;unsigned int week:3;d;38 如上类型声明语句建立了奇怪的位域结构,结构名为如上类型声明语句建立了奇怪的位域结构,结构名为bitDate,同时定义该结构的实例,同时定义该结构的实例d。这个结构实例。这个结构实例d占有的占有的内存大小内存大小sizeof(d)=sizeof(bitDate)=4。一般地一般地sizeof(bit_t)并不简单是其中位域成员的位数之并不简单是其中位域成员的位数之和除和除8,而是同时满足每一单独的成员占有的位数连续地局,而是同时满足每一单独的成员占有的位数连续地局限于字节单元中。限于字节单元中。一般不将一个位域成员从一个字节单元的中间跨字节边一般不将一个位域成员从一个字节单元的中间跨字节边界分布。界分布。39 如下代码说明位域成员如何定位于字节的起始边界如下代码说明位域成员如何定位于字节的起始边界:struct c char a:8;char b:3;char e:5;char d:7;e;printf(%d,%dn,sizeof(c),sizeof(e);/输出输出3,3struct r char b:3;char a:8;char e:5;char d:7;s6;printf(%d,%dn,sizeof(r),sizeof(s);/输出输出4,2440 内存的寻址以字节为基本单元。内存的寻址以字节为基本单元。C/C+规定不取位域成员的长度也不取位域成员地址规定不取位域成员的长度也不取位域成员地址即即sizeof(d.year)和和&d.year是不允许的。是不允许的。成员名称成员名称year占有占有9个个bit位,其合理的取值范围为位,其合理的取值范围为0511。位域成员的性质类似于由其后位长度界定的整数,。位域成员的性质类似于由其后位长度界定的整数,保证位域成员不要超出其各自的范围,同其它整数一样可出保证位域成员不要超出其各自的范围,同其它整数一样可出现在算术表达式中,因此可以将现在算术表达式中,因此可以将 d.year等当作一个微小的整等当作一个微小的整数看待数看待,作为左值或右值。作为左值或右值。如如:d.year=52;d.month=11;d.week=3;d.day=18;int k=d.day;41 位域各成员的细节在字节单元上的分布取决于机器的具位域各成员的细节在字节单元上的分布取决于机器的具体实现,依赖于这些情况的程序是不可移植的。体实现,依赖于这些情况的程序是不可移植的。有的编译器位域成员的分布是从左往右,有的机器上则有的编译器位域成员的分布是从左往右,有的机器上则相反。微软对位域成员的排列顺序是从低到高如:相反。微软对位域成员的排列顺序是从低到高如:11 week:3 day:5 month:4 year:931 23 15 7 042
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 成人自考


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!