1.共用体和结构体的相同和不同
(1)相同点就是操作语法几乎相同。
(2)不同点是本质上的不同。struct是多个独立元素(内存空间)打包在一起;union是一个元素(内存空间)的多种不同解析方式。
#include<stdio.h> //对同一地址数据的不同解析方法 union myunion { int a; int b; //char b; }; struct mystruct { int a; char b; }; int main(void) { union myunion u1; struct mystruct s1; u1.a=2; s1.a=2; printf("u1.a_add=%p\nu1.b_add=%p\n",&(u1.a),&(u1.b)); printf("u1.b=%d\n",u1.b); printf("s1.b=%d\n",s1.b); return 0; }
输出:
u1.a_add=0xbfb4e190 u1.b_add=0xbfb4e190 u1.b=2 s1.b=92
(3).用指针方式描述共用体
union myunion { int a; char b; }; u1.a=1; u1.b=1; int a=1; char b=*((char*)(&a));//用char型访问a
2.大小端
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
大部分情况下为小端模式,(C51为大端)。
3.用代码查看大小端模式
#include<stdio.h> union myunion { int a; char b; }; void is_little_endian(void) { union myunion u1; u1.a=1; if(u1.b==1){ printf("小端模式\n"); }else{ printf("大端模式\n"); } } void is_little_endian2(void) //union 的本质 { int a=1; char b=*((char*)(&a)); if(b==1){ printf("小端模式\n"); }else{ printf("大端模式\n"); } } int main() { is_little_endian(); is_little_endian2(); return 0; }
对同一地址里的值用不同方式解析。
大端模式下,高位对应低地址。红框代表char型解析数据为0;
小端模式下,低位对应低地址。红框代表char型解析数据为1;
![](https://i-blog.csdnimg.cn/blog_migrate/1673417adb98b26a3cfc9f0c90874a1a.png)
4.枚举
宏定义和枚举的区别
(1)枚举是将多个有关联的符号封装在一个枚举中,而宏定义是完全散的。也就是说枚举其实是多选一。
(2)什么情况下用枚举?当我们要定义的常量是一个有限集合时(譬如一星期有7天,譬如一个月有31天,譬如一年有12个月····),最适合用枚举。(其实宏定义也行,但是枚举更好)
(3)不能用枚举的情况下(定义的常量符号之间无关联,或者无限的)用宏定义。
总结:宏定义先出现,用来解决符号常量的问题;后来人们发现有时候定义的符号常量彼此之间有关联(多选一的关系),用宏定义来做虽然可以但是不贴切,于是乎发明了枚举来解决这种情况。
#include<stdio.h> enum week { Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday, }; int main(void) { enum week Today; Today=Monday; switch(Today) { case Monday: printf("周一 \n"); case Tuesday: printf("周二\n"); case Wednesday: printf("周三 \n"); case Thursday: printf("周四 \n"); case Friday: printf("周五 \n"); case Saturday: printf("周六 \n"); case Sunday: printf("周天 \n"); } return 0; }