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

C++ 结构体和联合体

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.lryc.cn/news/102567.html

相关文章:

  • 使用TensorFlow训练深度学习模型实战(下)
  • lucene、solr、es的区别以及应用场景
  • Java方法的使用(重点:形参和实参的关系、方法重载、递归)
  • 登录页的具体实现 (小兔鲜儿)【Vue3】
  • 大学如何自学嵌入式开发?
  • pytorch学习——线性神经网络——1线性回归
  • 00 - RAP 开发环境配置
  • 山西电力市场日前价格预测【2023-08-01】
  • QT--day5(网络聊天室、学生信息管理系统)
  • 【用IDEA基于Scala2.12.18开发Spark 3.4.1 项目】
  • HEVC 速率控制(码控)介绍
  • 四大软件测试策略的特点和区别(单元测试、集成测试、确认测试和系统测试)
  • ingress-nginx controller安装
  • 开源快速开发平台:做好数据管理,实现流程化办公!
  • 基于深度学习的裂纹图像分类研究(Matlab代码实现)
  • TypeScript入门学习汇总
  • Vue3使用vxetable进行表格的编辑、删除与新增
  • JUC 并发编程之JMM
  • k8s集群中安装kibana 7.x 踩坑
  • CSS的一些基础知识
  • 解决多线程环境下单例模式同时访问生成多个实例
  • 转转闲鱼交易猫源码搭建
  • 设计模式精华版汇总
  • uniapp实现带参数二维码
  • 金融行业软件测试面试题及其答案
  • 强化学习QLearning 进行迷宫游戏和代码
  • Vue2 第九节 过滤器
  • Swift 对象数组去重
  • 代码随想录算法训练营day52 300.递增子序列 674.最长连续递增子序列 718.最长重复子数组
  • Android 面试题 虚拟机、进程、线程 七