有时候,当遇到一组数据具有不同的数据类型,比如实现一个学生信息表,需要以人为单位,且每个人的内部信息由姓名、学号、年级、住址等不同类型数据组成。这时候如果用单类型的变量进行罗列就会不太方便,于是我们使用结构体(struct)来实现。它可以将若干个不同的数据类型的变量或数组封装在一起,以储存自定义的数据结构,方便储存一些复合数据。
结构体的定义:
基本结构有两种:
1.
struct Name { //一些基本的数据结构或者自定义的数据类型 成员表; //可以有多个成员 成员函数; //可以有多个成员函数,也可以没有 }结构体变量表; //可以同时定义多个,用“,”隔开
eg:
struct studentInfo { int id; char name[20]; char major[20]; }Tom, Jerry, stu[1000]; //两个结构体变量与一个结构体数组
2.
struct Name { //一些基本的数据结构或者自定义的数据类型 成员表; 成员函数; }; Name 结构体变量名;
eg:
struct node { int x, y; string name; }; node a[105];
【注:①结构体变量名和结构体名不能相同。②在定义结构体时,系统对其不分配实际内存,只有在定义结构体变量时,系统才为其分配内存。③结构体里面,能定义除了自己本身以外的任何数据类型(可以定义自身类型的指针变量)】
结构体变量的特点:
1.可整体操作
eg:
swap(a[i], a[i+1]); //结构体变量里面的所有变量都进行交换
2.访问结构体内的元素很方便
两种访问方法:
①“.”操作;【成员运算符“.”在存取成员数值时使用其优先级最高,并且具有左结合性】
【调用结构体成员函数时也进行“.”操作。注:结构体成员函数默认将结构体变量作为应用参数】
eg:
struct studentInfo { int id; char name[20]; studentInfo* next; //用来指向下一个学生的地址 }Tom, *p; //访问Tom中的元素 Tom.id; Tom.name; Tom.next;
【注意一下访问指针变量中元素的操作】
//访问指针变量p中元素 (*p).id; (*p).name; (*p).next;
②“->”操作
【便于访问结构体内指针变量中元素】
p->id; p->name; p->next;
结构体变量中元素可以直接读入、赋值等
cin>>Tom.name; Tom.id=1819; int TomId=Tom.id;
3.结构体变量的初始化简单
可以进行赋值(逐一赋值,或与数组类似进行初始化);
Tom.id=1; Tom.name=Tom; studentInfo Tom={1, "Tom", 123};
也可以在读入时赋值。
结构体的构造函数:
【重点到!】
结构体内的变量很多时,用赋值进行初始化就很麻烦...所以,我们用构造函数来初始化结构体。
它定义在结构体中,函数名与结构体同名,且不需要写返回类型。
【构造函数可以有很多骚操作,但是不建议作死,按固定模板写就好...】
模板:
struct node { int ...; node(){} //在后面解释一下为啥要写这个 node(int ...) { } };
【解释:一般来说,对于一个普通定义的结构体,其内部都会生成一个默认的构造函数(但不可见),如:node(){}这样。因为这个构造函数的存在,才可以直接定义node类型的变量而不进行初始化。建议都写上这个默认生成的构造函数,计算机有时候可能无法识别。当然也可以进行其它操作。】
eg:
struct node { int x, y; node(){} node(int xx, int yy): x(xx), y(yy) {} //相当于{x=xx; y=yy;} }pt[10]; //调用node() int num=0; for(int i=1; i<=3; i++) { for(int j=i; i<=3; j++) { pt[num++]=node(i, j); //直接使用node() } } for(int i=0; i<num; i++) { cin>>pt[i].x>>pt[i].y; }
拓展:
【其实node(){}这一行代码也可以不为空(逐渐变态.jpg】
eg:
struct node { int n1, n2; int a[10]; node() { p1=2; memset(a, 0, sizeof(a)); } //当申请了一个结构体变量a,计算机就自动完成了a.p1=2的赋值以及结构体嵌套数组的清零操作 node(int n1, int n2) { p1=n1, p2=n2; } }a;
【应用:矩阵快速幂等】