例9-1. 输出平均分最高的学生信息
假设学生的基本信息包括学号、姓名、三门课程成绩以及个人平均成绩。输入n个学生的成绩信息,计算并输出平均分最高的学生信息
#include<stdio.h>
struct student{ /* 学生信息结构定义 */
int num; /* 学号 */
char name[10]; /* 姓名 */
int computer, english, math; /* 三门课程成绩 */
double average; /* 个人平均成绩 */
};
int main()
{
int i, n;
struct student max, stu;
printf("Enter n:");
scanf("%d", &n);
printf("Input the student's number, name and course scores:\n");
for(i=0; i<n; i++){
printf("No. %d", n);
scanf("%d%s%d%d%d", &stu.num, stu.name, &stu.computer, &stu.english, &stu.math);
stu.average=(stu.computer+stu.english+stu.math)/3.0;
if(i==0)
max=stu;
else if(stu.average>max.average)
max=stu;
}
printf("num:%d, name:%s, average:%.2f\n", max.num, max,name, max.average);
return 0;
}
结构,是C语言中一种构造数据类型,能够将有内存联系的不同类型数据统一成一个整体,使之相互关联
结构也是变量的集合,可按照对基本数据类型的操作方法单独使用其变量成员
结构与数组,都是构造类型,是多个变量的集体,但数组成员类型相同,结构成员类型不同
结构类型定义的一般形式为
{
类型名 结构成员名1;
类型名 结构成员名2;
......
类型名 结构成员名n;
};
struct point
{
double x;
double y;
};
在实际生活中,一个较大的实体可能由多个成员构成,而这些成员有可能又是由一些更小的成员构成,如下图中学生信息的构成:
struct address{
char city[20];
char street[20];
int code;
int zip;
};
struct nest_student{
int num;
char name[10];
struct address addr;
int computer, english, math;
double average;
}
struct student{
int num;
char name[10];
int computer, english, math;
double average;
};
struct student s1, s2;
struct student{
int num;
char name[10];
int computer, english, math;
double average;
}s1, s2;
struct{
int num;
char name[10];
int computer, english, math;
double average;
}s1, s2;
结构变量初始化:
struct student stu={101, "Zhang", 87, 78, 85};
1. 结构变量成员的引用
在C语言中,使用
stu.num=101;
strcpy(stu.name, "Wang");
nest_stu.addr.zip=310053;
2. 结构变量的整体赋值
赋值时,将赋值运算符右侧结构变量的每一个成员的值都赋值给左侧结构变量中相应的成员
struct student s1={101, "Zhang", 78, 87, 85}, s2;
s2=s1;
3. 结构变量作为函数参数或返回值
可以在函数间传递结构类型数据
结构变量作为函数参数
定义: double count_average(struct student s)
调用: stu.average=count_average(stu);
例9-2. 学生成绩排序
输入n(n<50)个学生的成绩信息,按照学生的个人平均成绩从高到低输出他们的信息
定义结构数组 struct student stus[50], temp;
#include<stdio.h>
struct student{ /* 定义学生信息结构 */
int num;
char name[10];
int computer, english, math;
double average;
};
int main()
{
int i, index, j, n;
struct student stus[50], temp; /* 定义结构数组 */
printf("Enter n:");
scanf("%d", &n);
for(i=0; i<n; i++){
printf("Input info of NO. %d\n", i+1);
printf("Number Name, computer, english, math:");
scanf("%d%s%d%d%d", &stus[i].num, stus[i].name, &stus[i].computer, &stus[i].english, &stus[i].math);
stus[i].average=(stus[i].computer+stus[i].english+stus[i].math)/3.0;
}
/* 给结构数组排序,采用选择排序法 */
for(i=0; i<n-1; i++){
index=1;
for(j=i+1; j<n; j++){
if(stus[j].average<stus[index].average)
index=j;
}
temp=stus[index];
stus[index]=stus[i];
stus[i]=temp;
}
/* 输出排序后的信息 */
printf("Num\tname\taverage\n");
for(i=0; i<n; i++)
printf("%d\t%s\t%.2f\n", stus[i].num, stus[i].name, stus[i].average);
return 0;
}
一个结构变量只能表示一个实体信息,如果有多个相同类型的实体,需要构建结构数组表示
结构数组是结构与数组的结合,与变通数组的不同之处在于,
结构数组的定义方法与结构变量类似:
struct student stus[50];
表示stus是一个结构数组,有50个数组元素,每个元素都是一个结构类型struct student的变量
结构数组的初始化与数组的初始化没有本质区别
struct student stus[50]={
{101, "Zhang", 78, 87, 85},
{201, "Wang", 83, 92, 79}
};
结构数组元素的成员引用,格式为:
使用方法与同类型变量完全相同
stus[i].num=101;
strcpy(stus[i].name, "Feng");
stus[i]=stus[k];
例9-3. 修改学生成绩
输入n(n<50)个学生的成绩信息,再输入一个学生的学号、课程以及成绩,在自定义函数中修改该学生指定课程的成绩
自定义函数: pos=update_score(stus, n, num, course, score);
#include<stdio.h>
struct student{
int num;
char name[20];
int computer, english, math;
double average;
};
int update_score(struct student *p, int n, int num, int course, int score)
{
int i, pos;
for(i=0; i<n; i++, p++)
if(p->num==num)
break;
if(i<n){
switch(course){
case 1:
p->computer=score; break;
case 2:
p->english=score; break;
case 3:
p->math=score; break;
}
pos=i;
}else{
pos=-1;
}
return pos;
}
int main()
{
int i, pos, n, num, course, score;
struct student stus[50]; /* 定义结构数组 */
/* 输入n个学生信息 */
printf("Input n: ");
scanf("%d", &n);
for(i = 0; i < n; i++){
printf("Input the info of No.%d:\n", i+1);
printf("number:");
scanf("%d", &stus[i].num);
printf("name:");
scanf("%s", stus[i].name);
printf("computer score:");
scanf("%d", &stus[i].computer);
printf("math score:");
scanf("%d", &stus[i].math);
printf("english score:");
scanf("%d", &stus[i].english);
}
/* 输入待修改学生信息 */
printf("Input the number of updated student: ");
scanf("%d", &num);
printf("Choice the course: 1.math 2.english 3.computer: ");
scanf("%d", &course);
printf("Input the new score: ");
scanf("%d", &score);
/*调用函数,修改学生成绩*/
pos = update_score(stus, n, num, course, score);
/*输出修改后的学生信息*/
if(pos == -1){
printf("Not found!\n");
}else{
printf("After update:\n");
printf("num\t computer\t english\t math\n");
printf("%d\t %d\t %d\t %d\n", students[pos].num, students[pos].computer, students[pos].english, students[pos].math);
}
return 0;
}
指针可以指向任何一种变量,而结构变量也是C语言中的一种合法变量,因此,指针也可以指向结构变量,这就是
struct student stu={101, "Zhang", 78, 87, 84};
struct student *p;
p=&stu;
(*p).num=101; /* 用*p访问结构成员 */
p->num=101; /* 用指向运算符"->"访问指针所指向的结构成员
当p指向结构变量Stu时,以下三条语句等效
将结构指针作为函数的参数,可以完成比基本类型指针更为复杂的操作
如自定义函数
int update_score(struct student *p, int n, int num, int course, int score);
在调用时
pos=update_score(stus, n, num, course, score);
stus就是struct student类型的数组
与结构变量作为函数参数相比,用结构指针作为函数参数的效率更高,而在此例中,也只能采用指针作为函数参数才能通过间接访问实现程序功能