千家信息网

C语言中如何自定义类型

发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,这篇文章主要介绍了C语言中如何自定义类型,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、结构体1.结构体变量的定义及初始化直接上代码
千家信息网最后更新 2025年01月18日C语言中如何自定义类型

这篇文章主要介绍了C语言中如何自定义类型,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

一、结构体

1.结构体变量的定义及初始化

直接上代码:

struct Point {        int x;        int y;}p1;     //创建结构体时顺便创建变量,分号一定不能掉struct Point p2;    //单独创建变量struct Point p3 = { 1,2 };   //创建变量时顺便赋值struct Node {        char str[20];        struct Point p;     //结构体嵌套}n1 = { "abcd",{3,4} };int main() {        printf("%s\n", n1.str);   //结构体访问时,用.或者->,变量访问用.,指针访问用->        printf("%d\n", n1.p.x);        printf("%d\n", n1.p.y);        return 0;}

struct是创建结构体的关键字,Point是结构体的名字,p1为结构体Point的一个变量,x,y称为结构体Point中的成员变量,变量的创建有两种形式,第一,可以在创建结构体时一起创建,第二,单独创建,创建规则为类型+名称,对于结构体的赋值,可以在创建变量的时候顺便赋值,可以先创建变量再单独赋值。结构体的访问有两种方式,当使用变量进行访问时,用.(点),再选择该变量对应的属性;当使用指针进行访问时,用->,再选择对应的属性即可。

2.结构体内存对齐

当我们想去计算结构体占内存大小的时候,就需要知道结构图内存对齐这一概念,我们先来看两个例子:

struct A {        char a;        char b;        int c;};struct B {        char a;        int c;        char b;};int main(){        printf("%d\n", sizeof(struct A));        printf("%d\n", sizeof(struct B));        return 0;}

结果表明,A和B两个结构体所占内存大小并不相等,但是其内部成员变量是一样的,只是顺序不一样。造成结果不同的原因就是因为内存对齐,我们来介绍结构体内存对齐的规则:

1.第一个成员在与结构体变量偏移量为0的地址处。

其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。在VS编译器中,默认对齐数是8。

结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

3.为什么要内存对齐呢?

从上面的结果我们大概就能猜到,为了节省空间。总的来说,主要原因有两点:

1.平台原因:

某些硬件平台只能在特定的地址处取地址,没有内存对齐,取值时可能会出错。

2.性能原因:

对于不对齐的情况,在读取数据时可能要读取两次,以下图为例:

在一个32位平台上,在不对齐的情况下,如果想要读取int的4个字节,第一次会读取到char的一个字节,和int的后3个字节(小端),需要再读取一次,才能将int的4个字节完全读取出来;相比较而言,如果是在内存对齐的情况下,只需要读取一次就可以把int的4个直接读取出来。

二、位段

结构体还有实现位段的能力,问题来了,什么是位段呢?

1.什么是位段

位段的声明和结构体是类似的,但有两点不同:

  • 位段的成员必须是 int、unsigned int 或signed int 。

  • 位段的成员名后边有一个冒号和一个数字。

例如:

struct A{ int _a:2; int _b:5; int _c:3; int _d:4;};

A就是一个位段类型,想要知道A的大小,同样可以用sizeof来求。

2.位段的内存分配

拿上面的位段A来说,会先在内存中开辟一个4字节的空间,冒号后面的数字表示该成员变量所占内存的大小,单位为bit,位段中的成员在内存中从左向右分配, 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是 舍弃剩余的位还是利用,这是不确定的。总的来说,跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。光说不太好理解,我们来看下图:

当然,位段虽然比结构体更节省内存,但其存在跨平台问题,需要谨慎使用。

三、枚举

1.枚举的定义

enum Day//星期{ Mon,  //默认情况下Mon值为0,后面的成员变量的值依次递增 Tues, Wed, Thur, Fri, Sat, Sun};

当然也可以在定义的时候赋值,例如:

enum Color//颜色{ RED=1, GREEN=2, BLUE=4};

2.枚举的优点

我们知道,#define可以定义常量,那为什么要用枚举呢?

枚举的优点:

1.增加代码的可读性和可维护性

2.和#define定义的标识符比较枚举有类型检查,更加严谨。

3.使用方便,一次可以定义多个常量

既然存在,就有其存在的道理,有些时候#define更方便,有时候枚举更方便,我们要学会合理使用

四、联合(共用体)

1.联合类型的定义

union Un  //声明{ char c; int i;};union Un un;  //定义变量printf("%d\n", sizeof(un));  //计算共用体的大小

2.联合的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为 联合至少得有能力保存最大的那个成员)。

union Un{ int i; char c;};union Un un;// 下面输出的结果是一样的吗?printf("%d\n", &(un.i));printf("%d\n", &(un.c));//下面输出的结果是什么?un.i = 0x11223344;un.c = 0x55;printf("%x\n", un.i);

从结果可以看出,i和c的地址是一样的,因为他们共用一块空间,当分别给i、c赋值时,后赋值的c会覆盖之前i的部分值。

3.联合大小的计算

  • 联合的大小至少是最大成员的大小。

  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

例如:

union Un1{ char c[5]; int i;};union Un2{ short c[7]; int i;};//下面输出的结果是什么?printf("%d\n", sizeof(union Un1));  //8,c占5个字节,比i大,最大对齐数位4,需要为4的倍数,所以为8printf("%d\n", sizeof(union Un2));  //16,c占14个字节,最大对齐数为4,所以为16

感谢你能够认真阅读完这篇文章,希望小编分享的"C语言中如何自定义类型"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

结构 变量 成员 内存 大小 最大 联合 字节 结果 类型 整数 地址 情况 时候 空间 原因 篇文章 两个 就是 平台 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发项目简介范文 阿里云物联网 数据库 魔兽世界不同服务器可以邮寄 网络安全什么书比较好 资兴民宿软件开发 广东好的软件开发口碑推荐 服务器登录只有cmd 易语言数据库可以存多少条数据 四川数据软件开发服务参考价格 2008r2文件服务器 佛山网络技术实验室 软件开发可以进微软吗 易语言数据库导入超级列表框 短信提醒网络安全 京东软件开发测试论文 内蒙古蒙泰互联网科技 廊坊软件开发销售电话 xml与数据库结合 海南盐步软件开发培训学校周期 贵州品质软件开发价钱 spring注解导入数据库类 如何判断小程序与数据库的连接 网页怎么保存文件到服务器 深圳市大晟软件开发公司 严格按照规范设计数据库表 网络安全风险评估的形式 我省网络安全应急演习 该服务器安全证书未生效怎么办 为什么魔方的服务器那么垃圾 如何配置iis服务器
0