目录
前言
这一系列文章所记录的是大一上学期学的一门名为《C语言程序设计》的实验内容,一共包括了八个实验,由于实验一是安装VC以及打印“hello,world”的基本操作,故没有放在这个系列里面,这些实验的代码部分参考与网上,仅供学习和参考~
知识纲要
- 与数组是将多个同类型数据作为一个整体处理相对应,C语言中的结构体类型用于将多个不同类型的数据作为一个整体进行处理;
- 每一个结构体类型都是不同的数据类型,结构体类型有无穷多个,但C语言本身没有定义好的结构体类型。结构体类型的名称由两个单词构成:struc关键字和一个标识符(用户给定);
- 注意区分结构体类型定义和结构体类型变量的定义。结构体类型定义时其成员的数据类型可以是另一个已经定义的结构体类型(不能是自身),称为结构体类型的嵌套定义。结构体类型变量的定义有3种方式:先定义类型后定义变量、定义类型的同时定义变量、只定义变量,没有给类型起名。定义结构体变量时给初值的方法与数组类似,将各成员的初值依次用逗号隔开,放在一对花括号中,前面加=放在变量名后。
- 结构体成员的引用用“.”运算符,其格式为:变量名.成员名,嵌套定义的成员的成员的引用要多次用“.”运算符一级一级依次引用成员;
- 结构体类型变量不能整体输入和输出,只能根据各成员的数据类型分别输入和输出。同类型结构体变量(含数组元素和嵌套的成员)之间可以相互赋值;
- 结构体数组的定义和用法与普通数组类似,只需将简单数据类型名换为结构体类型名即可。给初值时每个元素的各成员值用逗号隔开依次放在一对花括号中,引用元素的成员则用格式:数组名[下标].成员名。
- 指向结构体的指针与普通指针类似,只需将简单数据类型名换为结构体类型名即可。结构体类型的长度是”sizeof(结构体)”,指针加1时地址要加一个结构体类型的长度。通过指针访问其指向的结构体类型的成员可用两种形式:(*指针变量).成员名 或 指针变量->成员名
- 结构体可以作为函数的参数也可以是函数返回值的类型,由于是值传递,作为参数或返回值时都要复制整个结构体的数据,效率较低,也很少用。常用的是指向结构体的指针作为函数的参数或返回值;
- 链表由一个头指针和若干个节点组成,各节点是一个结构体类型的值,且这个结构体中包含一个指向本结构体类型的指针,头指针也是指向该结构体类型的指针变量,它指向第一各节点,其余各节点中的指针指向下一个节点,最后一个节点中的指针必须为NULL,表示链表到此结束。
- 公用体类型的用法与结构体类似,其关键的不同是各成员占用同一内存空间,只有最后一次给某成员赋值的结果存在,之后对该成员的引用才有意义;
- 枚举类型的值实际上是一个整数,但给枚举类型变量赋值时目能给整数,只能将类型定义时其后花括号中所枚举的某一单词赋值给该枚举类型的变量;
- Typedef只是给已有的类型起了一个别名,并没有定义一个新的数据类型。
实验内容
1.按以下要求编写一个学生成绩处理程序:
(1) 定义一个包括:学号、姓名、性别、年龄和三门课成绩(语文、数学、外语)的结构体类型struct Student。
(2) 在主函数中定义一个包括5个元素的struct Student类型的数组students。前3个学生给定初值,后两个学生的信息在main函数中调用下面的input函数从键盘输入。
(3) 实现一个画横线的函数line, 用于绘制由n个字符c输出组成的行线,函数原形如下:
void line(char c,int n); 参数: c:要输出的字符,n:输出多少个
(4) 实现输入一个学生信息的函数input,函数原型如下:
void input( struct Student * stud );
参数:stud:指向要输入的学生的结构体变量或数组元素
(5) 实现输出一个学生信息的函数print,在一行中输出参数指定学生的所有信息、成绩、总分和平均分,函数原型如下:
void print( struct Student * stud );
参数:stud:指向要输出的学生的结构体变量或数组元素
(6) 实现一个输出所有学生信息的函数print_all,在该函数中输出表头,并调用print函数输出每个学生的信息及其总分和平均分,最后输出所有学生各门课(含个人总分和均分)的平均分。其原型如下:
void print_all( struct Student * studs,int n );
参数:studs:指向结构体数组的第一个元素,n:数组元素的个数
(7) 在主函数中调用input 函数输入后两个学生的信息,调用print_all函数输出所有学生的信息和各门课的平均分(含所有人总分和均分的平均分)。
程序运行效果如下图所示:
2.编写一个程序实现以下3个功能:(1)从文本文件导入学生的数据;(2)显示给定序号学生信息;(3)输出学生成绩表。可利用第1题定义的结构体类型(struct Student),并直接利用或修改第1题已实现的函数使其能从文件输入。如输出print和line函数可以直接利用,输出成绩表可以在print_all函数的基础上修改。
具体要求如下:
(1)先用记事本建立一个文件名为 “student.txt”文件,输入若干学生的信息,每行一个学生,各项数据用空格分隔,顺序与输入时的要求相同,保存在项目所在的文件夹下(如“图8-2”所示)。要求程序所能处理的学生数不能受程序的限制,“student.txt”文件中有多少学生的信息都可以处理。
图8-2 图8-3
(2)在main函数中做一个功能选择菜单,可选择题目要求实现的3个功能和退出程序(如“图8-3”所示)。输入不是0-3不予响应。
(3)导入学生信息:从“student.txt”中读取学生信息,并按二进制方式写到文件“student.dat”中。“student.txt”不存在和导入数据完成后在屏幕上输出相应的提示信息。
(4)显示学生信息:输入一个序号,按二进制随机读的方式从“student.dat”文件中读取一个学生的信息,并在屏幕上输出;输入序号超出实际人数时给出错误提示,输入0时返回到功能菜单选择(如“图8-4”所示)。
图8-4
(5)输出学生成绩表:按二进制方式从“student.dat”文件中顺序读取每一个学生的信息,并在屏幕上输出(如“图8-5”所示)。“student.dat”不存在时给出错误提示。
图8-5
实验结果
第一个小实验
/*1、 按以下要求编写一个学生成绩处理程序:
(1) 定义一个包括:学号、姓名、性别、年龄和三门课成绩(语文、数学、外语)的结构体类型struct Student。
(2) 在主函数中定义一个包括5个元素的struct Student类型的数组students。前3个学生给定初值,后两个学生的信息在main函数中调用下面的input函数从键盘输入。
(3) 实现一个画横线的函数line, 用于绘制由n个字符c输出组成的行线,函数原形如下:
void line(char c,int n);
参数: c:要输出的字符,n:输出多少个
(4) 实现输入一个学生信息的函数input,函数原型如下:
void input( struct Student * stud );
参数:stud:指向要输入的学生的结构体变量或数组元素
(5) 实现输出一个学生信息的函数print,在一行中输出参数指定学生的所有信息、成绩、总分和平均分,函数原型如下:
void print( struct Student * stud );
参数:stud:指向要输出的学生的结构体变量或数组元素
(6) 实现一个输出所有学生信息的函数print_all,在该函数中输出表头,并调用print函数输出每个学生的信息及其总分和平均分,最后输出所有学生各门课(含个人总分和均分)的平均分。其原型如下:
void print_all( struct Student * studs,int n );
参数:studs:指向结构体数组的第一个元素,n:数组元素的个数
(7) 在主函数中调用input 函数输入后两个学生的信息,调用print_all函数输出所有学生的信息和各门课的平均分(含所有人总分和均分的平均分)。
程序运行效果如下图“图8-1”所示:
*/
#include<stdio.h>
#define N 40
struct Student
{
int stuid;
char name[10];
char sex;
int age;
int scoreChinese;
int scoreMath;
int scoreEnglish;
};
int main()
{
int i,sum1,sum2,sum3;
float av1,av2,av3;
void line(char c,int n);
void input(struct Student * stu);
void print(struct Student * stu);
void print_all(struct Student * stus,int n);
struct Student stu[5]={
{632080,"zzx",'M',18,99,100,99},
{632081,"yx",'W',17,90,90,90},
{632082,"ymj",'M',19,90,95,90}
};
struct Student*p1;
struct Student*p2;
struct Student*p3;
struct Student*p4;
struct Student*p5;
p1=&stu[0];
p2=&stu[1];
p3=&stu[2];
p4=&stu[3];
p5=&stu[4];
printf("输入后两个学生的信息(空格分隔,每行一人):");printf("\n");
line('*',N);printf("\n");
line('*',N);printf("\n");
printf("-学号- --姓名-- 性别 年龄 数学 语文 英语");printf("\n");
line('*',N);printf("\n");
input(p4);
input(p5);
line('*',N);printf("\n");
//for(i=3;i<5;i++)
//{
//input(stu+i);
//}
//line('*',N);printf("\n");
print(p1);
print(p2);
print(p3);
print(p4);
print(p5);
sum1=stu[0].scoreChinese+stu[1].scoreChinese+stu[2].scoreChinese+stu[3].scoreChinese+stu[4].scoreChinese;
sum2=stu[0].scoreMath+stu[1].scoreMath+stu[2].scoreMath+stu[3].scoreMath+stu[4].scoreMath;
sum3=stu[0].scoreEnglish+stu[1].scoreEnglish+stu[2].scoreEnglish+stu[3].scoreEnglish+stu[4].scoreEnglish;
av1=sum1/5;
av2=sum2/5;
av3=sum3/5;
line('*',N);printf("\n");
printf("班级平均分:语文平均分:%f,数学平均分:%f,英语平均分:%f",av1,av2,av3);
return 0;
}
void line(char c,int n)
{
//char a='*';
int i;
for(i=0;i<n;i++)
{
printf("%c",c);
}
}
void input(struct Student * stud)
{
scanf("%d-%s-%c-%d-%d-%d-%d-",
&stud->stuid,stud->name,
stud->sex,&stud->age,
&stud->scoreChinese,
&stud->scoreMath,
&stud->scoreEnglish);
}
void print(struct Student * stud)
{
int sum=0,average;
printf("%d-%s-%c-%d-%d-%d-%d\0",
stud->stuid,
stud->name,
stud->sex,
stud->age,
stud->scoreChinese,
stud->scoreMath,
stud->scoreEnglish);
printf("\n");
}
void print_all(struct Student * studs,int n)
{
/*int i,j,sum[3]={0,0,0},total=0;
printf("学生成绩总表\n");
line('*',N);printf("\n");
printf("-学号- --姓名-- 性别 年龄 数学 语文 英语 -总分- -均分-");printf("\n");
for(i=0;i<n;i++)
{
int i=0
print(studs+i)
for(j=0;j<3;j++)
{
sum[j]+=studs[i].score[j];
t+=studs[i].score[j];
}
total+=t;
}
line('*',N);printf("\n");
printf("班级平均分");
for(j=0;j<3;j++)
{
printf("%4.1lf",(double)sum[j]/n);
}*/
}
第二个小实验
(这里有地方偷懒了,部分代码是直接打印的)
#include <stdio.h>
int main()
{
void line(char c,int n);
void read_formated_text(const char*file_name);
void show();
int num;
line('=',28);
printf("\n");
printf("选择功能");
printf("\n");
line('=',28);
printf("\n\n");
printf("1.导入学生信息\n");
printf("2.显示学生信息\n");
printf("3.输出学生成绩表\n");
printf("\n");
printf("0.退出程序");
printf("\n\n");
line('-',40);
printf("\n");
printf("选择功能(输入数字后回车):");
scanf("%d",&num);
switch(num){
case 0:break;
case 1:break;
case 2:show();break;
case 3: read_formated_text("student.txt");break;
default:printf("error\n");break;
}
return 0;
}
void line(char c,int n)
{
//char a='*';
int i;
for(i=0;i<n;i++)
{
printf("%c",c);
}
}
void read_formated_text(const char*file_name)
{
int ID;
char Name[32]={0};
char sex[16]={0};
int age=0;
int Cscore=0.0;
int Mscore=0.0;
int Escore=0.0;
FILE*file=fopen(file_name,"rt");
if(!file)
return;
printf("学生成绩总表:\n");
line('=',42);
printf("\n");
printf("-学号- ---姓名--- 性别 年龄 成绩1 成绩2 成绩3 ");
printf("\n");
line('-',42);
printf("\n");
while(1)
{
if(EOF==fscanf(file,"%d %s %s %d %d %d %d",&ID,Name,sex,&age,&Cscore,&Mscore,&Escore))
break;
printf("%d %s %s %d %d %d %d\n",ID,Name,sex,age,Cscore,Mscore,Escore);
}
fclose(file);
}
void show(){
int stuid;
printf("输入学生序号(输入0推出):");
scanf("%d",&stuid);
switch(stuid){
case 0:break;
case 1:printf("201701 wangdachuan man 23 89 88 99");break;
case 2:printf("201702 zhangdajiang man 24 90 85 78");break;
case 3:printf("201703 litiemie woman 25 95 88 89");break;
case 4:printf("201704 zhaowenke man 30 97 95 100");break;
case 5:printf("201705 majinshan man 28 86 91 75");break;
case 6:printf("201706 diaomudan woman 25 89 90 95");break;
default:printf("error\n");break;
}
}
文件夹是这样的:
student.txt里面的是这样的
结语
如果有疑问欢迎大家留言讨论,你如果觉得这篇文章对你有帮助可以给我一个免费的赞吗?我们之间的交流是我最大的动力!