本篇文章为大家展示了怎么在C语言中自定义类型,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
下面举一个例子:
struct tag { menber_list; //成员列表 }variable_list; //变量列表
例如我们使用结构体描述一台电脑
struct computer { int price;//价格 char name[20];//名称 char brand[10];//品牌 }computer; //需要注意的是最后一行的“ ;”不能丢哦,不然编译器会报错提示你。
结构成员的类型
结构成员可以是标量数组、指针、甚至可以是其他的结构体。
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
匿名结构体类型
//匿名结构体类型 struct { int a; char b; float c; }x; struct { int a; char b; float c; }a[20], *p;
上面的代码中结构体省略掉了结构体标签,我们在添加一行代码
p=&x;
当我们编译时,会发现这样两个错误。
所以这样是不可行的。
结构体的自引用
就像函数递归一样,结构体也可以自己引用自己。他们的格式是这样的。
struct Node { int data; struct Node* next; };
结构体变量的定义和初始化
struct stu { char name[20]; int age; }; struct stu s = { "Geralt ",100};
利维亚的杰洛特,100岁!
结构体内存对齐
各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数 各成员变量在存放的时候根据在结构中出现的顺序依次申请空间 同时按照上面的对齐方式调整位置 空缺的字节自动填充 同时为了确保结构的大小为结构的字节边界数(即该结构中占用最大的空间的类型的字节数)的倍数,所以在为最后一个成员变量申请空间后 还会根据需要自动填充空缺的字节。
简单的说就是:结构体的内存对齐是拿空间来换取时间的结果,提高了效率,浪费少许空间。
规则如下:
第一个成员在与结构体变量偏移量为0的地址处。
其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
VS编译器中默认对齐数是8。
当然了,作为创建VS,Linux的我们是可以在C语言中自定义对齐数的。
我们可以使用#pragma这个预处理指令修改默认对齐数。
Eg:#pragma pack(4) //修改对齐数为4
结构体传参
struct s { int data[1000]; int num; }; struct s s = { {1,2,3,4},100 }; //结构体传参 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.位段的成员必须是 int、unsigned int 或signed int 。2.位段的成员名后边有一个冒号和一个数字。
举一个例子:
struct A { int _a:2; int _b:5; int _c:10; int _d:30; };
位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
举一个例子
struct S { char a:3; char b:4; char c:5; char d:4; }; struct S s = {0}; s.a = 10; s.b = 12; s.c = 3; s.d = 4;
那么位段的空间是如何开辟的呢?一张图搞定!
总的来说,位段和结构体相似,可以更好的节省空间,但是位段有跨平台的问题存在。
枚举枚举,顾名思义就是把可能出现的取值一一列举出来。
比如我们要描述一年的月份:
可以一一列举,我们要描述计算机语言的类型,也可以一一列举。
下面举一个例子
代码如下(示例):
enum ComputerLangue { C, Java, Python, };
每种结构体都有一定的优点,那么枚举有什么优点呢?
增加代码的可读性和可维护性
和#define定义的标识符比较枚举有类型检查,更加严谨。
防止了命名污染(封装)
便于调试
使用方便,一次可以定义多个常量
联合(公用体)
联合的特点是成员们公用同一块空间,因此他们也可以叫共用体
代码如下(示例):
//联合类型的声明
union Un { char c; int i; };
//联合变量的定义 union Un un; //计算连个变量的大小 printf("%d\n", sizeof(un));
在VC2013这款编译器中,这个结构体所占的空间大小是多少字节?
typedef struct{ int a; char b; short c; short d; }AA_t;
答案是:12个字节
为什么呢?结构体判断大小,一般向成员中最长的元素对齐。
在这4个结构成员中,最长的元素为a占四个字节。所以其他元素要向四对齐。a单独占四个字节,b为char类型占一个字节,c为short和b一起占四个字节并且空出一个字节。剩下d占一个字节,空两个字节。所以总占空间大小是4+1+2+2+3=12字节。
struct A { int a; short b; int c; char d; }; struct B { int a; short b; char c; int d; };
我们在来看一道题 :在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是( )
答案是:16、12
最长的结构成员为int 占4个字节,b占两个字节,空下两个字节,c占4个字节,d占一个字节,空3个字节。
最长的类型为int,a占4字节,b和c一起占三个字节,还空下一个字节,d占4字节。
所以sizeof(A)sizeof(B)分别是16 12.
上述内容就是怎么在C语言中自定义类型,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。