结构体
结构体是一种可以自定义的数据类型,可以用来存储一组有关联的数据。
比如,一个学生有学号、姓名和成绩等要素。如果我们想存储全年级所有同学的信息,我们需要定义一个string型数组存储学号,一个string型数组存储姓名,一个double型数组存储成绩。这样的处理方式非常麻烦,不仅要同时处理多个数组,还要保证每个数组下标对应正确的学生,可操作性不强。
我们发现,学号,姓名和成绩有关联(都属于同一个学生),所以可以考虑用结构体的方式储存学生信息。
结构体的定义
定义结构体有以下几种方法
struct Student
{
string name;
string number;
double grade;
};
struct Student stu1,stu2;//定义Student变量时必须使用struct关键字
struct Student
{
string name;
string number;
double grade;
} stu1,stu2;
可以用以上方式在定义结构体的时候就定义好试stu1,stu2两个变量。
struct
{
string name;
string number;
double grade;
} stu1,stu2;
这种方式只能在定义结构体时设置stu1,stu2两个变量。
在结构体中,可以存在多种不同的数据类型,可以有基本类型(int,float,char等),可以是不同类型的数组,也可以是指针类型。
但是,在C++中,结构体绝对不能嵌套定义。
struct Student
{
string name;
string number;
double grade;
struct Student st1;
} stu1,stu2;
以上代码是绝对不允许的,原因了解一下即可:在定义数据类型Student时时,编译器不知道Student类型需要多大的内存空间,自然也不能知道st1需要多少内存。
struct Student
{
string name;
string number;
double grade;
struct Student* st1;
} stu1,stu2;
但是如果将st1设为Student* 类型是可以的,因为指针类型的长度是已知的(一般与long int类型相同)。这也是C++实现链表的基础。
typedef关键字
typedef关键字可以给任意一种数据类型起一个别名。
比如,有的人不喜欢把整型数据叫int,但是在C++中,不使用int关键字就无法定义一个整型数据。这时,就可以使用typedef关键字。
typedef int INT;//给int起一个别名INT
INT a = 5;//a也是整型变量
结构体是一种自定义的数据类型,自然也能用typedef关键字命名。
typedef struct Student
{
string name;
string number;
double grade;
} STU s;//同时定义了一个变量s
STU stu1,stu2;//使用typedef后,定义变量时就不用struct关键字了
结构体的用法
结构体是一种自定义的数据类型,其本质与其他数据类型(如int,double)相同。所以,其他数据类型能做的事,结构体都可以完成。
- 结构体与其他类型一样可以定义变量
- 结构体也有对应的指针类型
- 结构体也可以用sizeof运算符计算内存
用变量和指针访问结构体内部数据的方式是不同的
变量通过 . 运算符访问,指针通过 ->运算符访问
typedef struct Student
{
string name;
string number;
double grade;
} STU;
int main() {
STU stu1;
STU* stu2;
stu1.grade = 60;
stu2->grade = 100;
return 0;
}
与其他基本数据类型不同,结构体内可以定义函数,调用方法与上相同。
注意
结构体的内存大小不等于其中数据类型大小的加和。
typedef struct test
{
int a;
float b;
double c;
char d;
} T;
int main() {
cout<< sizeof(double) + sizeof(int) + sizeof(char) + sizeof(float)<<endl;
cout<< sizeof(T);
return 0;
}
/*结果为
17
24
*/
这是因为C++为了更快的找到要访问的元素引入了内存对齐机制(应该不会考吧,有点小复杂),感兴趣可以参考文章戳此
共同体
共同体也是一种自定义的数据类型,也可以使用typedef关键字起别名。
顾名思义,共同体是几个不同类型的变量共用了一段内存。
例如
union A{
int a;
double b;
};
union A的大小为8,与其中最长的变量double相同,大部分情况下可以认为共同体的内存大小与其中最长变量的大小相同,少部分情况下会涉及到内存对齐机制,具体使用时还是要使用sizeof计算一下。
共同体由于是共用了一段内存,所以其中只能保存一个变量(最后一次定义的变量)。
typedef struct test
{
int a;
double b;
} T;
union A{
int a;
double b;
};
int main() {
union A a1;
cout<< sizeof(a1)<<endl;
a1.a=10;
cout<<a1.a<<endl;
cout<<a1.b <<endl;//由于最后一个定义的变量是a,所以共用体里只保存了a,此时输出的b就是随机的
return 0;
}
/*结果为:
8
10
2.05167e-307
*/
枚举类型
枚举类型可以理解为我们定义了一系列有关系的整数常量。以星期为例
enum Day{
MON,TUE,WED,THU,FRI
};
在枚举类型中,每一个元素都有自己对应的整数值,默认从0开始(MON=0),每次递增1,但是也可以自己定义。自定义一个值之后,其后的元素也是以递增1的方式赋值。
enum Day{
MON,TUE,WED=3,THU,FRI
};
int main() {
Day day = TUE;
cout<<day<<endl;
day = THU;
cout<<day<<endl;
return 0;
}
结果为:
1
4