C語言課程設(shè)計

作為剛剛學(xué)習(xí)C的新手录别,水平較低,難免出錯邻吞。希望各位前輩不吝賜教组题,批評指正。



????在C語言學(xué)習(xí)了一段時間之后抱冷,我們開始入了課程設(shè)計崔列。初學(xué)了一些簡單的語法之后,感覺要完成一項工程還是有些困難的旺遮。
????聽說在寫課程設(shè)計時赵讯,比起一下子打出來完,不如分模塊耿眉,分功能的有步驟的去寫圆雁。
????課程設(shè)計的核心齐遵,是對鏈表的操作,實現(xiàn)動態(tài)鏈表的增、刪、改、查。這里主要說一下課程設(shè)計的思路和想法。
????對于鏈表的具體操作江滨,諸君都比我水平高,不敢贅言厌均,就簡單提一下唬滑。

1.顯示主菜單

在復(fù)雜面前,先做一些微不足道的小工作棺弊。先把菜單的內(nèi)容寫了出來晶密,在主函數(shù)里調(diào)動menu()就會出來這個直接顯示的界面。

1.png

????其實一開始镊屎,考慮到menu()只是用來顯示惹挟,我就把它定義成了void型,后來在學(xué)長的提醒下缝驳,把void改為了int连锯,原來在一些其他的編譯器里,void型被淘汰或者是會報錯用狱。為了養(yǎng)成良好的編程習(xí)慣运怖,就把剩下的void都改成了int或其他。

2.操作菜單

接下來夏伊,在操作菜單里摇展,填寫以下內(nèi)容 :

2.png

????這個就是提供一個選擇功能的途徑,至于功能溺忧,之后再補全咏连,總之先把位置留出來。
???通過輸入數(shù)字的方式來選擇功能鲁森,在1--8的范圍內(nèi)(圖中的printf是添加讀檔功能前的7個祟滴,不必在意),輸入正確就讓flag=1歌溉,如果輸入其他的垄懂,那就循環(huán)回來重輸。
????至于那個while里的判斷(真or假)痛垛,只要n不在1--8草慧,就一直為真,一直循環(huán)匙头,當然你要是高興漫谷,把(flag==0)換成(1)也行。


3.png

上一步對flag的操作蹂析,目的就是為了引出下面的循環(huán)舔示,在正確的選擇功能里朽寞,通過swich實現(xiàn)相關(guān)功能的函數(shù)調(diào)動,n也就是用到這里斩郎,當然在一開始并沒有這些函數(shù),我只是寫了printf和break而已喻频。

為了方便起見缩宜,我把switch里的內(nèi)容先折疊一下。


4.png

????在你選擇并實現(xiàn)了相關(guān)功能以后甥温,順序執(zhí)行锻煌,在125行進行詢問是否繼續(xù),并且通過getchar()來獲取一個字符姻蚓。如果y(yes)宋梧,再次獲取n,再次循環(huán)狰挡,周而復(fù)始捂龄。
???? 如果輸入其他的,那就直接退出了exit(0)加叁。
????(函數(shù)exit()通常是用在子程序中用來終結(jié)程序用的倦沧,要加上頭文件#include<stdlib.h>)。

3.創(chuàng)建鏈表

????說起創(chuàng)建鏈表它匕,大家都有自己的做法展融。我的做法就是定義了兩個結(jié)構(gòu)體指針,先共同賦了一片空間豫柬,為p1賦值告希,(圖中的sca就是我調(diào)動賦值的函數(shù))。
sca.png

其實再一開始烧给,我就聲明了一個全局變量:
????????????????struct work*head=NULL;
????在之后的對鏈表操作都是在對頭進行操作燕偶。讓鏈表停止的操作,就是在初始化時创夜,使工號為0杭跪。在第一個節(jié)點時,需要特殊處理一下驰吓,即令p和head指向同一片空間涧尿,這樣就能起到 拿起鏈表頭就能拿起一串的效果。

????之后的操作就司空見慣了檬贰,讓p1申請空間并賦值姑廉,再讓p2指向p1所開辟的新空間,循環(huán)往復(fù)的增加節(jié)點翁涤,直到工號為0時停止桥言。

最后萌踱,別忘了單鏈表的尾要置空。最后的返回值就是把“頭head”返回去了号阿,因而可以實現(xiàn)case 1里的 head=creat(head)了并鸵。

????*那個system("cls")是后來為了美觀加上的,在前期修改時為了及時的反饋問題扔涧,盡量不要加园担。

4.顯示節(jié)點和鏈表

剛剛做了一套貌似復(fù)雜的操作,現(xiàn)在我們來看一些輕松的東西枯夜。

在我們對鏈表進行操作時弯汰,難免要經(jīng)常查看節(jié)點和整個鏈表,要是每次都輸出的話那是多么的繁瑣湖雹,不如直接調(diào)動函數(shù)咏闪。我就寫了兩個方便自己查看的,一個是看單個節(jié)點
node.png

如你所見摔吏,傳入?yún)?shù)結(jié)構(gòu)體指針鸽嫂,把每一個數(shù)據(jù)成員都顯示出來。


list.png

另一個是顯示整個鏈表征讲,把頭head傳進來溪胶,為了防止對head進行誤操作,臨時定義結(jié)構(gòu)體指針p稳诚。令p和head指向同一片空間哗脖,再通過 do-while 對p進行遍歷。在printnode()的基礎(chǔ)上輸出一個一個又一個的節(jié)點扳还。

5.增加

毫無疑問才避,這是這里面最簡單的功能操作。

在這個函數(shù)里面氨距,你甚至不需要具體的完全遍歷桑逝。
add.png

????如你所見,為了圖方便俏让,我甚至都沒有去找最后的節(jié)點插入楞遏,而是就直接放到了頭結(jié)點的后面。反正就算只有一個節(jié)點也可以放到后面首昔。

6.查找

????除了增加以外寡喝,最簡單的就算是查找了,因為這個遍歷的過程勒奇,會是其他功能的基礎(chǔ)预鬓。


find.png

圖中for循環(huán)的過程,就是鏈表遍歷的過程赊颠,在一遍的搜索之后格二,如果出現(xiàn)的需要的東西劈彪,那就停止搜索,可以拿出來操作了顶猜。這里只是作為顯示沧奴,并不需要操作什么。

圖中的continue是考慮到會有工號重復(fù)的情況长窄。

7.刪除

delete.png

????進入了刪除模式之后扼仲,會有兩個選項,按工號或者姓名刪除抄淑,其實原理都一樣,這里就以工號刪除為例驰后。

????令新的指針代替頭指針實現(xiàn)遍歷(213)肆资,判斷出來要刪除的節(jié)點之后,再進行一次判斷:你要刪除的灶芝,是頭結(jié)點郑原,還是其他的。

a.頭結(jié)點刪除:

????直接讓指針指向下一位夜涕,釋放掉原本的第一個犯犁,再讓頭指針重新指向原本的第二個。這里實現(xiàn)的過程就是pt比pt2多走了一位女器,以便進行操作酸役。

b.其他節(jié)點:

????直接令p2的后繼指向pt的后繼,也就是把pt直接隔過去驾胆,再進行釋放涣澡。
至于下面的if,如你所見丧诺,它的功能就是在while循環(huán)里入桂,使指針不斷向后推進,直至目標出現(xiàn)驳阎。

????當然了抗愁,按姓名刪除的操作幾乎一模一樣,唯一的一點小區(qū)別就是呵晚,if的判斷變成了這樣:
????????if( strcmp(name,pt->name)==0 )
需要判斷這兩個字符串是否一致蜘腌,完全一致的話,返回值就是0了饵隙,就能找到該節(jié)點了逢捺。strcmp需要頭文件<stdlib.h>.

7.修改
modify.png

????寫之前感覺修改會很難,大概是不小心走了什么歪門邪道吧癞季,寫出來發(fā)現(xiàn)它的過程和遍歷一樣簡單劫瞳,無非是在我找到相關(guān)pt之后倘潜,又為它重新賦值了一遍而已(你當然會記得那個sca是我之前定義的賦值函數(shù))。

排序!

????如果你特別熟練鏈表以及它的增刪改查志于,那么前面寫的實在是基礎(chǔ)涮因。而排序的確讓我為難困惑了一番。

a.冒泡的錯

????再最開始版本的排序里伺绽,我嘗試了用冒泡排序?qū)ぬ栠M行操作养泡,排的過程也比較簡略∧斡Γ可排出來之后感覺哪里好像有點不對澜掩,原來當時只是把num排了順序,結(jié)果是其他的就亂了杖挣。
mp.png

如你所見肩榕,它繁瑣而低效(關(guān)鍵是還不對...)。

????其實當時忘了一點惩妇,為什么不直接聲明一個結(jié)構(gòu)體變量株汉,然后把它當做中間變量進行排序呢?

b.選擇排序

并沒有順著那個思路想下去歌殃,換了個方法乔妈。

????思想:如果說,原本的鏈表是無序的氓皱,而我最終的目的是創(chuàng)造出有序的路召。而且我有能力去找到這里面最大的或最小的(遍歷就可以了),那么我何不再去創(chuàng)建一個新的鏈表波材,它是由原本鏈表摘出來的節(jié)點所組成优训,那必然是有序的。

sort.png

????和其他操作的最開始一樣各聘,傳入了頭和它之后的一串鏈表揣非,于以往不同的是,這次開始了直接對頭指針的操作躲因。
(366和367是為了防止傳進來一個空頭造成錯誤早敬。

核心代碼就是white里的循環(huán)了:

第一層循環(huán)

????目的是為了讓頭不斷向后遍歷,只不過這次的目的大脉,就是遍歷到終點搞监。期間每執(zhí)行一次,就讓我定義的指針重新指向同一塊镰矿。

第二層循環(huán)

????p(也就是頭)的遍歷琐驴,如果后一個大于前一個,就讓后一個成為max,同時定位它的前一個節(jié)點绝淡,以這種方式標記過后宙刘,p再繼續(xù)向后推進,以實現(xiàn)在循環(huán)過后牢酵,可以過濾出來最大的悬包,找到了又怎樣呢,我們來看接下來的操作馍乙。

第一個if(379)

????這時還要考慮到那種情況布近,也就是頭結(jié)點萬一最大該怎么操作,這也并不難想丝格,直接讓head指向下一位撑瞧,同時斷開max(也就是頭)與原鏈表的聯(lián)系。
其它情況就是显蝌,既然上一步(371 while)找出來了max预伺,那么就在這里把它摘出來,令剛剛標記的前一項(pre)指向max的后繼琅束,在斷開max與原表的聯(lián)系。

第二個if(387)

????細心的你會發(fā)現(xiàn)算谈,在每次的賦值里和之前的幾步操作里涩禀,都沒有用到pnew,不僅如此然眼,它還在一開始就被置空了艾船。
我的目的就是讓它成為那個新的鏈表的頭。在之前幾步高每,我們分別找到了max屿岂,分離出了max,終于要在這一步為max找一個著落了鲸匿。

????當然爷怀,if第一次肯定是會執(zhí)行的(因為上來就讓pnew置空了),我們讓最大的那個節(jié)點成了新鏈表的第一個带欢,那么可想而知的是运授,在之后幾次的循環(huán)里,每次都會執(zhí)行else乔煞,并且在里面新摘出來的max被一個個的連到了鏈表的后面吁朦。

????到最后,別忘了還有那個大循環(huán)的渡贾,它每次執(zhí)行一遍里面的內(nèi)容逗宜。如是,原本的無序鏈表每次少一個節(jié)點(最大的節(jié)點),而新有序鏈表每次會多一個纺讲。

????原鏈表終結(jié)之日擂仍,也就是新鏈表生成之時。屆時刻诊,循環(huán)也就徹底結(jié)束了防楷,于是我們令頭指針指向那個新生鏈表(394),再讓它們共同指向這條有序的鏈表则涯,傳回去就行了复局。


????到了這里,課程設(shè)計也就基本上結(jié)束了粟判,增刪改查帶排序都說完了亿昏,如果你覺得意猶未盡,我們的學(xué)長學(xué)姐提出了一個新的要求:
????該怎么做档礁,才可以讓你的數(shù)據(jù)保存下來角钩,讓我下次打開時還能看到這次的數(shù)據(jù),下次開機時它們還在這里呻澜?

emmm....

對文件的操作

????在學(xué)文件的時候递礼,我總覺得這塊的內(nèi)容可以在今后用到的時候及搜及學(xué)。要實現(xiàn)如上功能羹幸,需要fwrite和fread :

(1)size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

其中脊髓,ptr:指向保存結(jié)果的指針;size:每個數(shù)據(jù)類型的大姓な堋将硝;count:數(shù)據(jù)的個數(shù);stream:文件指針
   函數(shù)返回讀取數(shù)據(jù)的個數(shù)屏镊。

(2)size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
     其中依疼,ptr:指向保存數(shù)據(jù)的指針;size:每
個數(shù)據(jù)類型的大卸妗律罢;count:數(shù)據(jù)的個數(shù);stream:文件指針
    函數(shù)返回寫入數(shù)據(jù)的個數(shù)棍丐。

舉個小例子:
fwrite(p,sizeof(int),1,fp )
????這就是個每次向fp里存一個整型的弟翘,p就是那個要存到文件里的指針。
read同理骄酗,不表稀余。

????原本是要在每個功能的后面都加上這么一個寫入文件的,后來在學(xué)長的提醒下趋翻,把最后一個功能改成了“保存并退出”睛琳,合理了不少。

save

save.png

????如我這個save函數(shù):fopen打開,司空見慣师骗。利用for循環(huán)历等,使pt從頭到尾的指一遍,每次把一個struct work存進去辟癌,也就是一個節(jié)點寒屯,以這種方式把整條鏈表存進去。

read

read.png

????你會發(fā)現(xiàn)黍少,這是個沒有穿入?yún)?shù)的結(jié)構(gòu)體函數(shù)寡夹,在直至文件fp的結(jié)尾之前,一直進行著循環(huán)厂置。fread的返回值是寫入數(shù)據(jù)的個數(shù)菩掏,也就是說每次從文件里面讀一個,直到最后一個.

else的作用是把每一個節(jié)點都顯示出來昵济,顯得有那么一點合情合理...

那每次讀出來的節(jié)點都去了哪里呢智绸?
????這個和剛剛說的排序思路差不多,讓head指向和pt一樣的空間后访忿,循環(huán)申請空間瞧栗,每次都存入一個從文件里讀出來的節(jié)點。形成了一條以head為頭的新的鏈表(也就是上次你退出時的數(shù)據(jù))海铆,被傳回來得以繼續(xù)操作迹恐。

????這樣,你也就得到了一個游添,可以增刪改查排序的系草,還能記
錄數(shù)據(jù)的課程設(shè)計了通熄。



over.png

寫課程設(shè)計唆涝,對于初學(xué)者來說是個漫長而復(fù)雜的過程,一籌莫展和萬念俱灰的想法總是交相輝映唇辨。雖然有時也會絕望(比如我第一次運行有好幾十個錯誤)廊酣,但這就是個從中學(xué)習(xí)的過程。
把代碼一點一點的改對赏枚,是個愉悅而有成就感的事亡驰。

last but not least :

感謝敏學(xué)姐、浪浪學(xué)長的指導(dǎo)和審閱饿幅,祝學(xué)長和429學(xué)長的鼓勵支持凡辱。
感謝圖書館,提供了幾乎所有知識栗恩。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末透乾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌乳乌,老刑警劉巖捧韵,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異汉操,居然都是意外死亡再来,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門磷瘤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芒篷,“玉大人,你說我怎么就攤上這事膀斋∷蠓ィ” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵仰担,是天一觀的道長糊识。 經(jīng)常有香客問我,道長摔蓝,這世上最難降的妖魔是什么赂苗? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮贮尉,結(jié)果婚禮上拌滋,老公的妹妹穿的比我還像新娘。我一直安慰自己猜谚,他們只是感情好败砂,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著魏铅,像睡著了一般昌犹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上览芳,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天斜姥,我揣著相機與錄音,去河邊找鬼沧竟。 笑死铸敏,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的悟泵。 我是一名探鬼主播杈笔,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糕非!你這毒婦竟也來了蒙具?” 一聲冷哼從身側(cè)響起敦第,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎店量,沒想到半個月后芜果,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡融师,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年右钾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旱爆。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡舀射,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怀伦,到底是詐尸還是另有隱情脆烟,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布房待,位于F島的核電站邢羔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏桑孩。R本人自食惡果不足惜拜鹤,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望流椒。 院中可真熱鬧敏簿,春花似錦、人聲如沸宣虾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绣硝。三九已至蜻势,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間域那,已是汗流浹背咙边。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工猜煮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留次员,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓王带,卻偏偏與公主長得像淑蔚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子愕撰,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx刹衫?那么一定聽過它的“同行”Apache吧醋寝!Ngi...
    JokerW閱讀 32,650評論 24 1,002
  • 本文內(nèi)容:1、 什么是鏈表带迟?2音羞、 鏈表共分幾類?3仓犬、 鏈表的 C 實現(xiàn)嗅绰! 總表:《數(shù)據(jù)結(jié)構(gòu)?》 工程代碼 Gith...
    半紙淵閱讀 39,930評論 0 54
  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型搀继。 運用指針編程是C語言最主要的風(fēng)格之一窘面。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu); ...
    朱森閱讀 3,430評論 3 44
  • //leetcode中還有花樣鏈表題叽躯,這里幾個例子财边,冰山一角 求單鏈表中結(jié)點的個數(shù)----時間復(fù)雜度O(n)這是最...
    暗黑破壞球嘿哈閱讀 1,514評論 0 6
  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理点骑。運行時機制的原理和運用場景酣难。SDWebImage的原...
    LZM輪回閱讀 2,004評論 0 12