结构体(struct)的使用
结构体在很多场合中非常常用,可以将若干个不同的数据类型的变量或数组封装在一起,一存储自定义的数据结构,方便存储一些复合数据。
结构体的定义
定义一个结构体的基本格式如下
struct Name{
//一些基本的数据结构或者自定义的数据类型
}
例如,需要存储一个学生的学号、性别、姓名和专业,就可以这样定义:
struct studentInfo{
int id;
char gender;//'F'or'M'
char name[20];
char major[20];
}Alice,Bob,stu[1000];
其中studentInfo是结构体的名字,内部定义了id(学号)、gender(性别)、name(名字)和major(专业)。而大括号外定义了studentInfo型的Alice和Bob代表两个结构体变量;之后的stu[1000]就是当有很多学生时定义的一个结构体数组(如果不在此处定义变量或数组,则大括号外直接跟上分号)
结构体也可以按照基本数据类型那样定义
studentInfo Alice;
studentInfo stu[1000];
需要注意的是,结构体里面能定义除了自己本身(这样会引起循环定义的问题)之外的任何数据类型。不过虽然不能定义自己本身,但是可以定义自身类型的指针变量。例如:
struct node{
node n;//不能定义node型变量
node* next;//可以定义node*类型的指针变量
}
访问结构体内的元素
两种方法:“.”操作和“->”操作。现在把studentInfo类型定义成下面这样:
struct studentIfo{
int id;
char name[20];
studentInfo* next;
}stu, *p;
这样studentInfo中多了一个指针next来指向下一个学生的地址,且结构体变量中定义了普通类型变量stu和指针变量p。
于是访问stu中变量的写法如下:
stu.id
stu.name
stu.next
访问指针变量p中元素的写法如下:
(*p).id
(*p).name
(*p).next
另一种访问结构体指针变量内元素的更简洁的写法:
p->id
p->name
p->next
使用*或->访问结构体指针变量内元素的写法是完全等价的。
结构体的初始化
使用“构造函数”的方法来进行初始化。所谓构造函数就是用来初始化结构体的一种函数,它直接定义在结构体中。构造函数的一个特点就是它不需要写返回类型,且函数名与结构体名相同
一般对于一个普通定义的结构体,其内部会生成一个默认的构造函数(但是不可见)
struct studentInfo{
int id;
char gender;
//默认生成的构造函数
studentInfo(){}//没有返回类型,没有参数,没有函数体
};
那么,如果想要自己手动提供id和gender的初始化参数,要怎么做?需要提供初始化参数来对结构体内部的变量进行赋值
struct studentInfo{
int id;
char gender;
//把下面参数用以对结构体内部变量进行赋值
studentInfo(int _id, char _gender){
//赋值
id = _id;
gender = _gender;
}
}
其中 _ id和 _ gender都是变量名,只要不和已有变量名冲突就行。
构造函数也可以简化成一行
x struct studentInfo{
int id; char gender;
studentInfo(int _id, char _gender):id(_id), gender(_gender) {}
}
这样可以在需要时直接对结构体变量进行赋值了:
studentInfostu = studentIfo(10086, 'M')
注意:如果自己重新定义了构造函数,就不能不经初始化就定义结构体变量。为了既能不初始化就定义结构体变量,又能享受初始化带来的便捷。我们可以吧studentInfo(){}手动加上。这意味着,只要参数个数和类型不完全相同,就可以定义任意多个构造函数,以适应不同的初始化场合。实例:
struct studentIfo{
int id;
char gender;
//可以不初始化就定义结构体变量
studentInfo(){}
//只初始化gender
studentInfo(char _gender){
gender = _gender;
}
//同时初始化gender和id
studentIfo(int _id, char _gender){
id = _id;
char = _char;
}
};