c博客06-2019-结构体&文件
1.本章学习总结
1.1 学习内容总结
-
结构体的定义和赋值
结构体的一般形式为
struct 结构体名
{
数据类型 成员名1;
数据类型 成员名2;
:
数据类型 成员名n;
};
结构体的定义方式
1.先定义结构体类型再定义变量名
struct 结构体名
{
成员列表;
};
struct 结构体名 变量名;
2.在定义类型的同时定义变量
struct 结构体名
{
成员列表;
}变量名;
结构体成员的赋值方式
1.依次给每一个结构体成员变量进行赋值
struct A a;
a.b=1;
a.c=2;
2.使用已有的结构体变量给另一个结构体变量赋值(结构体变量之间是可以相互赋值)
struct A a={1,2};
struct A aa;
aa=a;
-
结构体数组排序
排序方法有冒泡排序、选择排序等
案例:学生结构体信息成绩排序——学生的记录由学号和成绩组成,N名学生的数据已放入主函数中的结构体数组s中。编写函数fun,按分数降序排列学生的记录,高分在前,低分在后。
方法:选择排序
-
结构体指针
指针引用结构体变量成员的方式
(*指针变量名).成员名
或
指针变量名->成员名
“->”是“指向结构体成员运算符”,它的优先级同结构体成员运算符“.”一样高。
p->num 的含义是:指针变量 p 所指向的结构体变量中的 num 成员。
p->num 最终代表的就是 num 这个成员中的内容。
-
共用体、枚举类型
共用体
1.概念 :
使几个不同的变量共占同一段内存的结构称为 “共用体”类型的结构。
union 共用体名
{
成员列表
}变量列表
union data
{
int i;
char ch;
}a,b,c;
结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。
共用体变量所占的内存长度等于最长的成员的长度。
枚举
1、定义
enum weekday{sun,mou,tue,wed,thu,fri,sat};
enum weekday a,b,c;
或
enum weekday{sun,mou,tue,wed,thu,fri,sat}a,b,c;
或
enum {sun,mou,tue,wed,thu,fri,sat}a,b,c;
类似与结构体的定义方式,关键字为enum
2、注意点
1)枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。
2)在C编译中,对枚举元素按常量处理,故称枚举常量。它们不是变量,不能对它们赋值。
-
文件读写,文件中数据读进结构体数组
一、文件读写
声明文件指针变量的形式为:
FILE *file;
1.打开文件
file = fopen("1.txt","r+");
fopen函数中有两个传入参数,第一个参数是文件的名称,第二个参数为打开文件的方式。
2.读写文件
1)字符的读写:fgetc()函数和fputc()函数
2)字符串的读写:fgets()函数和fputs()函数
3)数据块的读写:fread()函数和fwrite()函数
4)格式化读写:fscanf()函数和fprintf()函数
5)随机读写函数:fseek()、rewind()、ftell()
3.关闭文件
fclose(file);
二、文件中数据读进结构体数组
1.文件中存储的方式为二进制形式数据:
需要使用fread函数从文件中读取结构体数据到对应的结构体指针上。
struct test
{
int a;
};
struct test t;
fread(&t, 1,sizeof(t), fp);
2.文件中是以文本方式存储的可读的结构体数据:
需要根据文件中数据的存储格式,通过fscanf函数读取各个值到对应的结构体成员变量中。
struct test t;
fscanf(fp, "%d",&t。a);
1.2 本章学习体会
在实际问题中,一组数据往往具有不同的数据类型。例如,在学生登记表中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。显然不能用一个数组来存放这一组数据。因为数组中各元素的类型和长度都必须一致,以便于编译系统处理。为了解决这个问题,我们在C语言可以用到另一种构造数据类型——结构体。“结构体”是一种构造类型,它是由若干“成员”组成的。每一个成员可以是一个基本数据类型或者又是一个构造类型。结构既是一种“构造”而成的数据类型,那么在说明和使用之前必须先定义它,也就是构造它。如同在说明和调用函数之前要先定义函数一样。让编程序的人自定义一个数据类型有诸多好处,第一结构体可以在一个结构中声明不同的数据类型,第二相同结构的结构体变量是可以相互赋值的,而数组是做不到的,因为数组是单一数据类型的数据集合,它本身不是数据类型(而结构体是),数组名称是常量指针,所以不可以做为左值进行运算,所以数组之间就不能通过数组名称相互复制了,即使数据类型和数组大小完全相同。第三,节省内存空间。第四,高效率。文件作为一种独立存在的存储形式,在结合结构体的作用下,可以便捷地对文件内的数据进行调用和编改,极大改变了编程者调用数据的方式。所以在学习结构体和文件后,我对C语言的基本语法操作又又了进一步的了解和提升,在后续的数据结构学习中定能发挥极大的作用。
2.综合作业--“我爱成语”
2.1.文件介绍
头文件介绍
头文件.h
结构体:USER和IDIOM
USER:存储用户的账号密码、游戏分数以及指向下一级的同类型指针
IDIOM:存储成语的名称、意识和指向下一级的同类型指针
函数:
FILE* OpenUser(FILE* fp);打开存储用户信息的文件
FILE* OpenIdiom(FILE* fp);打开存储成语资料的文件
void CloseFile(FILE* fp);关闭文件
USER* UserLink(FILE* fpUser, int* UserNum);建立USER类型的数据链表
IDIOM* IdiomLink(FILE* fp, int* num);建立IDIOM类型的数据链表
USER* Authentication(USER* users, char* UserName);验证用户账号信息
int IdiomMenu();成语游戏菜单
int LoginScreen(FILE* fpUser, char* UserName);登陆界面
void Register(FILE* fpUser, char* UserName);新用户账号注册
int Login(FILE* fpUser, char* UserName);用户登录
void IdiomGame(IDIOM* idioms, USER* LoginUser, int IdiomNum);猜成语游戏程序
void AddIdiom(FILE* fp);添加新的成语信息
void IdiomsSolitaire();成语接龙游戏程序
2.函数实现文件介绍。
文件1:main.c
根据登录函数和游戏界面选择函数返回的值对下一部的操作进行选择。
调用if语句来控制登录是否成功及进入游戏界面,调用switch函数来根据游戏界面选择函数返回的整型值进行对应的游戏程序操作。
文件2:读取信息.c
包含打开\关闭文件函数、链表建立函数和用户身份信息验证函数
文件3:登录界面.c
包含登录界面选择函数、注册函数和登录验证函数
文件4:成语菜单.c
包含成语菜单界面选择函数
文件5:成语游戏.c
包含猜成语游戏函数和添加成语信息函数
2.2.运行结果
1.登录界面
2.游戏界面
2.3大作业总结
1.碰到问题及解决办法
问题:
出现多次断电或者输出成语意思为空白的情况
解决办法:
1.结合断电处及以上的程序分析产生断点的原因,有未初始化指针变量、数组下标越界等。
2.调整文件的格式,保证能够正常读取。
2.小结
虽然只有短短半学期的学习,只是学习到了一些皮毛,也使我意识到了写程序不单单意味这能够使代码能够跑出来,这更是一门艺术。一开始写类的时候真的很难,没有任何思路,只能模仿课本上的代码。因为这样造成了我们大部分人的代码都是雷同的。随着学习的不断深入,我也逐渐形成了自己的“模板”,代码也慢慢有了灵魂。我也多次看同学的代码发现虽然我们学的知识是一样的,但是我们各自的代码和思路确实千差万别。现在回头看看自己第一个程序,真的很有感慨,就能简单的代码就折磨自己好几天。这门课对我最大的影响并不是让我多掌握了多上知识,而是在我的脑子里留下的一幅图,一副怎样写代码的图。这幅图还很小,仅仅有了一些大体脉络,其他的细节就需要我自己以后的学习了。计算机的专业课教给我们不了太多的知识,只能将我们领进这个门,其他的真的需要自己去找,自己去学习。望与君共同进步。