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;
}