记录学生的名字(C-string),学号(整型或字符型),年龄(整型)和身高(浮点型)
- 普通的数组做不到对各种的数据的处理。
- “结构”可以满足我们的条件,称为自定义数据类型。
- 共用体可以看做一个特殊的结构,与结构不同的地方在于他允许的同一块区域保存不同类型的数据。将结构变量或共用体变量用指针联系起来,便形成了链表。
1.结构
在字面上看,结构看作变量,它可以具有不同的数据类型,集合到一个整体,这个整体就是结构。
例如:存储学生信息
可以定义一个student结构,编译器把它当做一个整体,或者一个类型,和int,double等一样,程序中可以声明student型的变量,该变量包括了一个学生的所以信息:名字,学号,年龄和身高。
好处:对信息的有效的存储和管理。
1.1如何定义一个结构
两个步骤:
一个结构的定义,
一个结构变量的声明
我们可以采用如下形式定义一个student型的结构。
struct student
{
char name[20];//定义一个字符数组name
int age;//定义一个整数age
float weight;//定义一个浮点数float
};
关键字struct表明这些代码是一个结构的定义,紧跟的student是这个类型(或名称)
同时方括号里面也定义student中各个成员名(姓名,年龄和体重)
一般形式的结构
struct 结构名称(或称标识)
{
存储数据列表(或成员变量列表)
};
不要忘了后面的分号“;”
1.2结构变量的声明和使用
在程序中,可以像声明普通的int型变量一样声明一个结构变量,如下所示:
struct student A;
该语句声明了一个student型的变量A,在声明结构变量时,关键词strut可以省略,而直接写成" student A;",结构类型student的用法就和int,long等基本类型名相同,这说明,结构定义了一个新类型。
- 结构类型和结构变量是两个不同的概念。
- 结构类型就像int,double等类型一样,是一种数据类型,编译器并不给他分配内存空间,只有声明了结构类型的变量时,才给该变量分配存储空间。
变量A是student型,可使用成员操作。来访问各个成员(内部存储的数据),例如
A.name,A.age,和A.weigh分别代表变量A中存储的姓名,年龄和体重的信息。
实际上可以将A.name看做普通的字符数组,A.age,和A.weigh分别看做普通int型和float型变量,通过“结构变量名.成员名”可以访问变量里的成员。
#include<iostream>
using namespace std;
struct student//定义一个结构student
{
char name[20];//字符串数组name表示名字
int age;//int型变量age,表示年龄
float weight;//float型变量weight,表示体重
};
int main()
{
student A;//可以像使用内置类型int一样使用student,创建结构变量A
cout << "请输入学生姓名:" << endl;
cin >> A.name;//通过访问A中成员name
cout << "请输入学生的年龄:" << endl;
cin >> A.age;
cout << "请输入学生的体重:" << endl;
cin >> A.weight;
cout << "姓名:" << A.name << endl;
cout << "年龄:" << A.age << endl;
cout << "体重:" << A.weight << endl;
}
请输入学生姓名:
Jack
请输入学生的年龄:
21
请输入学生的体重:
68
姓名:Jack
年龄:21
体重:68
小结:声明一个student型的变量A,并用用户通过键盘依次输入学生的姓名,年龄,和体重,由A.name,A.age和A.weight对变量A中的成员进行访问,最后对写入结果进行输出。
其实就是像自己做过学生信息表,上面要求写学生的姓名,年龄和体重。
image.png
改一下就成了A班学生信息表
image.png结构定义的位置
- 既可以放在 将student结构定义在main函数的外部(外部声明),
也可以将其定义在main函数内部的最前面(内部声明) - 总的来说,只要在使用“student A;”语句声明student型结构变量前完成student结构的定义即可。
- 在使用变量,结构以及后面要介绍的函数前,一定要“先声明,后使用”
- 其实,在定义结构的同时完成创建结构变量的工作,只需要把结构变量名放在结构定义结束花括号的后面即可;
strut student
{
char name[20];
int age;
float weigh;
}stu1,stu2;
5.1.3 结构变量的初始化
在声明结构变量的同时,可以进行变量的初始化。
student stu1 = {"Ronaldo",30,70.5} ;
或者student stu1 ={{'R','o','n','a','l','d','0','\0'},30,70.5};
其实可以将结构定义,变量声明和变量初始化放在一起来完成。
#include<iostream>
using namespace std;
int main()
{
struct computer//定义结构compute
{
char brand[20];//成员1:字符数组bang,表示品牌
float price;//成员2:float型变量price,表示价格
}com1={"Dell",5000};//结构定义的同时声明一个该型变量,并初始化。
cout << "电脑品牌:" << com1.brand << "价格:" << com1.price << endl;
return 0;
}
电脑品牌:Dell价格:5000
- C++允许使用匿名结构,我们可以定义一个没有类型名称的结构,方法是省略名称
但一定要在结构定义的同时声明至少一个结构变量,否则这种用法没有意义
struct
{
char brand[20];
float price;
}com1;
这样将创建一个名com1.brand和com1.price来访问其内部成员,但这个类型没有名称,因此无法在以后的程序中声明这种类型的变量。
5.1.4结构变量间是否可以互相赋值
除了可以字符串数组进行整体的输入输出外,C++一般不允许对数组进行整体的操作,必须通过元素遍历的方式实现对数组的整体操作,那么,结构变量间也可以允许相互赋值。
可以使用赋值操作符"="将一个结构变量B赋值给另一个结构变量A,这样结构变量A的每个成员都将别设置成结构变量B中相应成员的值,即使成员是数组类型也被不例外,这种赋值方式被成为成员赋值。
#include<iostream>
using namespace std;
struct computer//定义结构computer
{
char brand[20];
float price;
};
int main()
{
computer com1 = { "Apple",7000 };
computer com2 = { "Lenovo",8000 };
cout << "赋值前:电脑品牌:" << com1.brand << "电脑价格为:" << endl;
com1 = com2;
cout << "赋值后:电脑品牌:" << com1.brand << "电脑价格为:" << endl;
cout << "电脑品牌:" << com1.brand << "价格:" << com1.price << endl;
return 0;
}
赋值前:电脑品牌:Apple电脑价格为:
赋值后:电脑品牌:Lenovo电脑价格为:
电脑品牌:Lenovo价格:8000
5.1.5结构体变量的sizeof
- 一般说,结构体变量占据的内存大小是所以成员变量占据内存之和。
struct ExS1
{
char c1;
short s1;
int i1;
};
从字面上看,sizeof(ExzS1)的结果应该是1+2+4=7,但实际上,返回结果为8,这牵扯字节对齐机制。
字节对齐的细节和编译器实现相关,一般而言有3个准则;
(1)结构体变量的首地址能够被期最宽基本类型成员的大小所整除;
(2)结构体每个成员相对于结构首地址的偏移量量(offset)都是成员大小的整数倍(游戏一个物品的内存地址找到其他的地址也在附近),如有需要编译器会在成员之间加上填充字节。
(3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(Trailing Padding)
字节对齐有助于加快计算机的取数速度,节省指令时间
(还有一部分我没有看)
网友评论