参考:结构体与共用体
作者:一只青木呀
发布时间: 2020-08-09 08:29:22
网址:https://blog.csdn.net/weixin_45309916/article/details/107889394
参考:联合体(union)的使用方法及其本质
作者:秦伟H
发布时间:2014-04-13 14:27:08
网址:https://blog.csdn.net/huqinweI987/article/details/23597091?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162847148716780366592652%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162847148716780366592652&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-3-23597091.first_rank_v2_pc_rank_v29&utm_term=%E8%81%94%E5%90%88%E4%BD%93&spm=1018.2226.3001.4187
目录
- 结构体
- 什么是结构体?
- 定义结构体
- 定义结构体变量:
- 匿名结构体:
- 实现给结构体取别名
- 结构体嵌套
- 联合体
- 概念
- 和struct的异同
- 共用内存地址
- union所占内存空间大小
结构体
什么是结构体?
用来存储不同类型的(数组存储的是同种类型数据)数据
定义结构体
struct 结构体名字{需要存储的类型或者数组};
例:
struct student{char name[20];int id;};
实际中,保存的数据一般不会是同一种类型。而结构体的大小也不是成员类型大小的简单相加。需要考虑到系统在存储结构体变量时的地址对齐问题。
由于存储变量地址对齐的问题,结构体大小计算必须满足两条原则:
一、结构体成员的偏移量必须是成员大小的整数倍
二、结构体大小必须是所有成员大小的整数倍
具体计算方法参照这篇博文:结构体对齐计算方式
定义结构体变量:
struct student stu1;这样就是定义一个结构体类型的变量,这样就能够使用这个结构体变量来存东西,其实就是给结构体里面的变量赋值,使用方式:stu1.id=12;直接‘ . ’出成员赋值即可。
定义结构体数组: struct student stu[10];这样就是定义一个结构体数组,这样就能狗使用这个结构体数组来存10个信息,使用方式:stu[0].id=12;跟上面一个直接 ’ . ’ 出成员赋值及即可。stu[0]就是表示第一个结构体变量
匿名结构体:
struct
{ int id;char b;
}p;
这样想当然定义了结构体变量,变量名是p,要写就变量就在后面接几个变量名
实现给结构体取别名
typedef struct{}Str;Str s; //可以直接定义结构体变量
结构体嵌套
struct Node{int a;int b;};struct Str{struct Node n;}//示例struct Str s;s.n.a=10;s.n.b=20;
联合体
概念
联合体又称共用体
union 名字{成员};
联合的所有成员引用的是内存中的相同位置,以最大的成员的内存长度作为union的内存大小。
定义:
union Node{char c;short s;int a;double d;};
联合体虽然可以有多个成员,但同一时间只能存放其中一种
和struct的异同
union,中文名“联合体、共用体”,在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量。
不过区别也挺明显:
-
结构体(struct)中所有变量是“共存”的——优点是“有容乃大”,全面;缺点是struct内存空间的分配是粗放的,不管用不用,全分配。
-
联合体(union)中是各变量是“互斥”的——缺点就是不够“包容”;但优点是内存使用更为精细灵活,也节省了内存空间。
共用内存地址
#include<stdio.h>
union var{long int l;int i;
};
int main(){union var v;v.l = 1;printf("v.l is %d\n",v.i);v.i = 2;printf("now v.l is %ld! the address is %p\n",v.l,&v.l);printf("now v.i is %d! the address is %p\n",v.i,&v.i);system("pause"); return 0;
}
所以,union叫共用体还真是贴切——完全就是共用一个内存首地址,并且各种变量名都可以同时使用,操作也是共同生效。如此多的access内存手段,确实好用,不过这些“手段”之间却没法互相屏蔽——就好像数组+下标和指针+偏移一样。
union所占内存空间大小
前面说了,首先,union的首地址是固定的,那么,union到底总共有多大?根据一些小常识,做个不严谨不高深的基础版验证吧。
根据:分配栈空间的时候内存地址基本上是连续的,至少同类型能保证在一起,连续就说明,我如果弄三个结构体出来,他们三个地址应该连着,看一下三个地址的间隔就知道了,也可以用sizeof直接看,就知道union的大小了。
#include<stdio.h>
union sizeTest{int a;double b;
};
main(){union sizeTest unionA;union sizeTest unionB;union sizeTest unionC;printf("the initial address of unionA is %p\n",&unionA);printf("the initial address of unionB is %p\n",&unionB);printf("the initial address of unionC is %p\n",&unionC);system("pause"); }
很容易看出,8,0,8,这间隔是8字节,按double走的。