7070|11

1999

帖子

24

TA的资源

五彩晶圆(高级)

楼主
 

struct与 union的基本用法 [复制链接]

在网上看到一片介绍结构体的很好的文章,转过来和大家分享,用好结构体有事会让程序更简洁有条理。

结构体与联合体是C语言的常见数据类型,可对C的基本数据类型进行组合使之能表示复杂的数据结构,意义深远,是优异代码的必备工具。

一.        struct与 union的基本用法,在语法上union与struct相同,因此只以struct为例
1.1        基本用法:
  1. struct AA{ int a; int b;}; //结构体的声明和定义
  2. struct AA s1; //变量的声明和定义 
  3. s1.a=3; //变量的使用:
复制代码
1.2        在声明结构体的同时定义变量:
  1. struct AA{int a; int b}s2={1, 2}; //此处AA为可选项,初始化部分为可选
  2. s2.a=5;                 //变量的使用
复制代码
1.3        使用 typedef 来简化struct的类型说明:
  1. typedef struct AA{int a; int b;}SAA; 
  2. SAA s3, s4;         //变量的声明和定义
  3. s3.a=8; //变量的使用
复制代码
1.4 使用时尤其注意后面的分号,必不可少;
二.        struct 与 union的区别
2.1 struct中的成员是按顺序依次排列,互相独立,在排列时引入了对齐问题(2.2);而union中的成员共用一块内存,起始地址都是相同的,即union中的成员是对同一地址的多个引用、对同一地址的多种表达方法。
2.2 struct的对齐问题
对齐问题即struct中每个成员起始地址的分配。为了可以快速访问到每个成员,(以EW430为例)编译器根据成员的类型放到合适的地址上,默认为2字节对齐。如:
Struct AA{char c; int d;}aa;
假设aa被分配在地址N上,并且N为偶数,则aa.c的地址为N,aa.d的地址为N+2,而N+1地址未使用被浪费了。
对齐字节大小的指定:通过#pragma pack(n)来指定对齐字节的大小,n为某些常量(EW430中可取1,2,4,8,16),指定以n字节对齐。通常使用编译器默认的对齐大小最为适宜。如果指定对齐大小为1字节对齐,以上面的结构体变量aa为例,aa.c地址为N,aa.d地址为N+1,是个奇数地址,因为430在奇数地址只能读取一个字节,因此要访问d成员需要读取两次才能完成,后果是代码变长、速度变慢。
三.        匿名结构体与联合体
匿名结构体和联合体,即没有名字的结构体或者联合体,这种结构体(或联合体)无法通过.与->操作符引用(因为它所属的结构体或联合体没有名字,无法应用),而像暴露在外面一样,与外层作用域相同,可直接使用。
3.1 C标准中提及的匿名结构体和联合体(草稿原文引用)(C标准中提及的匿名结构(联合)体应该只适用于有名结构体(联合)中的匿名结构(联合)体成员)
  1. struct v{
  2.         union{ //匿名联合体
  3.                 struct {int i, j;}; //匿名结构体
  4.                 struct {long k, l;}w;
  5.         };
  6.         int m;
  7. }v1;
  8. v1.i=2; //合法,匿名结构体的成员被直接使用
  9. v1.k=3;//非法,有名字的结构体需要引用他的名字,如下
  10. v1.w.k=5; //合法
复制代码
[ 本帖最后由 shower.xu 于 2012-6-14 21:30 编辑 ]

struct与union的基本用法.pdf

120.05 KB, 下载次数: 70

struct union的基本用法

最新回复

下载学习了  详情 回复 发表于 2012-6-16 18:10
 
点赞 关注

回复
举报

1999

帖子

24

TA的资源

五彩晶圆(高级)

沙发
 
3.2 IAR中的匿名结构体和联合体
IAR中的匿名结构体和联合体可以具有全局作用域,因此结构体或联合体中的成员可以作为全局变量使用,但却兼具结构体或者联合体的属性。
(1)        IO430.h系列头文件的寄存器声明方式:
如:
  1. __no_init volatile union
  2. {
  3.   unsigned short SFRIE1;   /* Interrupt Enable 1 */

  4.   struct
  5.   {
  6.     unsigned short WDTIE           : 1; /* WDT Interrupt Enable */
  7.     unsigned short OFIE            : 1; /* Osc Fault Enable */
  8.     unsigned short                : 1;
  9.     unsigned short VMAIE           : 1; /* Vacant Memory Interrupt Enable */
  10.     unsigned short NMIIE           : 1; /* NMI Interrupt Enable */
  11.     unsigned short ACCVIE          : 1; /* Flash Access Violation Interrupt Enable */
  12.     unsigned short JMBINIE         : 1; /* JTAG Mail Box input Interrupt Enable */
  13.     unsigned short JMBOUTIE        : 1; /* JTAG Mail Box output Interrupt Enable */
  14.   }SFRIE1_bit;
  15. } @0x0100;
复制代码
说明:[1].  SFRIE1和SFRIE1_bit具有全局变量的性质,可以直接被引用。
         [2].        SFRIE1和SFRIE1_bit在同一联合体中,根据联合体的性质,他们共享同一地址,即对同一寄存器不同访问方式,SFRIE1对整个寄存器操作,SFRIE1_bit可对某位操作,如:
SFRIE1 |= 0x0001;和SFRIE1_bit.WDTIE = 1;具有相同效果。
         [3].        冒号(:)与整数称之为位域,使用位域表达的变量使用同一数据中的不同位,并按顺序排列。整数表示这个变量占用多少位。没有名字的位域不能被引用到,一般用来保留未使用到的位(占位作用)。

 
 

回复

1999

帖子

24

TA的资源

五彩晶圆(高级)

板凳
 
(2)  在应用程序中也可以使用此特性来实现一些功能。
记得某位网友曾提出过这样的问题,要高效的使用一个整数的高8位和低8位,则可以用如下代码解决:
  1. union {
  2.         unsigned int num;
  3.         struct {
  4.                 unsigned char nLow;
  5.                 unsigned char nHigh;
  6.         };
  7. };
复制代码
或者
  1. union {
  2.         unsigned int num;
  3.         struct {
  4.                 unsigned int nLow        :8;
  5.                 unsigned int nHigh         :8;
  6.         };
  7. };
  8. int a = num;
  9. int b = nLow;
  10. int c = nHigh;
复制代码
非常好的解决方案,只占用一个整数的空间,可以对高8位、低8位、整个16位引用而不需要计算。
(3) 联合体中的位域(补充)
  1. union {
  2.         unsigned int z;
  3.         unsigned int z1 : 1;
  4.         unsigned int z2 : 2;
  5.         unsigned int z3 : 3;
  6.         unsigned int z4 : 4;
  7. };
  8. z = 0xFFFF;
  9. a = z1;
  10. b = z2;
  11. c = z3;
复制代码
结果:a = 1, b = 3, c = 7;

 
 
 

回复

1999

帖子

24

TA的资源

五彩晶圆(高级)

4
 
(4)结构体中的位域长度0 (补充)
  1. union ZZ{
  2.         unsigned int z1 : 1;
  3.         unsigned int z2 : 1;
  4.         unsigned int z3 : 1;
  5.         unsigned int z4 : 1;
  6.         unsigned int : 0;
  7.         unsigned int z6 : 1;
  8. }zz;
复制代码
长度为0的位域是通知编译器不要在以前的单元上分配位域了,代表着一个单元的位域分配结束,这个长度为0的位域不能有名字。以后的位域分配要新开辟一个单元。
以上的例子中,z1, z2, z3, z4共用一个unsigned int中的4个bit,z6单独使用一个unsigned int; 此结构体共占用两个unsigned int空间



发帖大小设置太少了啊,长点的文章都很难一次发完啊
[ 本帖最后由 shower.xu 于 2012-6-14 21:31 编辑 ]

点评

是不是直接从WORD里复制过来的? 如果直接从WORD里复制,WORD本身会带很多代码,占了字符空间的 一般可以再记事本上去一下格式。  详情 回复 发表于 2012-6-15 08:48
 
 
 

回复

7233

帖子

195

TA的资源

五彩晶圆(高级)

5
 
typedef struct 是好东西比较好用 以前没发现
 
 
 

回复

2万

帖子

71

TA的资源

管理员

6
 

回复 4楼 shower.xu 的帖子

是不是直接从WORD里复制过来的?

如果直接从WORD里复制,WORD本身会带很多代码,占了字符空间的

一般可以再记事本上去一下格式。
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

记事本的话表格样式会变,又要编辑一遍,嘿嘿:titter:  详情 回复 发表于 2012-6-15 09:03
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

1999

帖子

24

TA的资源

五彩晶圆(高级)

7
 
原帖由 soso 于 2012-6-15 08:48 发表 是不是直接从WORD里复制过来的? 如果直接从WORD里复制,WORD本身会带很多代码,占了字符空间的 一般可以再记事本上去一下格式。

记事本的话表格样式会变,又要编辑一遍,嘿嘿

点评

调整了:)  详情 回复 发表于 2012-6-15 13:26
呵呵 哎 网页代码和WORD代码不兼容所致,我问问技术吧。  详情 回复 发表于 2012-6-15 09:18
 
 
 

回复

2万

帖子

71

TA的资源

管理员

8
 

回复 7楼 shower.xu 的帖子

呵呵 哎 网页代码和WORD代码不兼容所致,我问问技术吧。
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

2万

帖子

71

TA的资源

管理员

9
 

回复 7楼 shower.xu 的帖子

调整了:)
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

反应迅速,谢谢:Laugh:  详情 回复 发表于 2012-6-15 14:50
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

2452

帖子

19

TA的资源

五彩晶圆(中级)

10
 
很好的文章,收藏了
 
 
 

回复

1999

帖子

24

TA的资源

五彩晶圆(高级)

11
 
原帖由 soso 于 2012-6-15 13:26 发表 调整了:)

反应迅速,谢谢
 
 
 

回复

471

帖子

0

TA的资源

一粒金砂(高级)

12
 
下载学习了
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
艾睿电子& Silicon Labs 有奖直播 | 全新蓝牙信道探测:从技术创新到实际应用
直播时间:3月12日(周三)上午10:00
直播奖励:多功能榨汁机、蓝牙音箱、手机支架

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表