链表实现:
stuMain.c//入口
/*/*
* stuMain.c
*
* Created on: 2014年10月2日
* Author: Administrator
*/
#include<stdio.h>
#include<stdlib.h>
#include"student.h"
#include"studentList.h"
void menu() {
puts("1-输入\t\t\t2-保存\n");
puts("3-总分\t\t\t4-平均分\n");
puts("5-排名\t\t\t6-查询\n");
puts("7-统计及格\t\t8-=输出\n");
puts("-1-退出\t\t\n");
}
int main(void) {
int order = 0;
SL stulist = NULL;
while (1) {
menu();
printf("%s", "输入命令:");
scanf("%d", &order);
switch (order) {
case 1: {
char file[50];
printf("输入文件名:");
scanf("%s",file);
stulist = list_create_file(file);
break;
}
case 2: {
char file_name[50];
printf("输入文件名:");
scanf("%s",file_name);
if ( NULL != list_save_txt( stulist, file_name )){
puts("保存成功!");
}
break;
}
case 3: {
break;
}
case 4: {
puts("输入");
break;
}
case 5: {
list_sort_avg( stulist );
break;
}
case 6: {
int id = 0;
Stu stu = stu_create(0," ",0,0,0);
printf("输入要查询的学生的学号:");
scanf("%d",&id);
id = list_search_id( stulist, id, stu );
printf("id = %d\n",id);
if( 1 == id ){
stu_print( stu );
}else if( 0 == id ){
puts("查人此人");
}else if( -1 == id ){
puts("查询失败");
}
break;
}
case 7: {
list_pass( stulist );
break;
}
case 8: {
list_print( stulist );
break;
}
case -1: {
puts("谢谢使用");
exit(-1);
break;
}
default:{
puts("未知的命令,请重新输入命令");
break;
}
}
}
return 0;
}
student.h//学生类型声明及操作声明
/*/**
* @file student.h
* 定义了保存学生信息的结构体\n
* 操作学生信息的函数:
*
*
*
* @author 小代码
*/
#ifndef STUDENT_H_
#define STUDENT_H_
#include<stdbool.h>
/**
* @brief 学生对象结构体定义
*/
struct student {
/** @brief 学号 */
int stu_id;
/** @brief 姓名*/
char stu_name[10];
/** @brief 数学成绩 */
double stu_score_math;
/** @brief 英语成绩 */
double stu_score_english;
/** @brief 计算机成绩 */
double stu_score_computer;
/** @brief 总成绩*/
double stu_score_sum;
/** @brief 平均成绩 */
double stu_score_avg;
/** @brief 排名 */
int stu_score_grade;
/** @brief 直接前驱元素指针 */
struct student * prev;
/** @brief 直接后继元素指针 */
struct student * next;
};
/** @brief 学生结构体 */
typedef struct student STU;
/** @brief 学生结构体指针 */
typedef struct student * Stu;
/**
* @brief 输出学生信息的标题
*/
void print_title();
/**
* @brief 创建一个学生信息对象
*
* @param stu_id 学号
* @param stu_name 姓名
* @param stu_score_math 数学成绩
* @param stu_score_english 英语成绩
* @param stu_score_computer 计算机成绩
*
* @return 指向学生对象结构体的指针
* @retval NULL 创建失败
*/
Stu stu_create(int stu_id, char stu_name[20], double stu_score_math,
double stu_score_english, double stu_score_computer);
/**
* @brief 输出一个学生的信息
*
* 输出格式为每项占10个空格\n
* 如果参数为空,则不输出任何内容
*
* @param stu 要输出信息的学生对象
*/
void stu_print(Stu stu);
/**
* @brief 比较两个学生的平均分
*
*
* @param stu1
* @param stu2
*
* @return 比较结果
* @retval 1 stu1->stu_score_avg > stu2->stu_score_avg
* @retval 0 stu1->stu_score_avg = stu2->stu_score_avg
* @retval -1 stu1->stu_score_avg < stu2->stu_score_avg
*/
int stu_score_compare(Stu stu1, Stu stu2);
/**
* @brief 交换两个学生对象的所有成员的值
*
* 交换成功则返回 0\n
* 如果有任何一个参数为 NULL ,则返回-1
*
* @param stu1
* @param stu2
*
* @retval 0 交换成功
* @retval -1 交换失败
*/
int stu_swap(Stu stu1, Stu stu2);
#endif /* STUDENT_H_ */
student.c//学生操作实现
/*
#include"student.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/**
* @brief 输出学生信息的标题
*/
void print_title() {
printf("%-10s", "学号");
printf("%-10s", "姓名");
printf("%-10s", "数学");
printf("%-10s", "英语");
printf("%-10s", "计算机");
printf("%-10s", "总分");
printf("%-10s", "平均分");
printf("%-10s\n", "排名");
}
/**
* @brief 创建一个学生信息对象
*
* @param stu_id 学号
* @param stu_name 姓名
* @param stu_score_math 数学成绩
* @param stu_score_english 英语成绩
* @param stu_score_computer 计算机成绩
*
* @return 指向学生对象结构体的指针
* @retval NULL 创建失败
*/
Stu stu_create(int stu_id, char stu_name[10], double stu_score_math,
double stu_score_english, double stu_score_computer) {
Stu stu = (Stu) malloc(sizeof(STU));
if ( NULL == stu) {
printf("stu_create...动态分配内存失败!");
exit(-1);
}
stu->stu_id = stu_id;
strcpy(stu->stu_name, stu_name);
stu->stu_score_math = stu_score_math;
stu->stu_score_english = stu_score_english;
stu->stu_score_computer = stu_score_computer;
stu->stu_score_sum = stu->stu_score_math + stu->stu_score_english
+ stu->stu_score_computer;
stu->stu_score_avg = stu->stu_score_sum / 3;
stu->stu_score_grade = -1;
stu->prev = NULL;
stu->next = NULL;
return stu;
}
/**
* @brief 输出一个学生的信息
*
* 输出格式为每项占10个空格\n
* 如果参数为空,则不输出任何内容
*
* @param stu 要输出信息的学生对象
*/
void stu_print(Stu stu) {
if ( NULL == stu) {
return;
}
printf("%-10d", stu->stu_id);
printf("%-10s", stu->stu_name);
printf("%-10.2f", stu->stu_score_math);
printf("%-10.2f", stu->stu_score_english);
printf("%-10.2f", stu->stu_score_computer);
printf("%-10.2f", stu->stu_score_sum);
printf("%-10.2f", stu->stu_score_avg);
printf("%-10d", stu->stu_score_grade);
putchar('\n');
}
/**
* @brief 比较两个学生的平均分
*
*
* @param stu1
* @param stu2
*
* @return 比较结果
* @retval 1 stu1->stu_score_avg > stu2->stu_score_avg
* @retval 0 stu1->stu_score_avg = stu2->stu_score_avg
* @retval -1 stu1->stu_score_avg < stu2->stu_score_avg
*/
int stu_score_compare(Stu stu1, Stu stu2) {
int result = 0;
if (stu1->stu_score_sum > stu2->stu_score_sum)
result = 1;
if (stu1->stu_score_sum < stu2->stu_score_sum)
result = -1;
return result;
}
/**
* @brief 交换两个学生对象的所有成员的值
*
* 交换成功则返回 0\n
* 如果有任何一个参数为 NULL ,则返回-1
*
* @param stu1
* @param stu2
*
* @retval 0 交换成功
* @retval -1 交换失败
*/
int stu_swap(Stu stu1, Stu stu2) {
if ( NULL == stu1 || NULL == stu2) {
return -1;
}
int id_tmp = stu1->stu_id;
stu1->stu_id = stu2->stu_id;
stu2->stu_id = id_tmp;
char name_tmp[10];
strcpy(name_tmp, stu1->stu_name);
strcpy(stu1->stu_name, stu2->stu_name);
strcpy(stu2->stu_name, name_tmp);
double score_tmp = stu1->stu_score_math;
stu1->stu_score_math = stu2->stu_score_math;
stu2->stu_score_math = score_tmp;
score_tmp = stu1->stu_score_english;
stu1->stu_score_english = stu2->stu_score_english;
stu2->stu_score_english = score_tmp;
score_tmp = stu1->stu_score_computer;
stu1->stu_score_computer = stu2->stu_score_computer;
stu2->stu_score_computer = score_tmp;
stu1->stu_score_sum = stu1->stu_score_math + stu1->stu_score_english
+ stu1->stu_score_computer;
stu1->stu_score_avg = stu1->stu_score_sum / 3;
stu2->stu_score_sum = stu2->stu_score_math + stu2->stu_score_english
+ stu2->stu_score_computer;
stu2->stu_score_avg = stu2->stu_score_sum / 3;
return 0;
}
studentList.h//链表声明及操作声明
/*/**
* @file
* 定义了学生列表结构体
*
* @author 小代码
*/
#ifndef STUDENTLIST_H_
#define STUDENTLIST_H_
#include"student.h"
#include<stdio.h>
#include<stdbool.h>
/**
* @brief 学生列表结构体定义
*
*/
struct _stu_list {
/** @brief 链表头指针 */
Stu head;
/** @brief 链表尾指针 */
Stu last;
};
/** @brief 学生链表 */
typedef struct _stu_list sl;
/** @brief 指向学生链表的指针 */
typedef struct _stu_list * SL;
/**
* @brief 创建一个初始化的链表
*
* @return 指向 _stu_list 的指针
* @retval NULL 创建失败
*/
SL list_init();
/**
* @brief 从文件创建一个学生列表
* @param file_name 含有学生信息的文本文件的文件名
* @return 返回学生列表
* @retval NULL 创建失败
*/
SL list_create_file( char * file_name );
/**
* @brief 销毁一个学生信息链表
*
* @param stu_list 要销毁的链表的指针
*/
void list_destroy(SL stu_list);
/**
* @brief 求学生信息链表的长度
*
* @param stu_list 要求长度的学生信息链表
*
* @return 学生信息链表 的长度
* @retval -1 参数为空
*
*/
int list_len( SL stu_list );
/**
* @brief 判断一个链表是否为空
*
* @param stu_list 要判断是否为空的链表
*
* @retval true 为空
* @retval false 不为空
*
*/
bool list_is_empty( SL stu_list );
/**
* @brief 在链表后追加一个元素
*
* @param stu_list 要追加元素的链表
* @param stu 要追加的元素
* @return 返回的元素的指针
* @retval NULL 追加失败
*/
Stu list_append(SL stu_list, Stu stu);
/**
* @brief 根据学生的学号删除一个学生的信息
* @param stu_list 保存学生信息的链表
* @param stu_id 要删除的学生的学号
* @return 返回被删除的学生
* @retval NULL 删除失败
*/
Stu list_delete ( SL stu_list, int stu_id );
/**
* @brief 输出一个链表的内容
* 如果链表为空或参数为NULl,则没有任何输出
*
* @param stu_list 要打印的链表
*/
void list_print( SL stu_list );
double list_score_sum(SL stu_list);
double list_score_avg(SL stu_list);
/**
* @brief 根据学生号查的一个学生对象
*
* @param stu_list 保存学生信息的链表
* @param stu_id 要查的的学生的学号
* @param stu 传出查询的学生
* @return 查找结果
* @retval -1 链表为空
* @retval 1 查询成功
* @retval 0 没有查到
*/
int list_search_id(SL stu_list, int stu_id, Stu stu);
/**
* @brief 排序链表
* 使用选择排序法
*
* @param stu_list 要排序的学生链表
*/
void list_sort_avg(SL stu_list);
/**
* @brief 把一个学生信息链表写入到当前目录中的一个TXT文本文件
* 默认文件名为:student.txt\n
* 根据排序的结果,从1开始对学生信息的 stu_score_grade 字段赋值
* @param stu_list 要写入到文件的学生链表
* @param file_name 械写入到的文件名
* @return 写入到文件中的链表的指针
*/
FILE * list_save_txt(SL stu_list, char * file_name );
/**
* @brief 列出平均分高于60的学生的信息
* @param stu_list 学生信息链表
* @return 分数高于60分的学生信息链表
* @note 返回一个链表的功能还未实现
*/
SL list_pass(SL stu_list);
#endif /* STUDENTLIST_H_ */
studentList.c//学生操作实现
#i#include"studentList.h"
#include"student.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/**
* @brief 创建一个初始化的链表
*
* @return 指向 _stu_list 的指针
* @retval NULL 创建失败
*/
SL list_init() {
SL stu_list = (SL) malloc(sizeof(sl));
if ( NULL == stu_list) {
printf("list_init..动态分配内存失败");
exit(-1);
}
stu_list->head = stu_create(0, " ", 0.0, 0.0, 0.0);
stu_list->last = stu_create(0, " ", 0.0, 0.0, 0.0);
stu_list->head->prev = NULL;
stu_list->head->next = stu_list->last;
stu_list->last->prev = stu_list->head;
stu_list->last->next = NULL;
return stu_list;
}
/**
* @brief 从文件创建一个学生列表
* @param file_name 含有学生信息的文本文件的文件名
* @return 返回学生列表
* @retval NULL 创建失败
*/
SL list_create_file( char * file_name ) {
FILE * stu_file = fopen(file_name,"r");
if ( NULL == stu_file) {
return NULL;
}
SL stu_list = list_init();
int stu_id = 0;
char stu_name[10];
double stu_math = 0.0;
double stu_english = 0.0;
double stu_computer = 0.0;
while ( EOF
!= fscanf(stu_file, "%d\t%s\t%lf\t%lf\t%lf", &stu_id,
stu_name, &stu_math, &stu_english,
&stu_computer)) {
Stu stu = stu_create(stu_id, stu_name, stu_math, stu_english,
stu_computer);
// stu_print( stu );
list_append(stu_list, stu);
}
return stu_list;
}
/**
* @brief 销毁一个学生信息链表
*
* @param stu_list 要销毁的链表的指针
*/
void list_destroy(SL stu_list) {
if ( NULL == stu_list) {
return;
}
if (list_is_empty(stu_list)) {
free(stu_list);
}
Stu tmp = stu_list->head->next;
while (tmp != stu_list->last) {
Stu f = tmp;
tmp->prev->next = tmp->next;
tmp->next->prev = tmp->prev;
tmp = f->next;
free(f);
}
free(stu_list);
}
/**
* @brief 求学生信息链表的长度
*
* @param stu_list 要求长度的学生信息链表
*
* @return 学生信息链表 的长度
* @retval -1 参数为空
*
*/
int list_len(SL stu_list) {
if ( NULL == stu_list) {
return -1;
}
int len = 0;
if (list_is_empty(stu_list)) {
len = 0;
}
Stu tmp = stu_list->head->next;
while (tmp != stu_list->last) {
len++;
tmp = tmp->next;
}
return len;
}
/**
* @brief 判断一个链表是否为空
*
* @param stu_list 要判断是否为空的链表
*
* @retval true 为空
* @retval false 不为空
*/
bool list_is_empty(SL stu_list) {
bool flags = false;
if (stu_list->head->next == stu_list->last) {
flags = true;
}
return flags;
}
/**
* @brief 在链表后追加一个元素
*
* @param stu_list 要追加元素的链表
* @param stu 要追加的元素
* @return 返回的元素的指针
* @retval NULL 追加失败
*/
Stu list_append(SL stu_list, Stu stu) {
if ( NULL == stu) {
return NULL;
}
stu_list->last->prev->next = stu;
stu->prev = stu_list->last->prev;
stu->next = stu_list->last;
stu_list->last->prev = stu;
return stu;
}
/**
* @brief 根据学生的学号删除一个学生的信息
* @param stu_list 保存学生信息的链表
* @param stu_id 要删除的学生的学号
* @return 返回被删除的学生
* @retval NULL 删除失败
*/
Stu list_delete(SL stu_list, int stu_id) {
if ( NULL == stu_list) {
return NULL;
}
int len = list_len(stu_list);
if (len < 0) {
return NULL;
}
Stu stu = NULL;
list_search_id(stu_list,stu_id, stu );
stu->next->prev = stu->prev;
stu->prev->next = stu->next;
free(stu);
return NULL;
}
/**
* @brief 输出一个链表的内容
* 如果链表为空或参数为NULl,则没有任何输出
*
* @param stu_list 要打印的链表
*/
void list_print(SL stu_list) {
if (list_is_empty(stu_list)) {
return;
}
print_title();
Stu tmp = stu_list->head->next;
while (tmp != stu_list->last) {
stu_print(tmp);
tmp = tmp->next;
}
}
double list_score_sum(SL stu_list) {
double sum = 0.0;
Stu tmp = stu_list->head->next;
while (tmp != stu_list->last) {
sum += tmp->stu_score_math + tmp->stu_score_english
+ tmp->stu_score_computer;
tmp = tmp->next;
}
return sum;
}
double list_score_avg(SL stu_list) {
return list_score_sum(stu_list) / list_len(stu_list);
}
int list_search_id(SL stu_list, int stu_id , Stu stu) {
if (list_is_empty(stu_list)) {
return -1;
}
Stu tmp = stu_list->head->next;
// int i = 1;
// int len = list_len( stu_list );
while (tmp != stu_list->last) {
if( tmp->stu_id == stu_id ){
break;
}
tmp = tmp->next;
}
if (tmp == stu_list->last) {
tmp = NULL;
return 0;
}
stu->stu_id = tmp->stu_id;
strcpy( stu->stu_name, tmp->stu_name);
stu->stu_score_math = tmp->stu_score_math;
stu->stu_score_english = tmp->stu_score_english;
stu->stu_score_computer = tmp->stu_score_computer;
return 1;
}
void list_sort_avg(SL stu_list) {
if (list_is_empty(stu_list) || 1 == list_len(stu_list)) {
return;
}
Stu stu = stu_list->head->next;
Stu stu_next = stu->next;
Stu end = stu_list->last->prev;
while (stu != end) {
// stu_print( stu );
stu_next = stu->next;
while (stu_next != end->next) {
if (stu->stu_score_avg < stu_next->stu_score_avg) {
stu_swap(stu, stu_next);
}
stu_next = stu_next->next;
}
stu = stu->next;
stu_next = stu_next->next;
}
stu = stu_list->head->next;
int grade = 1;
while (stu != stu_list->last) {
stu->stu_score_grade = grade;
grade++;
stu = stu->next;
}
}
FILE * list_save_txt(SL stu_list, char * file_name ) {
if (list_is_empty(stu_list)) {
return NULL;
}
FILE * fp = NULL;
if ( NULL == (fp = fopen(file_name, "w"))) {
printf("创建 !");
exit(-1);
}
Stu stu = stu_list->head->next;
while (stu != stu_list->last) {
char stu_info[1024];
sprintf(stu_info, "%d\t%s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%d\n",
stu->stu_id, stu->stu_name, stu->stu_score_math,
stu->stu_score_english, stu->stu_score_computer,
stu->stu_score_sum, stu->stu_score_avg,
stu->stu_score_grade);
// puts(stu_info);
fputs(stu_info, fp);
stu = stu->next;
}
if (0 != fclose(fp)) {
puts("关闭文件失败!");
exit(-1);
}
return NULL;
}
SL list_pass(SL stu_list) {
if (list_is_empty(stu_list)) {
return NULL;
}
Stu stu = stu_list->head->next;
while (stu != stu_list->last) {
if (stu->stu_score_avg >= 60) {
stu_print(stu);
}
stu = stu->next;
}
return NULL;
}
student.txt//学生信息,以tab键作为分隔符
1001 小代码 34 45 56
1002 老狼 25 16 56
1003 行者 34 13 77
1004 天涯 34 18 88
1005 散人 34 99 56
测试过程:
/*
D:\code\gongda\eclipse\zonghe_1_list>test
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:1
输入文件名:student.txt
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:8
学号 姓名 数学 英语 计算机 总分 平均分 排名
1001 小代码 34.00 45.00 56.00 135.00 45.00 -1
1002 老狼 25.00 16.00 56.00 97.00 32.33 -1
1003 行者 34.00 13.00 77.00 124.00 41.33 -1
1004 天涯 34.00 18.00 88.00 140.00 46.67 -1
1005 散人 34.00 99.00 56.00 189.00 63.00 -1
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:2
输入文件名:studentinfo.txt
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:3
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:4
输入
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:6
输入要查询的学生的学号:1001
id = 1
1001 小代码 34.00 45.00 56.00 0.00 0.00 -1
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:6
输入要查询的学生的学号:1007
id = 0
查人此人
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:7
1005 散人 34.00 99.00 56.00 189.00 63.00 -1
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:5
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:8
学号 姓名 数学 英语 计算机 总分 平均分 排名
1005 散人 34.00 99.00 56.00 189.00 63.00 1
1004 天涯 34.00 18.00 88.00 140.00 46.67 2
1001 小代码 34.00 45.00 56.00 135.00 45.00 3
1003 行者 34.00 13.00 77.00 124.00 41.33 4
1002 老狼 25.00 16.00 56.00 97.00 32.33 5
1-输入 2-保存
3-总分 4-平均分
5-排名 6-查询
7-统计及格 8-=输出
-1-退出
输入命令:
-1
谢谢使用
D:\code\gongda\eclipse\zonghe_1_list>
*/
动态数组实现:
stuMain.c//入口
#include<stdio.h>
#include<stdlib.h>
#include"student.h"
#include"stu_array.h"
int main(void) {
StuArray stuarr = array_init();
Stu stu = stu_create(1001, "小代码", 23.3, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1002, "小代码", 56, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1003, "小代码", 0, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1004, "小代码", 234, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1005, "小代码", 555, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1006, "小代码", 12, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1007, "小代码", 4, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1008, "小代码", 777, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1009, "小代码", 23.3, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1010, "小代码", 23.3, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1011, "小代码", 23.3, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1012, "小代码", 23.3, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1013, "小代码", 23.3, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1014, "小代码", 23.3, 34.2, 45.6);
array_append(stuarr, stu);
stu = stu_create(1015, "小代码", 23.3, 34.2, 45.6);
array_append(stuarr, stu);
printf("长度:%d\n", array_len(stuarr));
printf("count = %d\n", stuarr->count);
printf("array size = %d\n", stuarr->arr_size);
array_print(stuarr);
array_delete_id(stuarr, 1011);
printf("长度:%d\n", array_len(stuarr));
printf("count = %d\n", stuarr->count);
printf("array size = %d\n", stuarr->arr_size);
array_print(stuarr);
// int id = 0;
// puts("输入要查询的学生的学号:");
// scanf("%d",&id);
// stu_print( array_get( stuarr, id ));
//
// puts("\n--排序测试--\n");
// array_sort_avg( stuarr );
// array_print(stuarr);
//
// puts("\n-----保存到文件---------\n");
// array_save_txt( stuarr );
//
//
// puts("\n---平均分大于60-------\n");
// array_pass( stuarr );
// 文件初始化测试
// FILE * stu_file = fopen("stu_file.txt", "r");
// if ( NULL == stu_file) {
// puts("打开失败!");
// exit(-1);
// }
//
// StuArray stuarr = array_init_file(stu_file);
// array_print(stuarr);
//
// if (0 != fclose(stu_file)) {
// puts("关闭文件失败!");
// exit(-1);
// }
printf("\n\nHello World!\n");
//测试
return 0;
}
student.h//
student.c//
这两个文件和链表中 的一样
stu_array.c//动态数组声明和操作声明
/**
* @file
* @author 小代码
*/
#ifndef STU_ARRAY_H_
#define STU_ARRAY_H_
#include<stdio.h>
#include"student.h"
/**
* @def 数组的默认初始化长度
*/
#define ARRAY_DEFAULT_SIZE 10
/**
* @brief 学生数组结构体
*/
struct _stu_array {
/**
* @brief 指向学生数组的指针
*/
Stu * stu_arr;
/**
* @brief 数组有效长度
*/
int count;
/**
* @brief 数组容量
*/
int arr_size;
};
typedef struct _stu_array STUARRAY;
typedef struct _stu_array * StuArray;
/**
* @brief 初始化数组
* @note 其中默认长度为 10
* @return 返回一个初始化的学生数组
* @retval NULL 初始化失败
*/
StuArray array_init();
/**
* @brief 返回学生数组的长度
*
* @param stuarr 要求长度的学生数组
*
* @return 返回学生数组的长度
* @retval -1 计算失败,可能是数组指针为NULL
*/
int array_len(StuArray stuarr);
/**
* @brief 在学生数组中追加一个学生对象
* @note 如果数组的容量不够用,则扩充一倍\n
* @note 如果要追加的元素为空或者数组指针为空,则返回NULL
* @param stuarr 要追加元素的数组
*
* @param stu 要追加的元素
*
* @return 追加的学生
*
* @retval NULL 追加失败
*/
Stu array_append(StuArray stuarr, Stu stu);
/**
* @brief 分所学生的学号删除学生
* @param stuarr 保存学生信息的数组
* @param stu_id 要删除的学生的学号
* @return 删除的学生
* @retval NULL 删除失败
*/
Stu array_delete_id( StuArray stuarr, int stu_id );
/**
* @brief 遍历输出一个数组
* 如果参数为空,则没有任何输出
*
* @param stuarr 要遍历输出的数组
*/
void array_print(StuArray stuarr);
/**
* @brief 扩展数组容量
* @note 此函数使用 malloc() 函数重新分配一个数组
* @param stuarr
*/
void array_expand( StuArray stuarr );
/**
*
* @brief 根据学号查询学生的信息
* 返回查询到的学生对象,如果没有查到,则返回NULL
*
* @param stuarr
* @param stu_id
* @return
*/
Stu array_get( StuArray stuarr, int stu_id );
/**
* @brief 根据学生的平均分进行排序
* @param stuarr 要排序的数组
*/
void array_sort_avg( StuArray stuarr );
/**
* @brief 把数组中的学生信息保存到一个文件中
* 此文件名为:student.txt
* @param stuarr
* @return
*/
FILE * array_save_txt( StuArray stuarr );
/**
* @brief 从一个文本文件中读取学生的信息
* 文件格式应为:
* 每一行是一个学生的信息,不同的信息段之间用空格或tab键隔开
* @note 参数 stu_file 应是使用"r"模式打开的文本文件
* * @param stu_file 保存学生信息的文件
* @return 学生信息数组
* @retval NULL 创建失败
*/
StuArray array_init_file( FILE * stu_file );
/**
* @brief 统计平均争超过60分的学生的信息
* @param stuarr 要统计的学生数组
*/
void array_pass( StuArray stuarr );
#endif /* STU_ARRAY_H_ */
stu_array.c//动态数组操作实现
#include"stu_array.h"
#include"student.h"
#include<stdio.h>
#include<stdlib.h>
StuArray array_init() {
StuArray stuarr = (StuArray) malloc(sizeof(STUARRAY));
if ( NULL == stuarr) {
puts("array_init...【初始化数组】动态分配内存失败!");
return NULL;
exit(-1);
}
stuarr->count = 0;
stuarr->arr_size = ARRAY_DEFAULT_SIZE;
stuarr->stu_arr = (Stu*) malloc(sizeof(Stu));
if ( NULL == stuarr->stu_arr) {
puts("array_init...【初始化默认数组】动态分配内存失败!");
return NULL;
exit(-1);
}
return stuarr;
}
int array_len(StuArray stuarr) {
if ( NULL == stuarr) {
return -1;
}
return stuarr->count;
}
Stu array_append(StuArray stuarr, Stu stu) {
if ( NULL == stuarr || NULL == stu) {
return NULL;
}
if (stuarr->count >= stuarr->arr_size - 2) {
array_expand(stuarr);
}
stuarr->stu_arr[stuarr->count] = stu;
stuarr->count++;
return stu;
}
/**
* @brief 分所学生的学号删除学生
* @param stuarr 保存学生信息的数组
* @param stu_id 要删除的学生的学号
* @return 删除的学生
* @retval NULL 删除失败
*/
Stu array_delete_id( StuArray stuarr, int stu_id ){
if(NULL == stuarr ){
return NULL;
}
int len = array_len( stuarr );
if( len < 0 ){
return NULL;
}
Stu stu = array_get( stuarr, stu_id );
int i = 0;
for( ; stu != stuarr->stu_arr[i]; i++ ) ;
len -= 1;
for( ; i < len; i++ ){
stuarr->stu_arr[i] = stuarr->stu_arr[ i + 1 ];
}
stuarr->count--;
return stu;
}
void array_print(StuArray stuarr) {
if ( NULL == stuarr) {
return;
}
int i = 0;
print_title();
for (i = 0; i < stuarr->count; i++) {
stu_print(stuarr->stu_arr[i]);
}
}
void array_expand(StuArray stuarr) {
Stu * tmp = (Stu*) malloc(sizeof(Stu) * stuarr->arr_size * 2);
int i = 0;
for (i = 0; i < stuarr->count; i++) {
tmp[i] = stuarr->stu_arr[i];
}
stuarr->stu_arr = tmp;
stuarr->arr_size *= 2;
// puts("进入:array_expand()函数");
//
// Stu * tmp = stuarr->stu_arr;
// tmp = (Stu*)realloc( tmp, (size_t)(stuarr->arr_size * 2));
//
// stuarr->stu_arr = tmp;
// stuarr->arr_size *= 2;
//
// stu_print( stuarr->stu_arr[0]);
// stu_print( stuarr->stu_arr[1]);
// array_print( stuarr );
}
Stu array_get(StuArray stuarr, int stu_id) {
int len = array_len(stuarr);
Stu stu = NULL;
if (0 == len) {
return NULL;
}
int i = 0;
for (i = 0; i < len; i++) {
stu = stuarr->stu_arr[i];
if (stu->stu_id == stu_id) {
break;
}
}
return stu;
}
/**
* @brief 根据学生的平均分进行排序
* @param stuarr 要排序的数组
*/
void array_sort_avg(StuArray stuarr) {
if (NULL == stuarr) {
return;
}
int len = array_len(stuarr);
int i = 0;
int j = 0;
for (i = 0; i < len - 1; i++) {
for (j = i + 1; j < len; j++) {
// printf("\ni->avg = %.2lf\tj->avg = %.2lf\n",stuarr->stu_arr[i]->stu_score_avg,stuarr->stu_arr[j]->stu_score_avg);
if (stuarr->stu_arr[i]->stu_score_avg
< stuarr->stu_arr[j]->stu_score_avg) {
stu_swap(stuarr->stu_arr[i],
stuarr->stu_arr[j]);
}
}
}
for (i = 0; i < len; i++) {
stuarr->stu_arr[i]->stu_score_grade = i + 1;
}
}
/**
* @brief 把数组中的学生信息保存到一个文件中
* 此文件名为:student.txt
* @param stuarr
* @return
*/
FILE * array_save_txt(StuArray stuarr) {
int len = array_len(stuarr);
if ( NULL == stuarr || 0 == len) {
return NULL;
}
FILE * stu_file = fopen("student.txt", "w");
if (NULL == stu_file) {
puts("创建文件失败!");
exit(-1);
}
int i = 0;
int sta = 0;
for (i = 0; i < len; i++) {
sta = fprintf(stu_file,
"%d\t%s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%d\n",
stuarr->stu_arr[i]->stu_id,
stuarr->stu_arr[i]->stu_name,
stuarr->stu_arr[i]->stu_score_math,
stuarr->stu_arr[i]->stu_score_english,
stuarr->stu_arr[i]->stu_score_computer,
stuarr->stu_arr[i]->stu_score_sum,
stuarr->stu_arr[i]->stu_score_avg,
stuarr->stu_arr[i]->stu_score_grade);
if (sta < 0) {
puts("写入文件失败!");
exit(-1);
}
}
return stu_file;
}
/**
* @brief 从一个文本文件中读取学生的信息
* 文件格式应为:
* 每一行是一个学生的信息,不同的信息段之间用空格或tab键隔开
* @note 参数 stu_file 应是使用"r"模式打开的文本文件
* * @param stu_file 保存学生信息的文件
* @return 学生信息数组
* @retval NULL 创建失败
*/
StuArray array_init_file(FILE * stu_file) {
if ( NULL == stu_file) {
return NULL;
}
StuArray stuarr = array_init();
int stu_id = 0;
char stu_name[10];
double stu_math = 0.0;
double stu_english = 0.0;
double stu_computer = 0.0;
while ( EOF
!= fscanf(stu_file, "%d\t%s\t%lf\t%lf\t%lf", &stu_id,
stu_name, &stu_math, &stu_english,
&stu_computer)) {
Stu stu = stu_create(stu_id, stu_name, stu_math, stu_english,
stu_computer);
stu_print(stu);
array_append(stuarr, stu);
}
return stuarr;
}
/**
* @brief 统计平均争超过60分的学生的信息
* @param stuarr 要统计的学生数组
*/
void array_pass( StuArray stuarr ){
int len = array_len( stuarr );
if( NULL == stuarr || 0 == len ){
return ;
}
int i = 0;
for( i = 0; i < len; i++ ){
Stu stu = stuarr->stu_arr[i];
if( stu->stu_score_avg > 60 ){
stu_print(stu);
}
}
}