C++ 结构体和联合体

chatgpt/2023/9/27 16:59:48
1.结构体

结构体是一种特殊形态的类,它和类一样,可以有自己的数据成员和函数成员,可以有自己的构造函数和析构函数,可以控制访问权限,可以继承,支持包含多态,结构体定义的语法和类的定义语法几乎一样。结构体和类的唯一区别在于,结构体和类具有不同的默认访问控制属性:在类中,对于未指定访问控制属性的成员,其访问控制属性为私有类型(private);在结构体中,对于未指定任何访问控制属性的成员,其访问控制属性为公有类型(public)。因此,在结构体定义中,如果把公有成员放在最前面,则最前面的“public:”可以省去,结构体可以按照如下语法定义:

struct 结构体名称
{公有成员
protected:保护型成员
private:私有成员
};

虽然结构体和类的功能完全相同,只是在形式上有细微的差异,但是为了保持和C程序的兼容性,C++还要引入结构体。
C语言只有结构体,而没有类,C语言结构体中只允许定义数据成员,不允许定义函数成员,而且C语言没有访问控制属性的概念,结构体的全部成员是公有的。C语言的结构体是为面向过程的程序服务的,并不能满足面向对象程序设计的要求,因此C++为C语言的结构体引入了成员函数、访问权限控制、继承、包含多态等面向对象特性。但由于用structure一词来表示这种具有面向对象特性的抽象数据类型不再贴切,另外C语言中struct所留下的根深蒂固的影响,C++在struct之外引入了另外的关键字——class,并且把它作为定义抽象数据类型的首选关键字。但为了保持和C程序的兼容性,C++保留了struct关键字,并规定结构体的默认访问控制权限为公有类型。
类和结构体并存,在编写C++程序时,是否还需要使用结构体是一个代码风格的问题,如果完全不使用结构体也丝毫不会影响程序的表达能力。
与类不同,对于结构体,人们习惯将数据成员设置为公共的。有时在程序中需要定义一些数据类型,它们并没有声明操作,定义它们的目的只是将一些不同类型的数据组合成一个整体,从而方便地保村数据,这样的类型不妨定义为结构体。如果用类来定义,为了遵循“将数据成员设置为私有”的习惯,需要为每个数据成员编写专门的函数成员来读取和改写各个属性,反而比较麻烦。
如果一个结构体的全部数据成员都是公共的,并且没有用户定义的构造函数,没有基类和虚函数,这个结构体的变量可以用下面的语法形式赋初值:

类型名 变量名={成员数据1初值,成员数据2初值,...}

在语言规则上,满足以上条件的类对象也可以用同样的方式赋初值,不过由于习惯将类的数据成员设置为私有的,因此类一般不满足以上条件。通过以上形式为结构体变量初始化,是使用结构体的另一个方便之处。
【例】用结构体表示学生信息

#include<iostream>
using namespace std;
struct Student //学生信息结构体
{int num;//学号string name;//姓名,字符串对象char sex;//性别int age;//年龄
};int main()
{Student stu = { 1001,"张三",'M',23 };cout << "Num:" << stu.num << endl;cout << "Name:" << stu.name << endl;cout << "Sex:" << stu.sex << endl;cout << "Age:" << stu.age << endl;return 0;
}

运行结果:
在这里插入图片描述
本程序中,Student结构体中有的成员是string类型的,string是标准C++中预定义的一个类,专用于存放字符串。

1.联合体

有时,一组数据中任何两个数据不会同时有效。例如,如果需要存储一个学生的各门课程的成绩,有些课程是等级制的,需要用一个字符来存储它的等级,有些课程只记“通过”和“不通过”,需要用一个布尔值来表示是否通过,而另一些课程的成绩是百分制的,需要用一个整数来存储它的分数,这个课程的成绩就可以用一个联合体来表示。
联合体是一种特殊形态的类,它可以有自己的数据成员和函数成员,可以有自己的构造函数和析构函数,可以控制访问权限。与结构体一样,联合体也是C语言继承而来的,因此它的默认访问控制权限也是公有类型的。**联合体的全部数据成员共享同一组内存单元。**联合体定义的语法形式如下:

union 联合体名称
{
公有成员
protected:保护型成员
private:私有成员
};

例如,成绩这个联合体可以声明如下:

union Mark
{char grade;//等级制的成绩bool pass;//只记是否通过的成绩int percent;//百分制成绩
};

联合体Mark的类型变量的存储结构如下图所示:
在这里插入图片描述
正是由于联合体的成员共用相同的内存单元,联合体变量中的成员同时至多只有一个是有意义的。另外,不同数据单元共用相同内存单元的特性,联合体有下面一些限制:
(1)联合体的各个对象成员,不能有自定义的构造函数、自定义的析构函数和重载的拷贝赋值运算符,不仅联合体的对象成员不能有这些函数,这些对象成员的对象成员也不能有。
(2)联合体不能继承,因而也不支持包含多态。
一般只用联合体来存储一些公有数据,而不为它定义函数成员。
联合体可以不声明名称,称为无名联合体。无名联合体没有标记名,只是声明一个成员项的集合,这些成员项具有相同的内存地址,可以由成员项的名字直接访问。
例如,声明无名联合体如下:

union
{int i;float f;
};

在程序中可以这样使用:

i=10;
f=2.2;

无名联合体通常用作类或结构体的内嵌成员
【例】使用联合体保存成绩信息,并且输出

class ExamInfo
{
public:
//3种构造函数,分别用等级、是否通过和百分制来初始化ExamInfo(string name, char grade) :m_name(name), mode(GRADE), m_grade(grade) {}ExamInfo(string name,bool pass):m_name(name), mode(PASS),m_pass(pass){}ExamInfo(string name, int percent):m_name(name), mode(PERCENTAGE),m_percent(percent){}void Show();
private:string m_name;  //课程名称enum{GRADE,PASS,PERCENTAGE}mode;   //采用哪种计分方式union{char m_grade;  //等级制的成绩bool m_pass;   //是否通过int m_percent;   //百分制的成绩};
};
void ExamInfo::Show()
{cout << m_name << ":";switch (mode){case GRADE:cout << m_grade;break;case PASS:cout << (m_pass ? "Pass" : "Fall");break;case PERCENTAGE:cout << m_percent;break;}cout << endl;
}
int main()
{ExamInfo c1("English", 'B');ExamInfo c2("Chinese", true);ExamInfo c3("C++程序设计", 85);c1.Show();c2.Show();c3.Show();return 0;
}

运行结果:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

excel英语翻译让你的数据更容易被理解

从前有一个名叫小明的办公室职员&#xff0c;他每天都要处理大量的数据和报表。然而&#xff0c;由于工作需要&#xff0c;他经常收到来自不同国家的Excel表格&#xff0c;这些表格上的内容都是用各种各样的语言编写的&#xff0c;让他很难理解其中的意思。这时&#xff0c;小明…

Redis主从复制、哨兵、cluster集群原理+实验

目录 一、Redis 主从复制 1、主从复制的作用 2、主从复制流程 3、搭建Redis 主从复制 安装Redis&#xff08;所有主机) 修改Master节点Redis配置文件 修改Slave节点Redis配置文件 验证主从效果 一、Redis 主从复制 主从复制&#xff0c;是指将一台Redis服务器的数据&am…

项目中使用过的线程池ThreadPoolTaskExecutor

创建线程池的实例应用 package com.youming.shuiku.datacenter.provider.utils;import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.ThreadPoolExecutor;Slf4j public class AsyncMana…

小研究 - JVM 垃圾回收方式性能研究(三)

本文从几种JVM垃圾回收方式及原理出发&#xff0c;研究了在 SPEC jbb2015基准测试中不同垃圾回收方式对于JVM 性能的影响&#xff0c;并通过最终测试数据对比&#xff0c;给出了不同应用场景下如何选择垃圾回收策略的方法。 目录 4 垃圾回收器性能比较 4.1 测试结果 5 结语 …

前端视频播放技术概览

转眼间&#xff0c;2023 年已进入下半场&#xff0c;在这样一个时间节点下&#xff0c;长视频平台如爱奇艺、优酷、腾讯视频等&#xff0c;以及短视频平台如抖音、快手等&#xff0c;对大家来说早已是司空见惯的事物。然而&#xff0c;在我们追剧、刷弹幕的时候&#xff0c;很少…

Docker Hub和镜像仓库

目录 前言 创建存储库 推送镜像&#xff08;可选&#xff09; 搜索镜像 拉取镜像 前言 Docker Hub 是 Docker 公司提供的官方公共 Docker 镜像注册表&#xff0c;允许用户存储、分享和获取 Docker 镜像。在 Docker Hub 上&#xff0c;你可以找到许多官方和社区维护的 D…

纯CSS实现手风琴效果(常用样式)

【效果图】&#xff1a; 【html代码】&#xff1a; <div class"rowd"><ul class"fold_wrap"><li><a href"#"><div class"pic_auto pic_auto1 trans"></div><div class"adv_intro flex&…

代码随想录算法训练营第34天| 1005.K次取反后最大化的数组和 134. 加油站 135. 分发糖果

今日学习的文章链接&#xff0c;或者视频链接 第八章 贪心算法 part03 自己看到题目的第一想法 看完代码随想录之后的想法 1005: class Solution { public:static bool cmp(int a, int b) {return abs(a) > abs(b);}int largestSumAfterKNegations(vector<int>&…
推荐文章