大四重写大一的C语言大作业是一种怎样的体验
来源:互联网 发布:it's had it翻译 编辑:程序博客网 时间:2024/05/19 13:29
序言
在整理文件时偶然发现大一时的C语言大作业,故突然心血来潮想看看曾经花费一个星期的成果。
它虽然只有一个文件,却足足有829行,可见当时我下了多大功夫。回忆起当时作业的要求,大致也不过是实现一个可以增删改记录的学生成绩管理系统,何至于要写829行呢?找到源码配备的文档,想起那些我绞尽脑汁想出来的诸多花哨的功能,我不禁感慨:年轻就是能折腾啊!
而在我准备仔细拜读时,我却高兴不起来了——我根本看不懂也不想看懂我的代码!尽管我读过很多很烂的代码,但当发现自己曾经的骄傲之作其实是一片垃圾不堪入目时,我还是十分难受。
记得老师布置大作业的时候鼓励我们多写代码,多添加功能,于是我就认为代码越多越好,并添加了很多古怪的功能。而现在我很清楚:代码不是拼数量的,而是拼质量的,功能设计也不是越丰富越好,为意义不大的功能耗费精力是不值得的。
好的代码?
回顾我学习C的一点点经历,感慨曾经有太多对编程语言的误解:
- 狂热于语言技巧 死记运算符优先级,死钻语言特性的行为就是走火入魔,语言是为我们服务的,好用的特性就用,不好用的特性应当避免。以前以为一个人知道越多的语言特性就越懂一门语言,现在才明白懂如何用一门语言比探究语言本身更重要。
- 误以为代码越难懂越好 曾以为只有自己能看懂的程序才算高大上,肆无忌惮地使用“
#
”、“##
”、“#@
”预处理运算符,滥用那些鲜为人知的宏替换的技巧。不仅降低了自己写代码的效率,还增加了别人阅读的时间,到最后写出的代码连自己也看不懂。 - 盲目追求运行效率 曾参加智能车比赛,为了提高车速,误以为变量名改短,数组展开成简单变量,循环展开…等就能提高程序运行速度,简直愚蠢之极。(想象力太丰富不一定是好事,要多看书,少瞎想)
- 不愿分享代码 曾以为代码是自己辛勤劳动所得,如果给了别人就没有价值了。现在才明白代码就像一件艺术品,没有人看它,它也就没有价值了。
我想,写代码应当努力达到作诗般简练优雅:
- 不追求平仄交替,只求抒发情感,表达思想
- 不追求辞藻华丽,只求通俗易懂,老妪能解
这样的好代码才能被人们clone、star、传诵。
重写代码!
万千的感慨令我不禁神游了一阵子,回过神,想起大四没有课,也算是有点闲时间,于是想改改这份代码。可当我发现几乎所有地方都有毛病时且不想再看逻辑混乱的代码时,我又改了主意,哎,还是重写吧!
总算是把800多行改成200多行了,程序讲解见我的Github博客,希望对刚学完C语言的同学们有所帮助。本人能力有限,如有前辈愿意点拨,敬请在本文后评论,不胜感激!
最后附上代码:
/* * Student Information Manager * https://baidut.github.io/ | Released under MIT license * Copyright (c) 2015 Zhenqiang.Ying <yingzhenqiang@gmail.com> */#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX 100#define NAME_LEN 10typedef struct { char name[NAME_LEN]; unsigned int score[3]; unsigned int sum;} Stu_t;Stu_t stu[MAX];int num;Stu_t input_stu(void); // 通过提示引导用户正确地输入一条学生记录,并返回这条记录void output_stu(int i); // 根据数组索引打印出对应的学生信息int find_stu(void); // 通过提示引导用户查找记录,如果找到则显示查找到的记录,并返回数组索引,否则返回-1void read_stu(const char *filename); // 根据文件名读入文件中的学生数据void write_stu(const char *filename); // 将学生数据写入到指定的文件中int confirm(const char *words); // 请求用户确认,输入y或Y返回1,输入n或N返回0,其他情况提示用户重新输入void safe_flush(FILE *fp); // safe_flush(stdin)清理多余的输入,防止影响下次获取输入int main(void) { const char *filename = "stud_info.txt"; read_stu(filename); // 导入数据 printf("欢迎使用学生成绩管理系统\n" "-当前已有%d条记录,本程序限制%d条记录\n", num, MAX); for (;;) { char choice; int i, j; printf( "-菜单:\t" "1.查找\t" "2.追加\t" "3.删除\t" "4.修改\t" "5.排序\t" "6.显示\t" "7.保存\t" "0.退出\n" "输入序号:"); choice = getchar(); safe_flush(stdin); switch (choice) { case '1': // 查找 find_stu(); break; case '2': // 追加 if (num < MAX) { stu[num] = input_stu(); output_stu(num); num++; puts("追加成功!"); } else puts("记录已满,无法追加!"); break; case '3': // 删除 i = find_stu(); if (-1 != i) { if (confirm("确认删除?")) { while (i++ != num) { stu[i-1] = stu[i]; } num--; puts("删除成功!"); } } break; case '4': // 修改 i = find_stu(); if (-1 != i) { stu[i] = input_stu(); output_stu(i); puts("修改成功!"); } break; case '5': // 按照总分排序 for (i = 0; i < num-1; i++) // 冒泡排序中已经排好的 for (j=0; j < num-1-i; j++) // 遍历没排好的 if ( stu[j].sum < stu[j+1].sum ) { Stu_t t = stu[j]; stu[j] = stu[j+1]; stu[j+1] = t; } puts("排序成功!"); /* fall through */ // 完成排序后自动显示 case '6': // 显示 for (i = 0; i < num; i++) { printf("%4d:\t", i+1); output_stu(i); } break; case '7': // 保存 write_stu(filename); break; case '0': // 退出 if (confirm("推出前保存?(Y/N)")) { write_stu(filename); } exit(0); default: puts("没有该序号!请重新输入"); break; } } // END for return 0;}void safe_flush(FILE *fp){ int ch; while ( ch = fgetc(fp), ch != EOF && ch != '\n');}int confirm(const char *words) { char choice; puts(words); for (;;) { choice = getchar(); safe_flush(stdin); switch (choice) { default: puts("输入非法,重新输入!"); continue; case 'Y': case 'y': puts("已确认!"); return 1; case 'N': case 'n': puts("已取消!"); return 0; } }}Stu_t input_stu(void) { Stu_t ret; puts("依次输入姓名、语文、数学、外语成绩,空格分隔,成绩要求是整数:"); while ( 4 != scanf("%s%d%d%d", ret.name, &ret.score[0], &ret.score[1], &ret.score[2])) { safe_flush(stdin); puts("输入有误,请重新输入!"); } safe_flush(stdin); ret.sum = ret.score[0] + ret.score[1] + ret.score[2]; return ret;}void output_stu(int i) { if (i < 0 || i > MAX) return; printf("%s\t语:%d\t数:%d\t外:%d\t总分:%d\n", stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].sum);}int find_stu(void) { char name[NAME_LEN]; int i; printf("输入姓名(限%d个字符):", NAME_LEN); scanf("%s", name); safe_flush(stdin); for (i = 0; i < num; i++) { if (0 == strcmp(stu[i].name, name)) { output_stu(i); return i; } } puts("没有找到记录!"); return -1;}void read_stu(const char *filename) { FILE *fp = fopen(filename, "rt"); if (NULL != fp) { fread(&num, sizeof(int), 1, fp); fread(stu, sizeof(Stu_t), num, fp); } fclose(fp);}void write_stu(const char* filename) { FILE *fp = fopen(filename, "wt"); if (NULL != fp) { fwrite(&num, sizeof(int), 1, fp); fwrite(stu, sizeof(Stu_t), num, fp); fclose(fp); puts("保存成功!"); } else puts("打开文件失败!");}
0 0
- 大四重写大一的C语言大作业是一种怎样的体验
- 年年加薪是一种怎样的体验?
- 不甘平庸是一种怎样的体验
- 参加RoboMasters大学生机器人大赛是一种怎样的体验
- 大一学C语言做过的作业。
- 跟着海盗头子创业是一种怎样的体验?
- 用C++写Web应用是一种怎样的体验?
- 拿到天使投资是一种怎样的体验
- 怎么关闭朋友圈+关闭朋友圈是一种怎样的体验
- “VR+教育/商业/旅游”是一种怎样的体验?
- MirrorSys:沉浸式现实是一种怎样的体验?
- 用 VR 玩《魔兽世界》是一种怎样的体验?
- 发表 SCI 封面文章是一种怎样的体验?
- 长期从事表格工作是一种怎样的体验?
- 2016年学习JavaScript是怎样的一种体验
- 跟傻子机器人聊天是一种怎样的体验?
- 在世界五百强实习,是一种怎样的体验?
- 在 Stack Overflow 远程办公是一种怎样的体验?
- java不同的垃圾回收器的比较
- 距离和相似度度量
- 改善python程序的91个建议读书笔记1
- Android 新版NDK环境搭建(免Cygwin)
- C 预处理指令 宏定义 条件编译
- 大四重写大一的C语言大作业是一种怎样的体验
- IOS Auto Layout代码实现自动布局--VFL(Visual format language)
- 标签页的制作
- Android sdk从另一台电脑迁移和含ADT的Eclipse迁移的注意事项
- Multicast notes
- 创建推送证书 遇到 “此证书由未知颁发机构签名”
- sonar 代码质量管理
- JAVA 实现手机号码压缩,解压
- C 预处理指令 条件编译