C++结构体、联合体、枚举体及其内存

C++结构体、联合体、枚举体及其内存

结构体:是一种特殊形态的类
结构体与类的区别:结构体与类具有不同的默认访问控制属性:
在类中,对于未指定访问控制属性的成员,其访问控制属性为私有类型;在结构体中,对于未指定任何访问控制属性的成员,其访问控制属性为公有型。
关键字:struct
定义:

Struct 结构体名称
{
	公有成员;
 Protected:
	保护型成员
Private:
私有成员
};

什么时候用结构体而不用类:
1:主要用来保存数据,而没有什么操作的类型
2:人们习惯将结构体的数据成员设置为公有,因此这时用结构体比较方便
如果:
1:一个结构体的全部数据成员都是公共成员;
2:没有用户定义的构造函数;
3:没有基类和虚函数;
那么这个结构体可以通过下列方式初始化:
类型名 变量名 = { 成员数据1初值, 成员数据2初值, …… };
例如:

struct student
{
	char name[20];//姓名
	int num;//学号
	int age;//年龄
	float score;//分数
};
student wh={"wh",1529401160,20,98.0};

其中student为结构体的类型名;wh为结构体变量名
结构体的内存大小:
以字节最大的单位 为地址对齐标准,如 结构体中 最大为 double,8个字节,那么 比它小的单位就要凑齐 8的整数倍字节大小。
例如:

struct test1
{
	char w;
	int s;
	double q;
}m;

char 1字节,int 4字节, double 8字节,所以以8字节对齐,总字节大小为8的倍数
8+4+1=13,而8字节对齐后,为16。

再例如:

struct test2
{
	char w[5];
	int s[2];
	double q;
}n;

w[5]:5字节,s[2]:8字节,q:8字节
5+8+8=21,对齐8字节后为24

struct test3
{
double r;
char k[9];
}s;
s 的大小为24
typedef union {
    Short i;
    int k[5];
    char c;
} Mat;
Typedef struct {
    int i;
    Mat j;
    double k;
}Like;
则语句 printf("%d",sizeof(Like)+sizeof(Mat));的执行结果是:52

联合体
联合体的全部数据成员共享一组内存单元,任何两个成员不会同时有效
关键字:union
定义:

union 联合体名称
{
	公有成员;
 Protected:
	保护型成员
Private:
私有成员
};

定义变量方法:在定义union联合体名称之后如:

union mark
{
	char grade;
	bool pass;
	int percent;
}wh;

或者先定义联合体类型,再定义变量:

union mark
{
	char grade;
	bool pass;
	int percent;
};
mark wh;

初始化方法:wh.grade=’A’;或wh.pass=Ture;或者wh.percent=90;
存储方式:共享一组内存单元,每一项元素起始地址都一样,都跟联合体 union 的地址偏移量为0

例如:union mark
{
	char grade;
	bool pass;
	int percent;
};

存储方式:

markgradepasspercent
****
**
**
**

存储空间:4字节
联合体的内存计算:此结构的容量要容纳最大的一个元素,而且要字节对齐其他元素的大小
例如:

union U
{
    char s[9];             //9个字节
    int n; //4个字节
    double d; //8个字节
};

union U中最大的是 9 个字节的 s[9],但 9 不能被 4 和 8 同时整除,而16可以,且16比9大。
所以 联合体所占空间 为16 个字节

union C{  
int i;  
char x[2];  
}a;  

int main(void)  
{  
a.x[0] = 10;  
a.x[1] = 1;  
printf("%d\n",a.i);  
return 0;  
}  

由于 PC 机位小端序,因此 低字节放低地址,同时a是全局变量存储在静态存储区,默认初始为0,对 x[2]赋值后,union C的地址空间的值为:
高地址0000 0000|0000 0000|0000 0001| 0000 1010 低地址(4个字节的存储空间)
所以输出 1×2的八次方+1×2的三次方+1×2 = 266;

如是在函数体内定义变量则其内存的值是不确定的需要先将其清0

union u{  
int i;  
char x[2];  
};  

int main(void)  
{ 
union u a;
memset(&a,0,sizeof(a));      //这步很关键,否则 union 的起始内存地址不会全是0,而是不确定会造成无法预测 union u a 中 元素的值
a.x[0] = 10;  
a.x[1] = 1;  
printf("%d\n",a.i);  
return 0;  
}  

枚举体
定义方法:
enum class 枚举类型名: 底层类型 {枚举值列表};
enum class Typename1 {General, Light, Medium, Heavy};
(不定义底层类型默认int,里面的值分别对应0,1,2,3)
enum class Typename2: char{General, Light, Medium, Heavy};
enum class Typename3 {General=4, Pistol, MachineGun, Cannon};(里面的值分别对应4,5,6,7)
特点:
强作用域,其作用域限制在枚举类中
转换限制,枚举类对象不可以与整型隐式地互相转换
可以指定底层类型
详解见:https://www.runoob.com/w3cnote/cpp-enum-intro.html

参考文章:https://blog.csdn.net/Jaihk662/article/details/79706768
https://blog.csdn.net/u014453898/article/details/53705448

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值