当前位置: 首页 > news >正文

构造数据类型

构造数据类型

一、结构体

1.定义

把多个数据类型(包含基本数据类型和构造数据类型),组合在一起,描述一个相对复杂的事物(个体)

2.定义结构体

结构体的声明: struct 结构体名 { 具体的属性值1; 具体的属性值2; 具体的属性值3; 具体的属性值4; 具体的属性值5; }; // 分号不可省略 // 只是声明,不开辟内存空间。 struct Date { int year; int mon; int day; }; struct Person { char name[50]; int age; int heigh; char phone[20]; struct Date date; };

3.定义结构体变量

//struct 结构体名 变量名; //开辟内存空间 struct Person per2; struct Person *point= &per2;

4.结构体成员的访问

(1)运算符
. 双目运算符 ,从左到右 1级优先级
-> 双目运算符 ,从左到右 1级优先级
何时使用 . 或 -> , 取决于运算符的的左操作数。左操作数是变量,使用. 。如果是指针,使
用->

(2)访问成员
访问成员的时候,如果是通过变量访问 , 使用. 运算符
访问成员的时候,如果是通过指针访问 , 使用->运算符
per2 是变量的情况
per2.name:表达式的类型是 name 的数据类型 。当使用访问运算符访问后,表达式的类型 ,由右操作数决定
per2 是指针的情况
per2->name:表达式的类型是name 的数据类型 。当使用访问运算符访问后,表达式的类型 ,由右操作数决定

5.结构体的大小

字节对齐问题: 默认 4字节对齐
当结构体声明好, 系统会对结构内存空间布局进行调整。提高cpu 读写内存的效率。
(1)需要存储变量的地址值,和该类型的大小 ,进行求余操作。如果余数为0 。则该变量储存在这个地址。如果不是,地址加1后,继续求余。
(2)找到结构体中,占用空间最大的成员(基本数据类型的成员, 4byte/8byte) 。 最终结构体的大小是4的倍数或8的倍数。

例如:

struct Person { char name[50]; //50 int age; //4 float heigh; //4 char phone[20]; //20 };

经过字节对齐后结构体大小为:80byte

6.结构体传参

(1)值传递

void fun(struct Person per){} //对结构体的数据成员操作 ,只能进行读取操作
劣势: 由于是值传递,所以在被调函数中,需要对实参进行整体复制。 函数调用完毕后,形参空间需要释放。如果结构体占用内存空间很多的话。效率就很低

(2)地址传递

void fill_per(struct Person* p){}

地址传递 ,内存使用效率高。 因为任意指针都是8个字节。在被调函数中,如果只需要读取数据的话,加const 修饰指针就可以了。 如果需要读写的话,去掉const再进行修改。

二、结构体数组

1.定义

struct 结构体名 数组名[整形常量];
strcut Person array[10];

2.初始化

//全部清 0 struct Person array[5]={0}; // 全部初始化 struct Person array2[3]={ {"zhangsan",10,{2026,05,10}}, {"lisi",11,{2025,03,12}}, {"wangmaizi",12,{2024,01,22}}, }; // gcc 支持的初始化方式 struct Person array3[3]= { [1]={"zhangsan",20,{2021,10,1}}, };

3.访问

void show_pers(const struct Person arrar[],int size) { int i = 0 ; for(i=0;i<size;i++) { show_per(&arrar[i]); //下标方式访问 } } int main(int argc, char **argv) { //全部清 0 struct Person array[5]={0}; // 全部初始化 struct Person array2[3]={ {"zhangsan",10,{2026,05,10}}, {"lisi",11,{2025,03,12}}, {"wangmaizi",12,{2024,01,22}}, }; / printf("array3 name:%s y:%d m:%d d:%d\n",array3[1].name,array[1].date.year,array[1].date.mon ,array[1].date.day); ////下标方式访问 show_pers(array2,3); return 0; }

4.typedef 和struct

struct Person { char name[50]; int id; }; typedef unsigned char u8; typedef int* (*PFUN)(int, int); //函数指针类型 typedef struct Person1 { char name[50]; int id; } PER; // PER == struct Person1 int main(int argc, char** argv) { struct Person per = {0}; PER per2 = {"zhangsan", 20}; struct Person1 per3 = {"lisi", 10}; printf("name:%s id:%d\n", per2.name, per2.id); return 0; }

三、共用体(联合体)

1.定义

定义共用体,也叫联合体。
和结构体的定义,初始化,访问元素,都一样的。
只有一处差异,开辟内存空间有差异。

  • 在结构体中,每个成员都是要开辟内存空间的,字节对齐问题。
  • 共用体中, 开辟空间的大小是,最大成员的大小。所有的成员共享一份内存。

2.应用

  1. 需要节省内存空间的情况 (如果可以使用结构体,或联合体)
  2. 作为函数参数传递的时候,如果参数本身有多个选项的时候,所有的选项,以联合体形式给出(多选1)。
  3. 可以判断大小端

3.语法定义

union 共用体类型名 { 数据成员1; 数据成员2; 数据成员3; ... }; // 分号不可省

4.初始化和访问

union TestAAA { int a; char b; long d; }; int main(int argc, char **argv) { //清零 union TestAAA test={0}; //访问 test.a =300; printf("a is %d\n",test.a); printf("b is %d\n",test.b); printf("b is %ld\n",test.d); test.d =123132300; // 会覆盖原来 test.a 中值 ,内存只有一份。 return 0; }

5.大小端判断

//大小端判断 union End { int ia; char cc; }; int main(int argc, char **argv) { union End end = {0}; end.ia = 1; printf("union size is %lu\n",sizeof(union End )); if (1 == end.cc) { printf("小端\n"); } else { printf("大端\n"); } return 0; }

四、枚举

1.定义

定义一个自定义的变量,把变量可以取到所有的值,一一列举出(或者说一个取值的范围)来。
枚举值,在c语言中当 整形(int)常量数据看

2.声明

enum 枚举类型名 {枚举值1,枚举值2,枚举值3,枚举值4.....} 枚举值 默认从0 开始,后面的只都是依次+1 // MON = 0 1 2 3 4 5 6 enum WEEK {MON,TUE,WED,THU,FRI,SAT,SUN}; 枚举值 ,用户可以指定初值。 //3 4 5 6 7 8 9 enum WEEK1 {MON1=3,TUE1,WED1,THU1,FRI1,SAT

3.定义变量

enum WEEK week= THU; // week =1000; 枚举这个类型,c语言中 当整形变量对待。不建议这么写。 switch(week) { case MON: printf("go to school\n"); break; case FRI: printf("to play...\n"); break; case SUN: printf("go to sleep\n"); break; default: printf("发呆\n"); }
http://www.jsqmd.com/news/881434/

相关文章:

  • AODV协议智能增强:多模型机器学习提升蓝牙Mesh网络路由可靠性
  • Rockchip Debian编译卡在QEMU?别慌,可能是Ubuntu 18.04的锅(附升级20.04避坑指南)
  • 安卓So层Hook实战:ARM64函数定位与参数还原五步法
  • 告别虚拟机:在龙芯3A6000真机上流畅运行统信UOS的配置心得与性能调优建议
  • 2026年质量好的油缸修复专用珩磨机可靠供应商推荐 - 行业平台推荐
  • Word2016受保护视图报错原因与安全放行指南
  • Java NIO 连接状态守卫:AlreadyConnectedException 源码深度剖析与 SocketChannel 生命周期契约
  • 在Ubuntu 22.04上,用SSH和HTTPS两种方式搞定OpenHarmony 4.1 Release源码下载(附工具链配置)
  • 粒子物理分析中类别权重对机器学习分类器性能与物理结果的影响
  • UABEA:Unity跨平台资源编辑与二进制解析工具深度指南
  • HPE DL560 Gen10服务器装系统踩坑实录:Windows Server 2012 R2下P816i-a SR阵列卡驱动安装全流程
  • Java中的接口
  • AssetStudio深度指南:Unity资源提取与二进制结构解析
  • 在Ubuntu 14.04上为老旧系统(如XP)搭建现代Web服务栈:Apache 2.4.59 + OpenSSL 1.1.1w + PHP 8.3.6 保姆级配置指南
  • 重赏之下必有勇夫的科学依据找到了:《Science》发现超级大奖励可“开挂”学习,多巴胺是幕后功臣
  • 深入Linux内核链表:从of_property_read_bool看设备树属性的组织与查找
  • r0capture安卓抓包原理:绕过证书固定提取SSL密钥
  • AI Agent Harness模型推理缓存优化
  • 机器学习加速超导材料发现:从梯度提升回归到DFT验证的完整工作流
  • 保姆级教程:Ubuntu 20.04下RTL8111/8168网卡驱动安装与自动加载(实测有效)
  • Unity深度感知动态模糊系统:分层控制与UI隔离实战
  • 混沌系统预测:输入长度如何影响模型误差与稳定性
  • Rust Web框架对比:Axum、Rocket、Warp深度解析
  • DaCe AD:打造不挑食的高性能自动微分引擎,加速科学计算梯度计算
  • 物理信息机器学习:融合物理定律与数据,革新燃烧模拟与优化
  • OpenClaw+SecGPT-14B:渗透测试上下文编排与AI报告生成实战
  • 量子噪声模拟:从原理到NISQ时代的实践优化
  • JMeter临界部分控制器:业务节奏建模与资源争用压测核心
  • 国际半导体博览会汇总,适合企业出海参展的展会清单 - 品牌2025
  • Godot .pck文件解析原理与三步安全解包指南