当前位置:网站首页>【学习笔记之菜Dog学C】自定义类型详解(结构体+枚举+联合)
【学习笔记之菜Dog学C】自定义类型详解(结构体+枚举+联合)
2022-08-02 14:39:00 【姜君竹】
一、结构体
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
- 结构体声明
结构体在声明是可以不完全声明。
struct Book {
char name[20];
int price;
char id[12];
}b4,b5,b6;//b4,b5,b6是全局的
//不完全声明,匿名结构体类型
struct {
char c;
int i;
char ch;
double d;
} s;
int main() {
//b1,b2,b3是局部的
struct Book b1;
struct Book b2;
struct Book b3;
return 0;
}
- 结构体自引用
结构体自引用,结构体可以包含结构体。
struct Node {
int d;
struct Node* next;
};
int main() {
struct Node n;
return 0;
}
- 结构体内存对齐
3.1 第一个成员在与结构体偏移量为0的地址处存放
;
3.2 其他成员变量都放在某一个对齐数的整数倍
的地址处;
对齐数是编译器默认的对齐数
与该成员字节的大小
中较小的那一个,vs中默认的值为8;
3.3 结构体总大小为最大对齐数
( 每个成员变量都有一个对齐数)的整数倍;
3.4 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处
,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
struct S {
char c;
int i;
};
struct B {
double d;
struct S s;
char c;
};
int main() {
printf("%d\n", sizeof(struct S));
printf("%d\n", sizeof(struct B));
struct S s1 = {
'x', 20};
struct B sb = {
3.14, {
'x', 20}, 'q' };
//.针对结构体变量
//->针对结构体指针
printf("%lf %c %d %c\n",sb.d, sb.s.c, sb.s.i, sb.c);
return 0;
}
- 为什么存在对齐数
4.1 平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
4.2性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐;
原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。结构体的内存对齐是拿空间来换取时间的做法。
- 设置默认对齐数
#pragma pack(2)
struct S {
char c1;
int i;
char c2;
};
#pragma pack()
int main() {
struct S s = {
0 };
printf("%d\n", sizeof(s));
return 0;
}
- 结构体传参
函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销;
如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降;
结构体传参的时候,要传结构体的地址。
struct S {
int data[1000];
int num;
};
struct S s = {
{
1,2,3,4}, 1000};
//结构体传参
void print1(struct S s) {
printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps) {
printf("%d\n", ps->num);
}
int main(){
print1(s); //传结构体
print2(&s); //传地址
return 0;
}
二、位段
- 位段声明
1.1位段的成员必须是 int、unsigned int 或signed int;
1.2位段的成员名后边有一个冒号和一个数字。 - 位段的内存分配
2.1位段的成员可以是int、unsigned int、signed int或者是char(属于整形家族)类型;
2.1位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的;
2.3位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。 - 跨平台问题
3.1int位段被当成有符号数还是无符号数是不确定的;
3.2位段中最大位的数目不能确定(16位机器最大16,32位机器最大32,写成27,在16位机
器会出问题);
3.3位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义;
3.4当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是
舍弃剩余的位还是利用,这是不确定的。
struct A {
// 4字节 - 32bit
int _a : 2;// _a成员占2个bit位
int _b : 5;// _b成员占5个bit位
int _c : 10;// _c成员占10个bit位
//15
// 4个字节 - 32bit
int _d : 30;// _d成员占30个bit位
};
int main() {
printf("%d\n", sizeof(struct A));
return 0;
}
三、枚举
枚举就是把可能的取值一一列举。
{}
中的内容是枚举类型的可能取值,也叫枚举常量
;
这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。
enum Color {
RED,//0
CREEN,//1
BLUE//2
};
int main() {
enum Color c = BLUE;
printf("%d\n", sizeof(c));
printf("%d\n", RED);
printf("%d\n", CREEN);
printf("%d\n", BLUE);
return 0;
}
为什么使用枚举:
1.增加代码的可读性和可维护性;
2.和#define定义的标识符比较枚举有类型检查,更加严谨;
3.防止了命名污染(封装);
4.便于调试;
5.使用方便,一次可以定义多个常量。
四、联合(共用体)
联合也是一种特殊的自定义类型;
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间,所以联合也叫共用体;
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小,因为联合至少得有能力保存最大的那个成员;
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
int check_sys() {
union U {
char c;
int i;
}u;
u.i = 1;
return u.c;
}
int main() {
int ret = check_sys();
if (1 == ret)
printf("小端\n");
else
printf("大端\n");
return 0;
}
union Un1 {
char c[5];
int i;
};
union Un2 {
short c[7];
int i;
};
//下面输出的结果是什么?
printf("%d\n", sizeof(union Un1));
printf("%d\n", sizeof(union Un2));
边栏推荐
猜你喜欢
如何正确且快速的清楚C盘!!释放C盘空间内存保姆级教程
es6 循环,并终止循环
解决(An error happened during template parsing (template: “class path resource [templates/...]
双亲委派机制
ShardingSphere基本介绍及核心概念
“绿色低碳+数字孪生“双轮驱动,解码油气管道站升级难点 | 图扑软件
CNN flower classification
- [email protected]设计"/>
NXP i.MX 8M Mini工业核心板B2B版本,4核ARM [email protected]设计
Servlet运行原理_API详解_请求响应构造进阶之路(Servlet_2)
第五章-5.2-指示器随机变量
随机推荐
Redis的5中数据类型总结
PAT Class A 1130 Infix Expressions
MySQL 的几种碎片整理方案总结(解决delete大量数据后空间不释放的问题)
Application software code signing certificate
Reading is the cheapest and noblest
如何正确且快速的清楚C盘!!释放C盘空间内存保姆级教程
《数字经济全景白皮书》银行业智能风控科技应用专题分析 发布
中国服装行业已形成一套完整的产业体系
什么是Nacos?
Redis最新6.27安装配置笔记及安装和常用命令快速上手复习指南
如何使用Swiper外部插件写一个轮播图
PAT Class A 1019 Common Palindrome Numbers
页面返回顶部和固定导航栏js基础案例
开篇-开启全新的.NET现代应用开发体验
2022-07-28 第六小组 瞒春 学习笔记
PAT Grade A 1143 Lowest Common Ancestor
Servlet运行原理_API详解_请求响应构造进阶之路(Servlet_2)
李开复花上千万投的缝纫机器人,团队出自大疆
公司最大的内卷,是“管理错位”
Drag and Drop in H5