【C语言】深入理解C语言数据类型:从结构体到共用体和枚举的全面解析

news2025/2/4 0:58:45

目录

一、结构体概述及定义

1、概念

2、定义方式

方式1:先定义结构体类型,再定义结构体变量

方式2:定义结构体类型的同时定义结构体变量

方式3:定义一次性结构体

二、结构体变量的初始化

1、一般初始化

2、清空结构体变量:使用memset

3、键盘输入给结构体变量中成员赋值

 4、单独操作结构体中的成员

 5、相同类型的结构体变量之间整体赋值

 三、结构体嵌套结构体

四、结构体数组 

1、初始化赋值

2、 键盘输入给结构体赋值

 五、结构体指针变量

1、 结构体指针变量

2、结构体数组元素的指针变量

六、结构体的指针成员

        1、指针成员

        2、结构体的指针成员指向堆区 

 3、浅拷贝问题

4、结构体在堆区 结构体的指针成员指向堆区。(了解)

5、结构体指针数组在堆区、结构体在堆区、结构指针成员在堆区(了解) 

七、结构体的内存分配对齐规则

1、自动对齐规则

2、结构体嵌套结构体 自动对齐规则

 3、强制对齐

八、结构体的位域

1、位域的概念

 2、防止位溢出

3、另起一个存储单元

 4、无意义位段

 九、共用体union

 十、枚举


一、结构体概述及定义

1、概念

一种或多种基本类型构造类型(数组)都叫数据结构,
结构体是一种或多种基本类型构造类型(数组)数据的集合,即数据结构的集合

2、定义方式

结构体定义由关键字 struct 和结构体名组成

方式1:先定义结构体类型,再定义结构体变量

struct stu
{
    int num;
    char name[10];
};//定义结构体stu
struct stu lucy;//定义结构体变量lucy

方式2:定义结构体类型同时定义结构体变量

struct stu
{
    int num;
    char name[10];
}lucy;//定义结构体stu同时定义结构体变量lucy

方式3:定义一次性结构体

struct 
{
    int num;
    char name[10];
}lucy;

 注:结构体变量可以与成员名相同。

访问成员方式:lucy.num(继承类型,int型) lucy.name(char型,数组名代表首元素地址)

定义结构体类型及其成员时系统不分配空间,并且定义类型一般不能给成员变量赋值

二、结构体变量的初始化

1、一般初始化

struct stu
{
    int num;
    char name[10];
};
void test()
{    
    //结构体变量的初始化,必须遵循成员的顺序以及类型
    struct stu lucy={100,"lucy"};
    printf("%d %s",lucy.num,lucy.name);
}

2、清空结构体变量:使用memset

3、键盘输入给结构体变量中成员赋值

 4、单独操作结构体中的成员

 5、相同类型的结构体变量之间整体赋值

三种方式:

 三、结构体嵌套结构体

定义:

struct stu
{
	int num;
	char name[10];
	struct data data;//嵌套结构体变量data
};
struct data
{
	int year;
	int month;
	int day;
};

初始化及输出:

	struct stu lucy = { 111,"lucy",{2002,3,7} };
	printf("%d %s\n", lucy.num, lucy.name);
	printf("%d %d %d", lucy.data.year, lucy.data.month, lucy.data.day);

四、结构体数组 

        结构体数组:本质是数组 每个元素结构体

1、初始化赋值

2、 键盘输入给结构体赋值

 五、结构体指针变量

1、 结构体指针变量

        本质是指针变量 保存的是结构体变量的地址

2、结构体数组元素的指针变量

六、结构体的指针成员

        1、指针成员

                指针变量作为结构体中的成员

        2、结构体的指针成员指向堆区 

 3、浅拷贝问题

        相同类型的结构体变量整体赋值时,如果结构体中没有指针成员赋值不会出现浅拷贝。 如果结构体中有指针成员 赋值 容易造成浅拷贝

        浅拷贝出现的问题:相同类型的结构体变量赋值导致各个结构体变量的指针成员指向同一处堆区空间,而各个结构体独立释放指针成员指向的空间时,造成同一处堆区空间被释放多次

struct stu bob;
bob = lucy;//浅拷贝

        解决方法:如果结构体中有指针成员 尽量使用深拷贝

struct stu bob;
bob.name = (char *)calloc(1, 128);
bob.num = lucy.num;
strcpy(bob.name, lucy.name);

4、结构体在堆区 结构体的指针成员指向堆区。(了解)

5、结构体指针数组在堆区、结构体在堆区、结构指针成员在堆区(了解) 

#include <stdio.h>
#include<stdlib.h>
struct stu
{
	int num;
	char *name;//指针成员
};
void test()
{
	struct stu **arr=NULL;
	arr=(struct stu **)calloc(5,sizeof(struct stu *));///给结构体指针数组申请堆区空间
	int i = 0;
	for ( i = 0; i < 5; i++)
	{
		//给指针数组中的每个元素 申请结构体堆区空间
		arr[i] = (struct stu*)calloc(1, sizeof(struct stu));
		//每个结构体中的name成员申请堆区空间
		arr[i]->name = (char*)calloc(1, 100);
		arr[i]->num = 10 + i;
		sprintf(arr[i]->name, "姓名%d", i + 1);
	}
	for ( i = 0; i < 5; i++)
	{
		printf("%d %s\n", arr[i]->num, arr[i]->name);
	}
	//释放
	for ( i = 0; i < 5; i++)
	{
		//先释放结构体中的name的指向
		if (arr[i]->name != NULL)
		{	
			
			free(arr[i]->name);
			arr[i]->name = NULL;
		}
		//释放结构体
		if (arr[i] != NULL)
		{	
			free(arr[i]);
			arr[i] = NULL;	
		}
		//释放整个arr指针数组
		if (arr != NULL)
		{
			free(arr[i]);
			arr= NULL;
		}
	}
}

七、结构体的内存分配对齐规则

1、自动对齐规则

(1)确定分配单位由 结构体中最大的基本类型 长度决定。

(2)确定成员的偏移量

        成员偏移量 = 成员自身类型长度整数倍。倍数由从前往后未被占用的内存空间决定。

(3)结构体的总大小 = 分配单位整数倍

 经典案例:画出以下结构体的对齐

struct Data
{
    char a;//成员偏移量 =1B*0
    short b;//成员偏移量 =2B*1
    int c;//成员偏移量 =4B*1
    char d;//成员偏移量 =1B*8
    short e;//成员偏移量 =2B*5
};

最大基本类型为int,分配单位4B,内存分配对齐:

abb
cccc
dee

故总共12B

2、结构体嵌套结构体 自动对齐规则

(1)确定分配单位由 全部结构体中最大的基本类型 长度决定。

(2)确定成员的偏移量

        普通成员偏移量 = 成员自身类型长度整数倍。倍

        被嵌套的结构体整体偏移量 = 该结构体中最大的基本类型整数倍

以上倍数由从前往后未被占用的内存空间决定。

(3)结构体的总大小 = 分配单位整数倍 

   嵌套结构体大小 = 该结构体中最大的基本类型整数倍

内存分配情况:共16B

a2
a1
b1b1b1b1
c2c2

 3、强制对齐

#pragma pack (value)时的指定对齐值value(value值为2^{n}

(1)确定分配单位 = min(结构体中最大的基本类型, value)

(2)确定成员的偏移量 成员偏移量 = 成员自身类型的整数倍。

(3)收尾工作 结构体的总大小 = 分配单位整数倍

八、结构体的位域

1、位域的概念

        在结构体中,以为单位的成员,咱们称之为位段(位域)

 总共占32位4B

没有非位域隔开且类型相同的位域 叫相邻位域。

相邻位域可以压缩。但是压缩的位数不能超过自身类型的大小。

不能对位域取地址(因:系统分配地址以字节为单位)

 2、防止位溢出

        对位域赋值不能超过位域本身位的宽度 

 

3、另起一个存储单元

 4、无意义位段

 九、共用体union

结构体:所有成员拥有独立空间

共用体:所有成员共享同一块空间

例: 

union Data
{
    char a;
    short b;
    int c;
};

成员a b c共享同一块空间,空间大小由最大的成员空间决定,data为4B。

体现共享:

 成员a b c共享同一块空间,但是每个成员 能操作的空间的范围 是由成员自身类型长度决定

 十、枚举

        枚举:将枚举变量 要赋的值 一一列举出来

以扑克花色为例枚举四种花色:

enum POKER_COLOR{HONGTAO,MEIHUA,FANGKUAI,HEITAO};

若修改某个枚举列表的值,从修改处再依次递增。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/762042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【正点原子STM32连载】 第五十六章 DSP测试实验摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第五…

欧姆龙cp11以太网设置

捷米特JM-ETH-CP转以太网模块控&#xff0c;用于欧姆龙 CP1L/ CP1E/ CP1H 系列 PLC 的以太网数据采集&#xff0c;非常方便构建生产管理系统。 支持 FINS/UDP、FINS/TCP 以太网协议通信&#xff0c;支持上位机软件&#xff08;组态王、MCGS、力控、KepWare OPC 服务器等&#…

leetcode2373. 矩阵中的局部最大值

https://leetcode.cn/problems/largest-local-values-in-a-matrix/ 给你一个大小为 n x n 的整数矩阵 grid 。 生成一个大小为 (n - 2) x (n - 2) 的整数矩阵 maxLocal &#xff0c;并满足&#xff1a; maxLocal[i][j] 等于 grid 中以 i 1 行和 j 1 列为中心的 3 x 3 矩阵中…

【Android】报错java.lang.reflect.InvocationTargetException解决办法

报错信息&#xff1a;java.lang.reflect.InvocationTargetException反射层调用方法失败 结果图 原因 InvocationTargetException异常由Method.invoke(obj, args…)方法抛出。(反射异常) 当被调用的方法的内部抛出了异常而没有被捕获时&#xff0c;将由此异常接收&#xff01;&…

Stable Diffusion如何生成高质量的图-prompt写法介绍

文章目录 Stable Diffusion使用尝试下效果prompt的编写技巧prompt 和 negative promptPrompt格式Prompt规则细节优化Guidance Scale 总结 Stable Diffusion Stable Diffusion是一个开源的图像生成AI系统,由Anthropic公司开发。它基于 Transformer模型架构,可以通过文字描述生成…

查询每年最新的数据

1.最近在工作中遇到了一个需求,要求查询出每个党组织每年最新的数据 2.使用的sql语句为: SELECTCREATED_TIME,party_org_id,id FROMbranch_book WHERECREATED_TIME IN ( SELECT MAX( CREATED_TIME ) AS CREATED_TIME FROM branch_book GROUP BY DATE_FORMAT( year, %Y ), pa…

移动云发布医疗行业白皮书,构建全民健康数字化枢纽

医疗卫生改革正在深入推进&#xff0c;全民健康信息化建设也在加速进行。医疗云作为医疗卫生数字化转型的基础性平台&#xff0c;正引起越来越多的关注和探讨。近日&#xff0c;由中国移动集团政企事业部牵头发起&#xff0c;移动云联合IDC中国重磅发布《建设医疗云平台&#x…

Threejs——十四、关于深度冲突、重叠、以及加载模型进度条效果实现(附完整代码)

深度冲突 两个模型重叠的模型&#xff0c;通过浏览器旋转预览&#xff0c;会发现模型旋转的时候会发生闪烁。 这种情况&#xff0c;主要是两个模型重合&#xff0c;电脑分不清谁在前谁在后&#xff0c;这种情况&#xff0c;可以理解为深度冲突Z-fighting。 function addBox()…

Pytorch基本使用——NLP数据集构建总结

构建NLP数据集&#xff0c;分为如下几步&#xff1a; 1.单词分割形式 2.词汇表 3.利用词汇表word2idx映射&#xff0c;制作数据集 4.打包 ✨ 1.单词分割 有两种表示方式&#xff0c;一种是word-level&#xff0c;另外一种是char-level。 &#x1f30a; 1.1 word-level token…

可爱小猫猫【InsCode Stable Diffusion美图活动一期】

一、 Stable Diffusion 模型在线使用地址&#xff1a;https://inscode.csdn.net/inscode/Stable-Diffusion 二、模型版本及相关配置&#xff1a; 模型&#xff1a;chilloutmix_NiPrunedFp32fix Lora&#xff1a;cat_20230627113759 采样迭代步数&#xff08;steps&#xff09;:…

十三、前端包管理工具详解

一、代码共享方案 我们已经学习了在JavaScript中可以通过模块化的方式将代码划分成一个个小的结构&#xff1a; 在以后的开发中我们就可以通过模块化的方式来封装自己的代码&#xff0c;并且封装成一个工具&#xff1b; 这个工具我们可以让同事通过导入的方式来使用&#xf…

jetson系列开发板生成.engine部署

jetson系列开发板 生成engine 1. 下载 tensorrtx 至 NX git clone -b yolov5-v5.0 https://github.com/wang-xinyu/tensorrtx.git2. 修改 yololayer.h 中的参数 labels.txt 中有几类就将 CLASS_NUM 修改为几。 static constexpr int CLASS_NUM 80; 3. 编译 tensorrtx/yolov…

OLED拼接屏出现坏点怎么办?专家提供的修复方法与建议

OLED拼接屏作为一种高级显示技术&#xff0c;广泛应用于商业展示、会议室和监控中心等场所。 然而&#xff0c;由于制造过程中的缺陷或长时间使用导致的原因&#xff0c;OLED拼接屏可能出现屏幕坏点问题。本文将详细介绍OLED拼接屏屏幕坏点的修复方法与注意事项&#xff0c;帮…

高效编程:如何优雅地判断数组中所有对象的值不为空?

前言 在前端开发中&#xff0c;判断数组中所有对象的值是否都不为空是一个常见的任务。这个任务可能涉及到多个对象和多个属性&#xff0c;因此需要一种简洁而高效的方法来处理。本文将介绍三种不同的方法&#xff0c;帮助你轻松应对这个问题。 方法一&#xff1a;使用 every()…

原生js实现将图片内容复制到剪贴板

核心代码 /*复制图片*/ copyImg(dom) {/* 警告&#xff1a;dom不能是img标签&#xff0c;建议用DIV标签包裹img标签&#xff0c;否者会报错&#xff01;不支持复制背景图&#xff01; */dom.style.userSelect auto;let selection getSelection(), range document.createRan…

【AT89C52单片机项目】数字密码锁设计

实验目的 使用单片机设计数字密码锁。 实验仪器 一套STC89C52RC开发板套件&#xff0c;包括STC89C52RC开发板&#xff0c;以及USB烧录线。 设计要求 1、有设置密码、开锁工作模式&#xff1b; 2、可以每次都设置密码&#xff0c;也可以设置一次密码多次使用。 实验原理 …

JS加密之JS基础大考验

JS加密之JS基础大考验 工欲利其器 必先善其事 JavaScript&#xff08;简称JS&#xff09;是一种高级、动态、弱类型的编程语言&#xff0c;主要用于前端网页开发&#xff0c;但也可用于后端服务器开发&#xff08;通过Node.js&#xff09;。下面是JavaScript的一些特点&#…

windows 安装Vcenter6.7避坑指南

1、推荐windows server 2016。第一次选择windows 2019会出现很多错误 2、内存要求&#xff1a;8G以上 3、如果安装了VMtools&#xff0c;则需要把VCC全部卸载了&#xff08;控制面板-->卸载程序&#xff09;

【Linux初阶】基础IO - 软硬链接 | 初识、理解、应用 文件acm时间

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux初阶】 ✒️✒️本篇内容&#xff1a;初识软硬链接&#xff0c;软硬链接的区别&#xff0c;理解软硬链接&#xff0c;软硬链接的应用&#xff0c;文…

Access简单应用

不说废话,直入正题. 关于Access的用法 一开始大家想用添加数据快速生成sql语句,其实在这里 java链接Access数据库需要ODBC连接池 机器jar包 ODBC连接池在 首次添加需要配置如上图所示,jar包链接在下面,直接放到项目下即可 UCanAccess - Browse Files at SourceForge.net下载…