1. 结构体的声明
1.1 结构体的基础知识
结构是一些值的集合,这些值被称为成员变量。结构的每个成员可以是不同类型的变量。
1.2 结构的声明
struct tag
{
member - list;
}variable-list;
例:描述一个人的信息:名字+电话+性别+身高
//声明的结构体类型struct peo
struct peo
{
char name[20];//名字
char tela[12];//电话
char sex[5];//性别
int high;//学号
}p1, p2;//分号不能丢
其中p1和p2是使用struct peo结构类型创建的两个变量,可以也就是p1和p2分别可以放一个人的信息。 但是因为p1和p2放在大括号的外面,所以p1和p2是两个全局的结构体变量。要想使其成为局部变量,我们可以使用下面这种方法创建结构体变量。
struct peo
{
char name[20];//名字
char tela[12];//电话
char sex[5];//性别
int high;//学号
};//分号不能丢
int main()
{
struct peo p1 = { 0 };//结构体变量的创建
return 0;
}
1.3 结构体成员的类型
结构的成员可以是标量、数组、指针,甚至是其他的结构体。
struct peo
{
char name[20];//数组
};
struct st
{
struct peo p;//其他结构体
int num;//标量
float* f = num;//指针
};
1.4 结构体变量的定义和初始化
根据上面那个例题,我们可以如下初始化:
#define<stdio.h>
struct peo
{
char name[20];//名字
char tela[12];//电话
char sex[5];//性别
int high;//学号
};//分号不能丢
int main()
{
struct peo p1 = { "暴龙战士","88888888888","男",250};//结构体变量的创建
return 0;
}
结构体成员包含结构体的结构体变量初始化:
我们需要再用一个{ }将结构体中包含的结构体初始化。
操作如下:
#define<stdio.h>
struct peo
{
char name[20];//名字
char tela[12];//年龄
char sex[5];//性别
int high;//学号
};//分号不能丢
struct st
{
struct peo p;
int num;
};
int main()
{
struct st s = { {"暴龙战士","88888888888","男",250},66 };
return 0;
}
初始化后我们可以按照以下的方法将其打印出来:
#define<stdio.h>
struct peo
{
char name[20];//名字
char tela[12];//年龄
char sex[5];//性别
int high;//学号
};//分号不能丢
struct st
{
struct peo p;
int num;
};
int main()
{
struct peo p1 = { "暴龙战士","88888888888","男",250};//结构体变量的创建
struct st s = { {"暴龙战士","88888888888","男",250},66 };
printf("%s %s %s %d \n",p1.name,p1.tela,p1.sex,p1.high );
printf("%s %s %s %d %d\n", s.p.name, s.p.tela, s.p.sex, s.p.high, s.num);
return 0;
}
也就是:结构体变量+.+成员变量。
2.结构体成员的访问
如果是结构体指针访问指向对象的成员:就用 结构体指针 -> 成员变量 的形式打印
如果是结构体变量访问成员:就用 结构体变量 . 成员变量 的形式打印
具体操作如下:
#define<stdio.h>
struct st
{
struct peo p;
int num;
};
void print1(struct peo* sp)
{
printf("%s %s %s %d \n", sp->name, sp->tela, sp->sex, sp->high);
//结构体指针 -> 成员变量
}
void print2(struct peo p)
{
printf("%s %s %s %d \n", p.name, p.tela, p.sex, p.high);
//结构体变量 . 成员变量
}
int main()
{
struct peo p1 = { "暴龙战士","88888888888","男",250};//结构体变量的创建
struct st s = { {"暴龙战士","88888888888","男",250},66 };
print1(&p1);
print2(p1);
return 0;
}
3.结构体传参
我们知道形参是实参的临时拷贝,如果使用结构体变量访问成员时形参就会将实参拷贝一份,这样就需要多开辟一块空间,就会结构体过大,参数压栈的系统开销比较大,从而导致性能的下降。
而使用结构体指针访问指向变量的成员时(如上述代码),我们只是将&p1(4个或8个字节)的地址传给sp而已。
结论:结构体传参的时候,要传结构体的地址。
4.结构体数组
使用结构体变量建立数据类型后,我们就可以利用这个数据类型创建数组,就比如创建整形数组就可以写为 int arr[ ],那么创建一个自己建立的数据类型的数组就可以写为:
声明的结构体类型名 + 数组名。
例如我们声明一个结构体类型struct my后,就可以在主函数写一个struct my类型的数组。如下:
struct my
{
int a;
char b;
int arr[5];
};
int main()
{
struct my brr[5];
}
例题1:
(1)定义一个结构体变量Birthday用来存放一个人的出生日期(年、月、日)。
(2)定义一个结构体变量Student 用来存放学生个人信息,包括姓名(10个字符),学号(长整型)、出生日期、身高、体重)
(3)定义一个结构体数组MyClass用来存放5个学生的信息
编写程序实现要求从键盘输入5个同学的信息,然后输出5个同学的信息。
#define<stdio.h>
struct Birthday
{
int year;
int month;
int day;
};
struct Student
{
char name[10];//名字
long int num;//学号
struct Birthday p;//出生日期
int hight;//身高
int weight;//体重
};
int main()
{
struct Student MyClass[5];
for (int i = 0; i < 5; i++)
{
printf("输入第%d个学生的信息:\n ", i + 1);
printf("名字:");
scanf("%s", &MyClass[i].name);
printf("学号:");
scanf("%ld", &MyClass[i].num);
printf("生日日期(年 月 日):");
scanf("%d %d %d", &MyClass[i].p.year, &MyClass[i].p.month, &MyClass[i].p.day);
printf("身高:");
scanf("%d", &MyClass[i].hight);
printf("体重:");
scanf("%d", &MyClass[i].weight);
}
printf("\n");
for (int j = 0; j < 5; j++)
{
printf("输出第%d个学生的信息:\n", j + 1);
printf("名字:");
printf("%s\n", MyClass[j].name);
printf("学号:");
printf("%ld\n", MyClass[j].num);
printf("生日日期(年 月 日):");
printf("%d %d %d\n", MyClass[j].p.year, MyClass[j].p.month, MyClass[j].p.day);
printf("身高:");
printf("%d\n", MyClass[j].hight);
printf("体重:");
printf("%d\n", MyClass[j].weight);
}
return 0;
}
例题2:
有5个学生,每个学生的数据包括学号、姓名、3门课的成绩。从键盘输入5个学生数据,要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程的成绩、平均分数)。 要求用一个input函数输入5个学生数据,用一个 average 函数求总平均分,用 max 函数找出最高分学生数据。总平均分和最高分的学生的数据都在主函数中输出。
#define<stdio.h>
#define n 5
struct stu
{
long int num;//学号
char name[10];//名字
int a;//科目一
int b;//科目二
int c;//科目三
};
void input(struct stu arr[n])
{
for (int i = 0; i < n; i++)
{
printf("输入第%d个学生的数据:\n", i + 1);
printf("输入学号:");
scanf("%ld", &arr[i].num);
printf("输入名字:");
scanf("%s", &arr[i].name);
printf("输入科目一:");
scanf("%d", &arr[i].a);
printf("输入科目二:");
scanf("%d", &arr[i].b);
printf("输入科目三:");
scanf("%d", &arr[i].c);
}
}
double average(struct stu arr[n])
{
double x = 0;
for (int i = 0; i < n; i++)
{
x += arr[i].a + arr[i].b + arr[i].c;
}
return x / (n * 3);
}
int max(struct stu arr[n])
{
int x = arr[0].a + arr[0].b + arr[0].c;
int y = 0;
for (int i = 1; i < n; i++)
{
if (x < arr[i].a + arr[i].b + arr[i].c)
{
x = arr[i].a + arr[i].b + arr[i].c;
y = i;
}
}
return y;
}
int main()
{
struct stu arr[n];
input(arr);
double avera = average(arr);
printf("总平均分:");
printf("%lf\n", avera);
int ma = max(arr);
printf("最高分的学生的数据:\n");
printf("学号:");
printf("%d\n", arr[ma].num);
printf("名字:");
printf("%s\n", arr[ma].name);
printf("科目一:");
printf("%d\n", arr[ma].a);
printf("科目二:");
printf("%d\n", arr[ma].b);
printf("科目三:");
printf("%d\n", arr[ma].c);
return 0;
}