大四重寫大一的C語言大作業是一種怎樣的體驗

來源:互聯網
上載者:User

標籤:c語言   編程   

序言

在整理檔案時偶然發現大一時的C語言大作業,故突然心血來潮想看看曾經花費一個星期的成果。

它雖然只有一個檔案,卻足足有829行,可見當時我下了多大功夫。回憶起當時作業的要求,大致也不過是實現一個可以增刪改記錄的學產生績管理系統,何至於要寫829行呢?找到源碼配備的文檔,想起那些我絞盡腦汁想出來的諸多花哨的功能,我不禁感慨:年輕就是能折騰啊!

而在我準備仔細拜讀時,我卻高興不起來了——我根本看不懂也不想看懂My Code!儘管我讀過很多很爛的代碼,但當發現自己曾經的驕傲之作其實是一片垃圾不堪入目時,我還是十分難受。

記得老師布置大作業的時候鼓勵我們多寫代碼,多添加功能,於是我就認為代碼越多越好,並添加了很多古怪的功能。而現在我很清楚:代碼不是拼數量的,而是拼品質的,功能設計也不是越豐富越好,為意義不大的功能耗費精力是不值得的。

好的代碼?

回顧我學習C的一點點經曆,感慨曾經有太多對程式設計語言的誤解:

  1. 狂熱於語言技巧 死記運算子優先順序,死鑽語言特性的行為就是走火入魔,語言是為我們服務的,好用的特性就用,不好用的特性應當避免。以前以為一個人知道越多的語言特性就越懂一門語言,現在才明白懂如何用一門語言比探究語言本身更重要。
  2. 誤以為代碼越難懂越好 曾以為只有自己能看懂的程式才算高大上,肆無忌憚地使用“#”、“##”、“#@”預先處理運算子,濫用那些鮮為人知的宏替換的技巧。不僅降低了自己寫代碼的效率,還增加了別人閱讀的時間,到最後寫出的代碼連自己也看不懂。
  3. 盲目追求運行效率 曾參加智能車比賽,為了提高車速,誤以為變數名改短,數組展開成簡單變數,迴圈展開…等就能提高程式運行速度,簡直愚蠢之極。(想象力太豐富不一定是好事,要多看書,少瞎想)
  4. 不願分享代碼 曾以為代碼是自己辛勤勞動所得,如果給了別人就沒有價值了。現在才明白代碼就像一件藝術品,沒有人看它,它也就沒有價值了。

我想,寫代碼應當努力達到作詩般簡練優雅:

  • 不追求平仄交替,只求抒發情感,表達思想
  • 不追求辭藻華麗,只求通俗易懂,老嫗能解

這樣的好代碼才能被人們clone、star、傳誦。

重寫代碼!

萬千的感慨令我不禁神遊了一陣子,回過神,想起大四沒有課,也算是有點閑時間,於是想改改這份代碼。可當我發現幾乎所有地方都有毛病時且不想再看邏輯混亂的代碼時,我又改了主意,哎,還是重寫吧!

總算是把800多行改成200多行了,程式講解見我的Github部落格,希望對剛學完C語言的同學們有所協助。本人能力有限,如有前輩願意點撥,敬請在本文後評論,不勝感激!

最後附上代碼:

/* * Student Information Manager * https://baidut.github.io/ | Released under MIT license * Copyright (c) 2015 Zhenqiang.Ying <[email protected]> */#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("開啟檔案失敗!");}

大四重寫大一的C語言大作業是一種怎樣的體驗

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.