### 结构体介绍
C语言里可以在一个存储区里记录多个相关的数字,这种存储区的类型叫结构体类型。
这种类型需要编写专门的语句创建出来。
结构体类型的存储区里包含多个子存储区,每个子存储区可以用来记录一个数字。
结构体中不同子存储区的类型可以不同,子存储区也可能是结构体类型的存储区。
结构体声明语句用来创建结构体类型数据。
结构体声明语句中需要使用struct关键字。
结构体声明语句里包含多个变量声明语句,这种变量叫做结构体的成员变量,每个成员变量代表一个子存储区。
#include <stdio.h>
int main(){
struct person{
int age;
float height;
char name[10];
}
return 0;
}
成员变量声明语句不会分配内存。
在C语言中结构体是不可以包含函数的。
结构体声明语句可以放在任何地方包括头文件里。
### 结构体变量
结构体类型可以用来声明变量,这种变量叫做结构体变量。
结构体变量被分配了内存,它们才可以用来记录数字。
声明结构体变量的时候需要把struct关键字和结构体名称一起作为类型名称使用。
#include <stdio.h>
struct person{
int age;
float height;
char name[10];
}
int main(){
struct person prsn; //结构体变量声明
return 0;
}
### typedef 关键字
typedef 关键字可以用来给一个数据类型起别名。
typedef通常会给结构体类型起别名,这个别名可以作为类型名称使用。
可以把结构体类型声明语句和起别名语句合并成一条语句。
#include <stdio.h>
typedef struct person{
int age;
float height;
char name[10];
} sperson;
int main(){
sperson prsn;
return 0;
}
这个时候可以省略结构体本身的名称。
#include <stdio.h>
typedef struct {
int age;
float height;
char name[10];
} sperson;
int main(){
sperson prsn;
return 0;
}
### 结构体变量的初始化
结构体变量也应该初始化。
结构体变量的初始化方法和数组初始化一样。
#include <stdio.h>
typedef struct person{
int age;
float height;
char name[10];
} sperson;
int main(){
sperson prsn = {18, 1.68f, "lanyulei"};
return 0;
}
结构体变量通常不会作为整体使用,一般一次通常只使用其中的某个子存储区。
可以采用如下写在表示结构体内部的某个子存储区:
prsn.age
其中prsn是结构体变量名称,age是成员变量名称
实例:
#include <stdio.h>
typedef struct person{
int age;
float height;
char name[10];
} sperson;
int main(){
sperson prsn = {18, 1.68f, "lanyulei"};
printf("age = %d\n", prsn.age);
printf("height = %g\n", prsn.height);
printf("name = %s\n", prsn.name);
return 0;
}
同类型的结构体变量之间可以直接赋值。
#include <stdio.h>
typedef struct person{
int age;
float height;
char name[10];
} sperson;
int main(){
sperson prsn2 = {0};
sperson prsn = {18, 1.68f, "lanyulei"};
prsn2 = prsn;
printf("age = %d\n", prsn2.age);
printf("height = %g\n", prsn2.height);
printf("name = %s\n", prsn2.name);
return 0;
}
### 结构体指针
结构体指针用来记录结构体存储区的地址。
当结构体指针和结构体存储区捆绑后就可以采用以下方法通过结构体指针表示结构体的子存储区。
p_person->age
其中p_person是一个结构体指针,age是一个成员变量的名称。
实例:
#include <stdio.h>
typedef struct person{
int age;
float height;
char name[10];
} sperson;
int main(){
sperson prsn = {18, 1.68f, "lanyulei"};
sperson *p_person = &prsn;
printf("age = %d\n", p_person->age);
printf("height = %g\n", p_person->height);
printf("name = %s\n", p_person->name);
return 0;
}
### 结构体类型的形式参数
可以使用结构体类型的形式参数,从调用函数向被调用函数传递结构体数据,但是这样做会浪费时间和空间。
直接传递结构体数据的例子:
#include <stdio.h>
typedef struct {
int row, col;
} pt;
void print(pt pt1){
printf("点的位置:(%d, %d)\n", pt1.row, pt1.col);
}
int main(){
pt pt1 = {0};
printf("请输入一个点的位置:");
scanf("%d%d", &(pt1.row), &(pt1.col));
print(pt1);
return 0;
}
为了避免这种浪费,可以使用结构体指针形式参数。
传递结构体指针形式参数的例子:
#include <stdio.h>
typedef struct {
int row, col;
} pt;
void print(const pt *pt1){
printf("点的位置:(%d, %d)\n", pt1->row, pt1->col);
}
int main(){
pt pt1 = {0};
printf("请输入一个点的位置:");
scanf("%d%d", &(pt1.row), &(pt1.col));
print(&pt1);
return 0;
}
声明结构体指针形式参数的时候,尽量使用const关键字。
可以把结构体存储区当返回值使用,这样可以把结构体数据从被调用函数传递给调用函数。
#include <stdio.h>
typedef struct {
int row, col;
} pt;
pt read(void){
pt pt1 = {0};
printf("请输入一个点的位置:");
scanf("%d%d", &(pt1.row), &(pt1.col));
return pt1;
}
int main(){
pt pt1 = read();
printf("点的位置: (%d, %d)\n", pt1.row, pt1.col);
return 0;
}
这个时候被调用函数需要提供一个结构体存储区用来存放返回值。
这种直接传递数据的方式,也会造成时间和空间的浪费。
使用结构体存储区可以避免这种情况,这个时候被调用函数需要提供一个结构体指针类型的存储来存放返回值。
#include <stdio.h>
typedef struct {
int row, col;
} pt;
pt *read(pt *pt1){
printf("请输入一个点的位置:");
scanf("%d%d", &(pt1->row), &(pt1->col));
return pt1;
}
int main(){
pt pt1 = {0}, *p_pt1 = NULL;
p_pt1 = read(&pt1);
printf("点的位置: (%d, %d)\n", pt1.row, pt1.col);
return 0;
}
不能把局部结构体存储区的地址作为返回值。