C++入坑系列(四)复合类型之结构体、共用体和枚举类型

C++的结构体、联合体、枚举类型(一) C++的结构体、联合体和枚举类型基础(一) 阅读详情

前言

无论在C语言还是C++中,均包含结构体、共用体和枚举类型。由于这三种复合数据类型的概念和使用方法比较简单,所以本文仅对其一些需要注意的内容进行总结。如有疏漏或不足之处,还望各位读者能够不吝指正。

结构体

简介

前面我们学习过的数组,其作用是保存多个相同数据类型的数据。但是在实际应用中,我们往往会遇到更加复杂的情况。比如:我们的学生管理系统,我们不仅需要保存学生的姓名,而且还需要保存学生的班级、学号、年龄等一些列信息,再加上这些信息不能够使用相同的数据类型进行存储,所以便不能使用数组去保存每个学生的详细信息了。
此时,便可以使用结构体数据类型,保存由不同数据类型组成的数据集合了。
简而言之,结构体就是一种可以保存不同数据类型的数据结构。

创建结构体的方法

结构体以struct关键字作为数据类型的标志。在实际使用中,我们可以使用下述三种方法,创建结构体数据类型:
1、常规方式1

struct testStruct
{
	string name;//学生的姓名
	unsigned int core;//学生的分数
	string address;	//学生的地址
};//声明一个结构体数据类型
testStruct structStu1;//C++中创建一个结构体structStu1
//struct testStruct structStu1;//C语言中创建一个结构体structStu1

2、常规方式2

struct testStruct
{
	string name;//学生的姓名
	unsigned int core;//学生的分数
	string address;	//学生的地址
}structStu1,structStu2;//声明一个结构体数据类型,并创建两个结构体structStu1和structStu2

3、利用typedef的方式

typedef struct
{
	string name;//学生的姓名
	unsigned int core;//学生的分数
	string address;	//学生的地址
}testStruct;//声明一个结构体数据类型
testStruct structStu1,structStu2;//创建两个结构体structStu1和structStu2

结构体中的位字段

在嵌入式等底层编程中,往往会遇到结构体的位字段概念,即可以指定结构体成员所占的位数。
尤其是涉及到寄存器封装的部分。由于寄存器往往由许多Bit位组成,而每个Bit位所占的位数可能并不相同,所以此时使用结构体的位字段,便可以实现寄存器的内存空间分配。我们以TI的DSP28335芯片的一个寄存器为例进行说明:
在这里插入图片描述

结构体使用技巧

在使用结构体时,如果注意成员变量的位置,那么可以在一定程度上提高程序的执行效率并且节省内存空间。
由于结构体中可以存储不同数据类型的成员,所以在开辟内存空间时,并不是按照固定的大小进行分配的。再加上CPU一般以4个字节作为最优的数据处理大小,所以注意不同数据类型的成员数据的位置,可以对结构体进行优化。
比如:

//声明一个学生的结构体
struct student1
{
	char sex;//学生的性别
	char test;//用于测试的一个字符
	int age;//学生的年龄
};
struct student2
{
	char sex;//学生的性别
	int age;//学生的年龄
	char test;//用于测试的一个字符
};
int main()
{
	student1 stu1 = 
	{
	'M','F',18
	};//定义并初始化一个结构体变量stu1
	cout << "stu1结构体占用的内存大小为:" << sizeof(stu1) << endl;
	student2 stu2 = 
	{
	'M',18,'F'
	};//定义并初始化一个结构体变量stu2
	cout << "stu2结构体占用的内存大小为:" << sizeof(stu2) << endl;
	return 0;
}

输出结果如下:
在这里插入图片描述
为什么相同成员的结构体,所占的内存空间大小却不同呢?
因为在student1结构体中,两个char数据类型是相邻的,由于char数据类型的大小为一个字节,所以4个字节可以保存两个char数据类型的变量,再加上int数据类型的大小为4个字节,所以stu1结构体变量所占的内存空间便是8个字节。
但是在student2结构体中,两个char数据类型之间插入了一个int数据类型,第一个char数据类型占据了4个字节中的一个字节,剩下的3个字节无法存储int类型的变量,所以还需要在第二个4字节的空间中保存int数据,而第二个char数据类型还需要再开辟一个4字节大小的空间进行保存,所以最终占用的内存空间大小便是12个字节。

共用体

简介

共用体和结构体的作用类似,不同之处在于:
结构体中可以同时存储结构体成员数据,但是共用体只能同时存储一个共用体结构体成员。

共用体的内存分配

通俗的来说,就是在创建结构体变量时,编译器会为结构体中所有的成员开辟内存空间。而在创建共用体变量时,编译器仅会开辟一个内存空间,该内存空间的大小与共用体成员中所占空间最大的成员数据相等。
从内存大小来说,结构体的大小是所有成员数据的大小之和,而共用体的大小是其占用内存最大的成员数据的大小。并且,结构体中的成员数据位于不同的内存地址处,而共用体中的成员数据全部位于同一个地址处。测例如下:

#include <iostream>
#include <cstring>
typedef struct
{
    char name[10];
    double core;
    char address[20];
}stuStruct;
typedef union
{
      char name[10];
      double core;
      char address[20];
}stuUnion;
int main()
 {
     using namespace std;
     stuStruct student1 =
     {"Issac",89.0,"ChengDu"};//初始化结构体
     cout << "结构体占用的内存大小为:" << sizeof(student1) << endl;
     cout << "结构体student1.name的地址:" << &student1.name << endl;
     cout << "结构体student1.core的地址:" << &student1.core << endl;
     cout << "结构体student1.address的地址:" << &student1.address << endl;
     stuUnion student2;
     student2.core = 90.5;
     cout << "共用体占用的内存大小为:" << sizeof(student2) << endl;
     cout << "共用体student2.core的地址:" << &student2.core << endl;
     strcpy(student2.name,"Issac");
     cout << "共用体student2.name的地址:" << &student2.name << endl;
     return 0;
 }

输出结果如下:
在这里插入图片描述

共用体与结构体的结合

在嵌入式开发中,经常需要对寄存器的某个位进行操作,但是也可以对整个寄存器的整体进行操作,完成整个寄存器的赋值操作。此时,便可以使用共用体和结构体,共同完成上述功能。如下所示:
在这里插入图片描述
在实际使用中,我们可以按照下面的说明进行使用:

union GPACTRL_REG GpaCtrlRegs;//创建一个共用体变量
 GpaCtrlRegs.all = 0xFF;//将这个寄存器的所有位设置为1
  GpaCtrlRegs.bit.test = 1;//将该寄存器的test位设置为1

枚举类型

简介

枚举类型的作用与利用define宏定义或者const关键字类似,均是创建常量的一种方式。在创建枚举类型时,使用enum作为该类型的标志。
枚举类型一般用于只能在某个数值范围内进行选择的场合下,比如:每周的七天,每年的12个月等。

创建枚举类型

此处,我们创建一个枚举数据类型,用来表示每周的星期几:

enum week
{
	Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday	
};//默认情况下,枚举类型的数据成员从0开始,比如上面的Monday就等于0,Tuesday等于1
enum week
{
	Monday = 1,Tuesday,Wednesday = 3,Thursday,Friday,Saturday,Sunday	
};//我们也可以人为指定枚举成员的数值,如上所示

为枚举类型分配内存空间

枚举类型的内存分配方法与共用体的方法相似,也仅仅会为整个枚举类型分配一个元素的内存空间的大小,比如:

typedef enum
{
	one = 1,two,three,four
}NUM_ENUM;//声明一个枚举类型
int main()
{
	NUM_ENUM num;//定义一个枚举类型变量
	cout << "枚举数据类型的大小为" << sizeof(num) << endl;//输出的结果为4
	return 0;
}

注意事项

在使用枚举类型时,需要额外注意以下限制:
1、枚举成员的值必须是整型,且同一个枚举变量中,不能有相同的枚举成员!!!比如:

enum testEnum
{
	one = 1,two = 2.0
};//错误,枚举类型只能是整型数据
enum testEnum
{
	one = 1,two = 2,one = 3
};//错误。同一个枚举类型中,不能出现相同的枚举成员

2、访问枚举成员时,必须访问枚举类型中存在的枚举成员,不能访问不存在的成员。
3、虽然枚举成员可以被认为是相应的整型数据,但是不能直接将一个整型数据赋值给一个枚举变量,但是可以利用强制类型转换实现,比如:

enum testEnum
{
	one = 1,two = 2
};
testEnum test1;
test1 = 1;//错误,及时枚举成员中的one实际上就是1
test1 = (testEnum)(1);//正确

总结

上述三种复合数据类型,在实际的工程开发中,也是会经常出现的。虽然概念上不难理解。但是在实际使用时,还是需要注意各个数据类型的注意事项。尤其是在使用共用体时,需要注意其内存分配原则。

C++ Primer Plus学习(三)—— 复合类型 复合类型数组字符串string类简介结构简介共用体枚举指针和自由存储空间指针、数组和指针算术类型组合数组的替代品 数组 字符串 string类简介 结构简介 共用体 枚举 指针和自由存储空间 指针、数组和指针算术 类型组合 数组的替代品 ... 阅读详情

相关推荐

C及C++中typedef的简单使用介绍

C/C++中关键字typedef的理解不是多透彻,今天小编抽空给大家分享下C及C++中typedef的简单使用介绍,需要的朋友可以参考下

面试中关于C++中的类,结构体,enum,字符变量等所占内存空间问题总结

关于C++中类所占的内存空间总结,见bluesky的文章: http://blog.sina.com.cn/s/blog_69c189bf0100mkeu.html 另外,阿里巴巴有一道笔试题,问sizeof(a)的大小 #pragma pack(2) class A { int i; union U { char buff[13]; int i; }u; void f

sd396791336的专栏 1949

CTF---Web---文件包含---01

文章目录前言一、题目描述二、解题步骤1.查看源代码2.文件包含(/etc/passwd)3.解码总结 前言 题目分类: CTF—Web—文件包含 一、题目描述 题目:提示寻找passwd文件 二、解题步骤 1.查看源代码 提示所有图片存储路径是download.php?name=img, 此时name参数的存在就提示此题可能为“文件包含”。 2.文件包含(/etc/passwd) 两种查看方式: 2.1、访问view-source:http://192.168.87.180/download.php

qq_22160557的博客 1391

2020-09-11

运算符总结 在js中,说运算符之前就必须提到类型的转换,数据类型会自动根据需要进行类型的转换。我们先来学习一下js数据类型转换 == 在比较之前会先转化等号两端的变量为统一的数据类型然后进行比较。 ===判断是否严格相等,如果类型不同就不等。 和=的区别: 对于String number等基础类型 不同类型比较,==转化成同一类型的值,看值是否相同。===如果类型不同,其结果就是不等。 同类型的比较,直接进行值的比较,两者结果一样 - 对于Array Object等高级类型 和=是没有区别的,进行

Yang_Feng_Love的博客 1031

从零开始的BW(五) 外部系统供数之OData测试

5、激活添加的服务,如提示下图中的激活失败,根据生成URI在事务代码SICF目录中找到对应的服务,设置超时时间,设置完之后重新激活即可,详情可参考SAP note 1986626。如果刚才设置BY Odata的query在这没有显示,SE38执行程序EQ_RS_AUTOSETUP,选中需要生成服务的query,生成服务后再去添加服务。测试get方法,URI中默认的参数是?4、事务代码/IWFND/MAINT_SERVICE中添加服务,如果提示用户不再登陆,在事务代码前加上/O或者/N即可。

m0_61386064的博客 1107

西工大noj100题python2024第三季21-30

【代码】西工大noj100题python2024第三季21-30。

weixin_70523540的博客 1576

【牛客网】—— 枚举(enum)所占内存大小

这里我们先来看一道题 这是牛客网上的一个题,我在计算这个类的大小时,对于enum枚举类型所占空间的大小有了一些困惑,通过查阅资料我了解到其实在C++标准文档中是这样说明的:“枚举类型的尺寸是以能够容纳最大枚举子的值的整数的尺寸”,同时标准中也说名了:“枚举类型中的枚举子的值必须要能够用一个int类型表述”,也就是说,枚举类型的尺寸不能够超过int类型的尺寸,但是是不是必须和int类型具有相同的尺...

chenxiyuehh的博客 1万+

UReport2 报表设计器 在线表格

UReport2官网 一、UReport2报表设计器 UReport2是一个开源的可视化报表设计器,功能强大,操作简单,可以实现复杂的报表统计,有各种各样的导出和打印功能,支持导入Excel表格! 1、报表设计器 2、设计一个简单的用户列表展示 二、可编辑表格 扩展了layui的表格,支持多元化数据编辑(单选,多些、日期、下拉联动),开发简单、高效、便捷。有了它就可以轻松开发类似进销存系统的表格录入功能了,用户拿来即用! 三、主从表录......

ejinxian的专栏 2万+

C++(六)复合类型(结构体,共用体,枚举)

文章目录一、结构体1.1 结构体类型的声明1.2 结构体类型变量的定义及初始化1.3 结构体类型变量成员的访问1.3 结构体类型和数组配合使用二、共用体三、枚举3.1 枚举类型的声明:四、指针 一、结构体 C/C++语言本身提供了很多基本数据类型,例如:int、float、char、double、long int 等供我们使用。但是程序编写的过程中问题往往比较复杂,基本的数据类型有时候不能满足我们...

红叶谷 wsp_1138886114的博客 1209

从零到一:手把手教你用STM32F103C8T6打造个人专属开发板(附立创EDA工程与源码)

本文详细介绍了如何使用STM32F103C8T6微控制器从零开始设计和制作个人专属开发板。内容涵盖硬件选型、原理图设计、PCB布局、功能验证等全流程,并提供了立创EDA工程文件和源码,帮助开发者深入理解STM32开发板的硬件架构与设计要点。

weixin_26802933的博客 285

WorkBuddy 技能指南:基础办公与文档处理

WorkBuddy 不仅仅是一个对话工具——它通过技能(Skills)系统,将通用 AI 助手转变为具备专业领域能力的智能助手。每个技能都是一套经过精心设计的"能力包",包含专业知识、工作流程和专用工具。本文聚焦于文档处理类技能——这是日常工作中使用频率最高、最实用的能力集合。

u011186532的专栏 703

【嵌入式】枚举类型与结构体的结合使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 【嵌入式】枚举类型与结构体的结合使用前言一、常用的预设二、使用枚举类型 前言 在嵌入式开发中经常需要按位分配内存,而这往往是配合着结构体typedef struct以及GNU C的__attribute__ ((packed))语句来一起使用的。这些按位分配的内存,常会存储一些预设好的值。 这篇笔记便是关于这些预设值该如何设定一些的讨论。 一、常用的预设 在嵌入式开发中,通常会通过宏定义来预设参数,示例如下: #define TEST_

fhxzh1993的博客 3479

让 PyCharm 代码“发光”:高亮插件与特效全攻略

PyCharm 作为一款强大的 Python IDE,支持多种插件让代码“发光”——无论是动态输入特效、彩虹括号,还是霓虹主题,都能让你的代码脱颖而出!进入 File → Settings → Editor → Color Scheme → Rainbow Brackets。进入 File → Settings → Appearance & Behavior → Material Theme。进入 File → Settings → Editor → Color Scheme → General。

qq_43580271的博客 3834

【C++ | 复合类型】结构体、共用体、枚举、引用等详解和C++例子

本文主要介绍C++的复合类型,并给出C++例子源码,说明各个复合类型的使用。

wkd_007的博客 1842

《Java开发及前端最全面试题-Offer直通车》目录

Java开发是需求最广,工资高的细分领域,同时也是会的人最多,有的公司招1个Java开发,要面试几十甚至上百面试者,同时要求很高,要求通晓技术栈很多及很深深度。如果你正准备面试,想要脱颖而出,那么《Java开发及前端最全面试题-Offer直通车》是你的不二选择。本书汇集了多篇超过1万字的精华内容,无论是Java基础、数据库、SpringBoot和SpringCloud等必问的,还是前端、k8s等容器和虚拟化和大数据各类技术面试,本书都为你提供了最全面的试题和参考答案。

大模型大数据攻城狮的专栏 1178

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C++中的几种基本复合类型

摘抄自《C++ Primer Plus》,由于博主比较比较熟悉C语言,所以这里不会有太全面的语法介绍,基本上只是为了和C进行比较,从而突显C++相比于C在复合类型用法方面的特殊之处 文章目录序言结构体共用体枚举类型总结 序言 在C语言中,我们学过的复合类型有结构体、共用体、枚举类型。今天我们就来看看它们在C++中是什么样子。 结构体 1、定义结构体 struct fruit { strin...

Shijia Yin 1088

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【C++ Primer Plus】笔记 - 第四章 复合类型

C++ Primer Plus 第四章-复合类型 自学笔记, 可能不适用于所有人, 仅供参考。

Morinnn的博客 1738

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

《C++ Primer Plus》 第四章 复合类型 Part 4——共用体和枚举

《C++ Primer Plus》 第四章 复合类型 Part 4——共用体 共用体union是一种数据格式,它能够存储不同的数据类型,但只能同时存储其中的一种类型。 共用体的声明&创建新变量 注意:共用体成员不能使用string类型。 union one_for_all { int intval; long long llongval; double doubleval; }; o...

NiuJuxin的博客 321

浅谈C++复合类型(上半篇)

本文简要讲述了C++中除了指针以外的复合类型,讲述了如何简单地使用这些复合类型,以及使用过程中的注意事项。

潇雪的博客 1374

C++字符串输入输出以及复合类型浅谈

文章目录0. 目前遇到的cout和cin的特性1. 字符和字符串2. 输入输出字符串接收数据情况3. 结构体4. 共用5. 枚举6. 基本类型组合而成的复合类型7. 静态数组和动态数组(需要创建指针)8. 字符和字符串 想要使用cout输出两个字符数组,第二个被正常输出,第一个正常输出后出现了乱码,处理字符串的函数,像cout输出字符串,它们都会把字符串里面的字符一个一个的进行处理,如果遇到空字符,则停止处理,由于第一种写法没有写入\ 3. 结构体 声明结构体使用struct关键字,创建形式如下: ...

花狗Fdog的博客 6878

4 复合类型数据

4.复合数据类型

South_Rosefinch的博客 944

C++ Primer Plus 学习笔记(复合类型)(二)

1. 结构(结构体) 结构是一种比数组更灵活的数据格式,因为同一个结构可以存储多种类型的数据,将数据的表示合并到一起。 结构是用户定义的类型,而结构声明定义了这种类型的数据属性。定义了类型后,可以创建这种类型的变量。 1. 1 结构的定义方法 结构的定义如下面的例子: struct inflatable // structure declaration { char...

HenryFeng1008的博客 1956

C++基础——复合类型

C++基础——复合类型 文章目录C++基础——复合类型字符串字符串输入getlineget空行和其他问题其他形式的字符串字面值字符函数库cctype共用体枚举类型 字符串 字符串输入 cin在读取字符串时以空格、制表符和换行符来确定字符串结束位置,这就导致当我们输入一行字符串,如果中间有空格或制表符,则会被拆成两个字符串作为输入。 为了方便,引入了读取一行的函数让字符串输入更加灵活。 getline getline作为cin的一个成员函数,通过回车键输入的换行符来确定输入结尾。 getline有两个参数,第

qq_41855159的博客 239

C++中的复合类型数据

1、数组 数组(array)是一种数据格式,能够存储多个同类型的值。数组声明要指出以下几点:(1)存储在每个元素中的值的类型;(2)数组名;(3)数组中的元素个数。 1.1 数组有效下标值的重要性 编译器不会检查使用的数组下标是否有效。如将一个值赋值给不存在的元素data[-1],编译器并不会指出错误,但是程序运行之后,这种赋值可能会引发错误,可能破坏数据或者代码,也可能导致程序异常终止。 2、字符串 字符串是存储在内存的连续字节中的一系列字符。 C-风格字符串具有一种特殊的性质:以空字符(nu

qq_41455814的博客 466

第四章 复合类型

第四章 复合类型 字符串 读取一行字符 getline():读取整行,遇到换行符,输入结束。(不保留换行符) 第一个参数:存储输入的数组名称 第二个参数:要读取的字符数 get():读取整行,遇到换行符,输入结束。(保留换行符) 第一个参数:存储输入的数组名称 第二个参数:要读取的字符数 cin.get(nam, Arsize); cin.get();//读取第一行的换行符 cin.getline...

qq_32631105的博客 237

C++ primer Plus学习笔记(第四章)——复合类型

第4章 复合类型4.1 数组4.4 字符串三级目录 4.1 数组 声明数组时应注意以下三点: 存储在每个元素中值的类型; 数组名; 数组中的元素数; 例如:short months[12];表示创建了一个名为months的数组,包含12个short类型的元素。 通用格式:typeName arrayName[arraySize]; 数组从0开始编号,months[0]是 short months的第一个元素。 数组的初始话规则: 只有在定义数组时可以初始化,不过可以使用下标修改数组某一元素的值。 若只

qq_38548951的博客 629
上一篇: C++入坑系列(五)函数与数组
下一篇: C++入坑系列(六)之const和指针
「已注销」
博客等级 码龄7年 49粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值