编程语言
首页 > 编程语言> > C++ 炼气期之结构体

C++ 炼气期之结构体

作者:互联网

1. 前言

随着计算机向着不同领域的延伸,数据的概念已经不仅局限于数值型数据,计算机需要处理大量的非数值、且复杂的类型数据。

为了能抽象地描述这些非数值、复杂类型的数据,C++引入了复合数据类型的概念。

C++数据类型分基本(原生)数据类型复合数据类型结构体就是一种复合数据类型。可认为复合数据类型是通过组合基本数据类型得到的一种新类型新类型用来描述问题域中的特定数据

本文所用到的成员一词指的是组成复合数据类型中的某一个子类型。

2. 结构体

现有一个开发学生管理系统的需求,系统需要一个学生信息管理模块,包含添加删除更新……学生信息功能。解决这个问题之前,则需要考虑如何存储学生的个人信息以及一个学校的所有学生信息。

学生的个人信息包含学生的年龄性别成绩……

如果仅存储一个学生信息,这个问题很好解决,定义 3 个变量即可。

如果需要存储全校学生信息,可以考虑使用数组,因受限于数组只能存储同类型数据的特点。为了完成这个需求,则需要 3 个数组,一个用来存储年龄、一个用来存储性别一个用来存储成绩。显然,在编码时,需要随时随地同步 3 个数组,稍有不慎,便会出现错误。

此时,可能会有一个想法,能不能创建一个学生类型,然后存储在数组中,数组中不再存储基本数据类型,而是一种新的学生类型,如同二维数组一样,一维数组中存储一维数组,且不是一件很开心的事情 。

于是诞生出了一种设计理念:复合基本类型,设计出一种新的数据类型。

复合的方式有很多种,结构体仅是其中之一。

2.1 结构体语法

//学生结构体:复合了 3 种基本数据类型
struct Student{
    //学生年龄
	int age;
    //学生性别
	char sex;
    //学生成绩
	float score;
}; 

结构体是一种数据类型,使用语法和基本类型一样。

数据类型名  变量名;

一旦在语法上承认了这种数据类型,和其它类型的区别就在于编译器为之所分配的内存大小。

结构体数组类似。创建数组结构体时,都是开辟了一个连续区域, 这个连续区域是多个变量的集合。数组这个连续区域只能保存类型相同的数据,结构体这个连续区域则可以存储不同类型的数据。

也就是说,在定义结构体之后,C++运行时系统为之分配的是一个连续区域。那么这个区域有多大?是不是由组成此结构体的子数据类型的大小之和?

下面来求证一下。

首先使用c++sizeof函数计算一下结构体的大小:

int main(int argc, char** argv) {
    //创建结构体类型变量
	Student stu;
    //计算结构体的大小
    int size= sizeof(stu);
	cout<<size<<endl;	
	return 0;
}

输出结果:12。也就是说在使用此结构体时,运行时系统分配的空间是12

Student结构体由一个int、一个char、一个float复合而成。理论上所需要的存储空间大小应该是4+1+4=9

int是 4 字节

char 是 1 字节

float 是 4 字节

通过对比,可以推翻前面的结论:运行时系统为结构体所分配的内存空间大小并不一定是构建这个结构体的所有子数据类型的大小之和。

原因何在?

这是因为内存对齐的缘故,内存对齐并不是本文的主题。这里只粗略说一下,运行时为结构体分配内存时,并不是我们所想象地简单地按顺序依次分配,实际上是为了提高内存的访问速度,以首地址为起始点,后续的内存空间地址尽可能是首地址的倍数。

1.png

如上图所示,在为char类型的变量分配空间时,为了保证访问float时的地址能被 4 整除,会为 char类型变量填充 3 个空字节,导致结构体最后被分配到的空间是 12

如下结构体类型:

struct Student {
	double age;
	char sex;
	double score;
};

在内存中占用 24个字节,原由和上述是一样的。

对结构体有了一个大致了解后,再看一下使用结构体的 2 种语法结构:

2 种语法结构的区别在于数据存储的位置有差异性。当然,从字面意思而言,动态创建更有灵活性,事实也是如此。

2.2 静态声明

静态声明的特点:数据存储在栈中,变量中保存的是结构体本身。

如下代码:

#include <iostream>
using namespace std;
//学生结构体
struct Student {
    //年龄
	double age;
    //性别
	char sex;
    //成绩
	double score;
};

int main(int argc, char** argv) {
    //静态声明
	Student stu;
	return 0;

标签:c++,对象模型,函数,static,编辑,参数,编写,系统,数据,管理系统
来源: