偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

為什么學(xué)完了C語言,我只會(huì)寫計(jì)算機(jī)程序?

開發(fā) 后端
以前學(xué)C語言的時(shí)候,寫過幾個(gè)小程序,還算蠻有意思的。先上程序截圖,占個(gè)坑,然后再慢慢講做這種小玩意的通用思路。
[[244836]]

以前學(xué)C語言的時(shí)候,寫過幾個(gè)小程序,還算蠻有意思的。先上程序截圖,占個(gè)坑,然后再慢慢講做這種小玩意的通用思路。

溫馨提示:亮點(diǎn)在最后

1、貪吃蛇: 

為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序?

2、都市浮生記(以前有一個(gè)很老的小游戲叫“北京浮生記”,仿那個(gè)寫的,去各種地方買賣商品): 


為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序?

3、背單詞的軟件(當(dāng)年女朋友剛考上英語專業(yè),寫給女朋友記單詞用的,然而被各種手機(jī)APP秒殺了,說實(shí)在的,如果不考慮界面的話,我覺得我這個(gè)功能還是蠻強(qiáng)大的……) 


4、C語言結(jié)合WindosAPI實(shí)現(xiàn)的圖形界面鬧鐘 

為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序?

首先我們需要知道,一款軟件究竟有哪幾個(gè)部分?

在這里我們不談軟件架構(gòu)神馬的專業(yè)知識(shí),就站在入門水平能理解的角度思考,我覺得可以分為5個(gè)部分:

1、業(yè)務(wù)邏輯

指的是解決具體問題的思路。比如做一款背單詞軟件,你怎么隨機(jī)抽取單詞,用什么規(guī)則去判斷用戶是否掌握了這個(gè)單詞,這就是業(yè)務(wù)算法。

2、控制算法

控制邏輯是除了業(yè)務(wù)邏輯之外,關(guān)于整體程序控制層面的算法,比如怎么去實(shí)現(xiàn)一個(gè)鏈表,怎么去實(shí)現(xiàn)圖的搜索,或者如何處理線程同步,等等。

3、人機(jī)交互

簡單來說就是界面。比如C語言的控制臺(tái)(“黑框框”)最基本的人機(jī)交互就是輸入和輸出。圖形化界面就復(fù)雜得多,標(biāo)簽、輸入框、按鈕、圖形繪制、事件監(jiān)聽等等。如果做移動(dòng)開發(fā),還可能涉及到各種傳感器。

4、數(shù)據(jù)存儲(chǔ)

小程序不需要外部的數(shù)據(jù)存儲(chǔ),只有程序內(nèi)部的變量、常量、靜態(tài)數(shù)值。想要功能豐富一點(diǎn),比如小游戲的排行榜、單詞軟件的單詞庫等等,就需要考慮數(shù)據(jù)存儲(chǔ)的問題。簡單一點(diǎn)可以用基本的文件讀寫,自己規(guī)定數(shù)據(jù)存儲(chǔ)的格式。復(fù)雜一點(diǎn)就需要用到數(shù)據(jù)庫了。

5、網(wǎng)絡(luò)通信

普通單機(jī)程序用不到網(wǎng)絡(luò)通信。但如果要做網(wǎng)絡(luò)程序,比如局域網(wǎng)對戰(zhàn)游戲、CS結(jié)構(gòu)的企業(yè)管理軟件、BS結(jié)構(gòu)的商城平臺(tái),等等,就需要考慮網(wǎng)絡(luò)通信的功能。有各種網(wǎng)絡(luò)協(xié)議,底層一點(diǎn)可以是TCP/IP,往上走的話有封裝好的Socket接口,再往上走還有HTTP、FTP等等具體的應(yīng)用協(xié)議。

梳理清楚這五個(gè)部分,我們再來看看,入門階段我們學(xué)C語言學(xué)了什么?

首先是基礎(chǔ)的程序語言知識(shí),從輸入輸出、變量、分支語句、循環(huán)語句,到數(shù)組、函數(shù)、指針、結(jié)構(gòu)體、文件讀寫,基本就學(xué)完了。

然后可能還接觸了一些簡單的算法和數(shù)據(jù)結(jié)構(gòu),比如排序、遞歸、棧、隊(duì)列等等。再復(fù)雜一些,可能會(huì)接觸樹的遍歷、圖的搜索、甚至是動(dòng)態(tài)規(guī)劃。

我們看看這些知識(shí)屬于哪些模塊?

1、它們解決業(yè)務(wù)邏輯不成問題,畢竟我們做的很多習(xí)題,都是真實(shí)情境抽象出來的算法。

2、它能解決一部分簡單的控制邏輯。這主要看你算法與數(shù)據(jù)結(jié)構(gòu)學(xué)的如何。當(dāng)然,涉及到設(shè)計(jì)模式、多線程、事件監(jiān)聽、以及系統(tǒng)層面的控制內(nèi)容,我們還沒學(xué)到。

3、人機(jī)交互,只學(xué)了簡單的輸入輸出。

4、數(shù)據(jù)存儲(chǔ),可以用文件讀寫。

5、網(wǎng)絡(luò)通信,暫時(shí)沒接觸。

接下來,我們只需要有針對性的彌補(bǔ)這些模塊,找到解決方案,就能做出有趣的應(yīng)用。

1、業(yè)務(wù)算法

這個(gè)不需要額外的技術(shù)了,入門階段學(xué)到的知識(shí)基本夠用,但我們要學(xué)會(huì)歸納項(xiàng)目需求,并把它們抽象出來,轉(zhuǎn)化為平常做的習(xí)題的形式,“能獲取什么數(shù)據(jù)、進(jìn)行怎樣的計(jì)算、要得到什么結(jié)果”。當(dāng)然了,思考的時(shí)候并不是這個(gè)順序,而是“要得到什么結(jié)果,需要什么數(shù)據(jù),要進(jìn)行怎樣的計(jì)算”。

2、控制邏輯

前面說到,首先這需要你的算法與數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)。至少要學(xué)會(huì)數(shù)組、結(jié)構(gòu)體、排序、鏈表、遞歸等等,掌握得越多,這塊就越輕松一些。當(dāng)然了,這畢竟不是競賽,自己做項(xiàng)目實(shí)踐的時(shí)候,沒有人強(qiáng)制規(guī)定你“在1s內(nèi)完成,內(nèi)存空間不超過65535KB”,所以哪怕入門階段會(huì)的少,效率低一些,也沒關(guān)系,首先做到“能用”,再考慮優(yōu)化。

那么復(fù)雜一些的控制邏輯問題怎么處理呢?

①多線程

需要調(diào)用系統(tǒng)接口。以windows系統(tǒng)為例,需要調(diào)用WindosAPI,也就是windows.h庫中的函數(shù)。初學(xué)階段,我們可以“不知其所以然”,會(huì)套用就行。

舉例:

問題情境:在貪吃蛇游戲中,我們需要一遍不停的讓蛇向當(dāng)前的方向移動(dòng),一邊獲取用戶輸入的控制信息。我們知道,C語言在使用任何一個(gè)輸入函數(shù)的時(shí)候,都會(huì)等待用戶的輸入,然后再進(jìn)行下面的語句。所以我們必須在一個(gè)單獨(dú)的線程里監(jiān)聽用戶的輸入,否則會(huì)導(dǎo)致“用戶不輸入內(nèi)容,蛇就不移動(dòng)”的情況。

實(shí)現(xiàn)方法(部分代碼): 

  1. #include <stdio.h>  
  2. #include <windows.h>  
  3. #include <conio.h>  
  4. char c;//存儲(chǔ)用戶輸入的按鍵字符的全局變量。  
  5. DWORD WINAPI getOrder();//子線程調(diào)用的方法,用來等待用戶輸入控制命令  
  6. int main()  
  7.  
  8. CreateThread(NULL,NULL,getOrder,NULL,0,NULL);  
  9. while(1){ //控制貪吃蛇不停的移動(dòng)  
  10. switch(c){  
  11. //處理wsad四個(gè)字符的情況,像上下左右移動(dòng)  
  12.  
  13.  
  14. return 0;  
  15.  
  16. DWORD WINAPI getOrder(){  
  17. while(1){  
  18. c=getch();//不停的等待用戶的輸入  
  19. //此處默認(rèn)用戶按的肯定是wsad四個(gè)按鍵,沒有處理錯(cuò)誤情況。真正寫代碼需要考慮。  
  20.  
  21.  

此處關(guān)于多線程的部分,是我當(dāng)年寫貪吃蛇程序時(shí),臨時(shí)上網(wǎng)搜索,直接按人家的格式套用的。說實(shí)話,我到現(xiàn)在也不明白CreateThread里面的幾個(gè)NULL和0分別需要設(shè)置什么(后來深入研究Java去了,一入Java深似海,沒再深究C語言WindowsAPI的問題)。

至于說CreateThread不穩(wěn)定不安全,實(shí)際編程里不推薦使用,而是要用_beginthread。對于初學(xué)階段,這有什么關(guān)系呢?就像我們小學(xué)、初中學(xué)數(shù)學(xué)的時(shí)候,課本里也把很多概念簡化了,并不嚴(yán)謹(jǐn)。我們使用它,是為了幫助我們邁過項(xiàng)目實(shí)踐里的攔路虎,實(shí)現(xiàn)自己想要的功能,真要是以后打算深入研究,再搞明白“為什么”、“什么好”也不遲。(當(dāng)然了,如果愿意多花一些時(shí)間,按網(wǎng)上的說法,去學(xué)習(xí)_beginthread怎么使用,一步到位,也沒有問題,此處給個(gè)鏈接: C語言多線程編程windows多線程CreateThread與_beginthreadex本質(zhì)區(qū)別 )。

②實(shí)現(xiàn)一些與操作系統(tǒng)相關(guān)的功能

這個(gè)當(dāng)然也可以通過WindowsAPI來實(shí)現(xiàn)。但還是那句話,初學(xué)階段,沒有必要。說起來有個(gè)更簡單的方法,只要會(huì)用system("");函數(shù)就行了。別看一個(gè)小小的system函數(shù),通過它,我們可以讓系統(tǒng)執(zhí)行各種dos命令,什么開機(jī)關(guān)機(jī),文件刪查,都不在話下。

當(dāng)然了,要玩轉(zhuǎn)system函數(shù)也有些技巧。首先是要學(xué)會(huì)拼接字符串,比如我們要實(shí)現(xiàn)定時(shí)關(guān)機(jī)的命令,讓用戶輸入一個(gè)時(shí)間,我們就要把時(shí)間數(shù)字轉(zhuǎn)換成字符串,再拼接到命令里面。

樣例代碼如下: 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. int main()  
  4.  
  5. int x,t;  
  6. char command[100]="shutdown -s -t " 
  7. char time[100];  
  8. printf("輸入1:設(shè)置定時(shí)自動(dòng)關(guān)機(jī) ");  
  9. printf("輸入2:取消自動(dòng)關(guān)機(jī) ");  
  10. scanf("%d",&x);  
  11. if(x==1){  
  12. printf("請輸入關(guān)機(jī)時(shí)間(分鐘數(shù)):");  
  13. scanf("%d",&t);  
  14. t=t*60;//把分鐘數(shù)化成秒數(shù)  
  15. itoa(t,time,10);//把數(shù)字轉(zhuǎn)換成字符串,存在time字符數(shù)組里  
  16. strcat(command,time);//拼接命令  
  17. system(command);//調(diào)用system函數(shù)來執(zhí)行拼接好的命令  
  18.  
  19. else if(x==2){  
  20. system("shutdown -a");//取消自動(dòng)關(guān)機(jī)的dos命令  
  21.  
  22. system("pause");  
  23. return 0;  
  24.  

這段代碼里,我們使用itoa函數(shù),把數(shù)字轉(zhuǎn)換為字符串,再是有那個(gè)strcat函數(shù)進(jìn)行拼接,最后調(diào)用system函數(shù)執(zhí)行命令。一定要深究的話,itoa并不是標(biāo)準(zhǔn)的C語言函數(shù),但大多數(shù)編譯器里都有它。

我們知道,system函數(shù)的返回值是數(shù)字,表示執(zhí)行成功或具體什么錯(cuò)誤。那么如果我們想分析它的輸出結(jié)果,或者用它執(zhí)行別的C程序,控制輸入的內(nèi)容呢?其實(shí)也很簡單,就是用DOS命令中的重定向符“< > << >>”,讓命令從文件中讀取輸入信息,或者把顯示信息輸出到文件。這樣我們可以通過操作文件,來具體進(jìn)行控制了。當(dāng)年我擔(dān)任C語言課程助教的時(shí)候,就用這個(gè)思路寫了一個(gè)自動(dòng)評測學(xué)生作業(yè)代碼的程序。

就算這樣效率比較低,還是那句話,“有什么關(guān)系呢?”我反對讓新手一開始就糾結(jié)效率和優(yōu)化的問題,這樣會(huì)抹殺對編程的興趣,或者變得不敢寫代碼。只有通過大量的實(shí)踐,找到“成功實(shí)現(xiàn)一個(gè)功能”的成就感,積累足夠的信心和經(jīng)驗(yàn),才能取得長足的進(jìn)步。學(xué)得深了,再逐步探究更好的辦法,我覺得這才是合適的順序。

3、人機(jī)交互

①黑框框(控制臺(tái)界面)

入門階段,最受初學(xué)者反感的就是那個(gè)討厭的黑框框了,看見它就想起無趣的scanf和printf,感覺相差了整整一個(gè)時(shí)代……其實(shí)吧,就算是黑框框,也能玩出花兒~

01. getch語句

getch語句是一個(gè)“無回顯的、即時(shí)獲取用戶按鍵字符”的函數(shù)。也就是說,我們按一個(gè)按鍵,它不會(huì)顯示在屏幕上,也不需要按回車鍵,就能直接被getch接收到。接收的方法是: 

  1. char c;  
  2. c=getch();  

(最前面別忘了#include)

這么一個(gè)小玩意兒,它能讓我們實(shí)現(xiàn)很多的功能:游戲按鍵控制(有時(shí)需要結(jié)合上文提到的多線程)、菜單選擇輸入、輸入密碼的星號(hào)功能。此處我們來看看輸入密碼的函數(shù)實(shí)現(xiàn)吧: 

  1. //輸入密碼的函數(shù)。傳入一個(gè)字符數(shù)組,以及這個(gè)字符數(shù)組的大小  
  2. void getPassword(char password[],int length){  
  3. char c;  
  4. int i=0;  
  5. do{  
  6. c=getch();//用getch來讀取用戶輸入  
  7. if(c==' '){//密碼里是不能有空格的  
  8. continue 
  9.  
  10. if(c==''){//退格鍵的處理  
  11. if(i==0){  
  12. continue 
  13.  
  14. printf(" ");  
  15. i--;  
  16. continue 
  17.  
  18. if(c==' '){//回車鍵的處理  
  19. break;  
  20.  
  21. if(i>=length-1){//達(dá)到最大長度時(shí)的處理  
  22. continue 
  23.  
  24. password[i]=c;//存入數(shù)組  
  25. printf("*");//顯示一個(gè)星號(hào)  
  26. i++;  
  27. }while(c!=' ');  
  28. password[i]='';//字符串末尾要添加''  
  29.  

當(dāng)我們需要輸入密碼時(shí),直接調(diào)用這個(gè)函數(shù)就可以了。測試它的主函數(shù)此處就不寫啦。效果如圖(輸入的內(nèi)容自動(dòng)變成星號(hào),而且可以任意退格,按回車鍵完成輸入) 

為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序? 

02. system("cls");

還記得我們剛才說的,用system函數(shù)調(diào)用DOS命令嗎。“cls”是DOS里的“清除控制臺(tái)屏幕上的已有內(nèi)容”的命令,可以清除我們已經(jīng)輸出的全部內(nèi)容。這有什么用呢?

許多人小時(shí)候都玩過“連環(huán)畫”,在一個(gè)本子的每一頁畫上變化的圖案,快速翻動(dòng)每一頁,圖像就動(dòng)了起來。

我們也可以通過system("cls");實(shí)現(xiàn)簡單的“動(dòng)畫”效果,當(dāng)然了,刷新太快難免出現(xiàn)閃屏的現(xiàn)象,這個(gè)沒辦法,畢竟這就是個(gè)土辦法……

舉個(gè)例子,不知道大家有沒有聽說過“生命游戲”,也就是是英國數(shù)學(xué)家約翰·何頓·康威在1970年發(fā)明的細(xì)胞自動(dòng)機(jī)。給個(gè)鏈接,大家去了解一下生命游戲(游戲作品) 我們用C語言來實(shí)現(xiàn)它: 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <time.h>  
  5. const int type_live=1;  
  6. const int type_dead=0;  
  7. const int map_size=20;  
  8. int map[20][20];  
  9. void initGame();//初始化  
  10. void run();//每一輪的運(yùn)行  
  11. int getLivingNum(int x, int y);//判斷某個(gè)格子周邊有幾個(gè)存活的細(xì)胞  
  12. void show_map();//把地圖的狀態(tài)打印到屏幕上  
  13. int main()  
  14.  
  15. initGame();  
  16. while(1>0){  
  17. run();  
  18. show_map();  
  19. system("cls");  
  20.  
  21. system("pause");  
  22. return 0;  
  23.  
  24. void initGame(){//初始化  
  25. int i,j;  
  26. srand((unsigned) time(NULL));  
  27. for(i=0;i<map_size;i++){  
  28. for(j=0;j<map_size;j++){  
  29. map[i][j]=rand()%2;//每一個(gè)格子的細(xì)胞生死狀態(tài)都是隨機(jī)的  
  30.  
  31.  
  32.  
  33. void run(){//每一輪的運(yùn)行  
  34. int i,j,num;  
  35. for(i=0;i<map_size;i++){  
  36. for(j=0;j<map_size;j++){  
  37. num=getLivingNum(i,j);  
  38. //按規(guī)則決定下一輪的生死狀態(tài)  
  39. if(num==3){  
  40. map[i][j]=type_live;  
  41.  
  42. else if(num!=2){  
  43. map[i][j]=type_dead;  
  44.  
  45.  
  46.  
  47. //獲取當(dāng)前格子周邊8個(gè)格子的活著的細(xì)胞數(shù)量  
  48. int getLivingNum(int x, int y){  
  49. int i,j;  
  50. int num=0;  
  51. for(i=x-1;i<=x+1;i++){  
  52. if(i<0||i>=map_size){//防止數(shù)組下標(biāo)越界  
  53. continue 
  54.  
  55. for(j=y-1;j<=y+1;j++){  
  56. if(j<0 || j>=map_size){//防止數(shù)組下標(biāo)越界  
  57. continue 
  58.  
  59. if(map[i][j]==type_live){  
  60. num++;  
  61.  
  62.  
  63.  
  64. if(map[x][y]==type_live){  
  65. num--;  
  66.  
  67. return num;  
  68.  
  69. void show_map(){//把地圖狀態(tài)輸出到屏幕上  
  70. int i,j;  
  71. for(i=0;i<map_size;i++){  
  72. for(j=0;j<map_size;j++){  
  73. if(map[i][j]==type_live){  
  74. printf(" *");  
  75.  
  76. else if(map[i][j]==type_dead){  
  77. printf(" ");  
  78.  
  79.  
  80. printf(" ");  
  81.  
  82.  

這邊最關(guān)鍵的界面控制原理,就是用system("cls");不停的清除之前輸出的內(nèi)容,輸出一遍,清除一遍,輸出一遍,清除一遍……就能讓畫面動(dòng)起來了。給個(gè)截圖,大家自己腦補(bǔ)一下動(dòng)起來的樣子…… 

為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序? 

03.其它一些小技巧

想讓控制臺(tái)的界面更美觀一些,還有兩個(gè)小方法。一個(gè)是system("color xy");控制控制臺(tái)的背景色和字體顏色(這里的xy,x是背景色,y是前景色,不要直接填xy,而是如下的數(shù)值):

0=黑色 1=藍(lán)色 2=綠色 3=湖藍(lán)色 4=紅色 5=紫色 6=黃色 7=白色 8=灰色

9=淡藍(lán)色 A=淡綠色 B=淡藍(lán)綠色 C=淡紅色 D=淡紫色 E=淡黃色 F=亮白色

另一個(gè)是system("title 標(biāo)題");,能把程序框框左上角顯示的標(biāo)題給替換了。來個(gè)簡單的例子: 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. int main()  
  4.  
  5. system("title hello,world");  
  6. system("color B1");  
  7. system("pause");  
  8. return 0;  
  9.  

運(yùn)行效果: 

為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序? 

②C語言里的圖形庫(graphics.h)

C語言也有自己的圖形庫,我知道的是graphics.h,應(yīng)該還有別的吧,沒研究過。graphics.h好像不是標(biāo)準(zhǔn)庫,許多編程軟件里都沒有,要另外裝。我這兩天抽空研究研究,來給大家寫個(gè)例子。graphics.h_百度百科

③圖形界面

想要拿C語言實(shí)現(xiàn)真正的圖形界面程序,那沒什么好辦法,去學(xué)WindowsAPI吧,當(dāng)年我接觸過一陣子,寫了幾個(gè)小東西(就像文章一開始的那個(gè)鬧鐘的截圖),但沒有深入研究,忘得差不多了,所以現(xiàn)在實(shí)在不敢給大家講太多。而且我覺得吧,WindowsAPI實(shí)在不太適合新手去接觸,何況根本沒這個(gè)必要,有時(shí)間精力,還不如轉(zhuǎn)而去學(xué)Java或者別的更容易做圖形界面的語言呢。

4、數(shù)據(jù)存儲(chǔ)

提到數(shù)據(jù)存儲(chǔ)這塊,大家第一反應(yīng)就是“數(shù)據(jù)庫”,想到SQL語言,以及眼花繚亂的一個(gè)個(gè)數(shù)據(jù)表,好像很麻煩的樣子。其實(shí)咱們?nèi)腴T階段不需要這么復(fù)雜嘛,完全可以用自定義的文件讀寫格式來代替。(話說就算是用SQL,也沒有想象中那么復(fù)雜,這東西是“會(huì)用”容易,想“優(yōu)化好”需要更深的學(xué)問)

①文件讀寫

大家在C語言入門階段的學(xué)習(xí)中,大概是學(xué)到指針部分的前面或后面一點(diǎn)(不同的教程順序不一樣),就會(huì)學(xué)到文件讀寫的基本操作,咱們先簡單復(fù)習(xí)一下:

fopen函數(shù),以某種模式(讀、寫等等)打開一個(gè)文件流fopen_百度百科

fprintf函數(shù),簡單理解就是往文件里寫入內(nèi)容的“printf”函數(shù)fprintf_百度百科

fscanf函數(shù),簡單理解就是從文件里讀取內(nèi)容的“scanf"函數(shù),注意“讀字符串時(shí)遇到空格或換行結(jié)束”fscanf_百度百科

fgets函數(shù),從文件里讀字符串,一次讀一行,遇到換行結(jié)束,遇到空格不結(jié)束fgets_百度百科

fclose函數(shù),關(guān)閉文件流fclose_百度百科

feof函數(shù),判斷文件流是否到結(jié)束位置了feof(函數(shù)名)

這些函數(shù)就是咱們處理數(shù)據(jù)存儲(chǔ)的基本工具~

說白了,數(shù)據(jù)存儲(chǔ),就是把我們想要保存的數(shù)據(jù)儲(chǔ)存在硬盤上,留著下次(或者每次)使用,不會(huì)像那些臨時(shí)存在內(nèi)存空間里的變量那樣,隨著程序的關(guān)閉而Say Goodbye。在入門階段的項(xiàng)目實(shí)踐中,我們只需要自己規(guī)定好數(shù)據(jù)存儲(chǔ)的格式,然后在程序里按照格式讀取或?qū)懭胛募?,就OK了。

老規(guī)矩,拿例子說話~還記得開篇我做的那個(gè)“都市浮生記”嗎?它涉及到用戶游戲數(shù)據(jù)存檔功能,玩游戲玩到一半,可以存檔,然后下次接著玩~我們就來看看這部分功能的實(shí)現(xiàn):

首先,設(shè)計(jì)一個(gè)文件存儲(chǔ)結(jié)構(gòu):

我們來分析,在這個(gè)游戲中,玩家重要的臨時(shí)數(shù)據(jù)有哪些:

01. 玩家名稱Name

02. 當(dāng)前金錢數(shù)額Money

03. 當(dāng)前倉庫容量Capacity

04. 游戲進(jìn)行的天數(shù)Day

05. 庫存貨物數(shù)量Num

06. 這些具體庫存貨物的信息(貨物編號(hào)ID,數(shù)量N,進(jìn)貨價(jià)格M)

07. 由于我這個(gè)游戲當(dāng)時(shí)設(shè)計(jì)的思路,是支持別人更改數(shù)據(jù),寫擴(kuò)展包的,所以增加了一個(gè)“游戲版本名稱Version”的數(shù)據(jù)存儲(chǔ),位置放在文件開頭。

怎么樣,是不是有一種做輸入輸出練習(xí)題的既視感。其實(shí)這玩意兒改一改,添加一點(diǎn)需求,就可以是一道編程習(xí)題了。。。我們先來結(jié)合游戲和文件內(nèi)容看一看效果 

為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序? 

游戲天數(shù)不一樣是因?yàn)?ldquo;存檔的時(shí)候是第4天,但再次開始游戲時(shí)直接進(jìn)入了下一天”。  

為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序? 

這邊沒有完整顯示對應(yīng)的數(shù)據(jù),反正就是這個(gè)意思,大家意會(huì)一下~

接下來看看代碼是怎么實(shí)現(xiàn)的(兩年前的源碼了,不是很規(guī)范,我大致加了一下注釋,大家領(lǐng)會(huì)思路就好)(注意,我項(xiàng)目里用到了bool類型,C本身是沒有的,需要引用stdbool.h頭文件c語言中的使用 )。 

  1. bool READ_USER(char *filename)  
  2.  
  3. int i,n;  
  4. FILE *fp;  
  5. fp=fopen(user.filename,"r");//以只讀模式打開文件  
  6. if(fp==NULLreturn false;//文件打開失敗……  
  7. fgets(user.bagname,100,fp);//讀取版本號(hào)  
  8. user.bagname[strlen(user.bagname)-1]='';/*我忘了當(dāng)年寫這句話是干嘛了,莫非fgets不會(huì)自動(dòng)添加''嗎,還是我自作多情?現(xiàn)在有點(diǎn)忘了,大家可以自己測試一下,評論里告訴我。*/  
  9. if(strcmp(user.bagname,area[0])!=0)//對比存檔的版本和當(dāng)前游戲版本是否相同  
  10.  
  11. printf("存檔文件與當(dāng)前擴(kuò)展數(shù)據(jù)包不匹配! ");  
  12. return false;//版本不同,再見吧~  
  13.  
  14. fgets(user.name,100,fp);//讀取玩家名字  
  15. user.name[strlen(user.name)-1]='';//同上面那個(gè)''的注釋  
  16. fscanf(fp,"%lld %d %d ",&user.money,&user.storage,&user.day);//讀取金錢、倉庫容量、游戲天數(shù)  
  17. fscanf(fp,"%d ",&user.cargo_amount);//讀取庫存商品數(shù)量  
  18. user.be_used=0;//忘了是干嘛的了  
  19. for(i=0;i<user.cargo_amount;i++)//循環(huán)讀取每個(gè)商品的信息  
  20.  
  21. fscanf(fp,"%d ",&n);//讀取商品id  
  22. fscanf(fp,"%d %d ",&user.cargo[n].amount,&user.cargo[n].total_price);//讀取該商品的數(shù)量、價(jià)錢  
  23. user.be_used=user.be_used+user.cargo[n].amount;//好像是計(jì)算已使用的庫存容量?  
  24.  
  25. fclose(fp);//關(guān)閉文件  
  26. WRITE_RECORD();//自己定義的另一個(gè)函數(shù),好像是寫排行榜來著  
  27. return true;//返回true,表示成功讀取了存檔數(shù)據(jù)文件  
  28.  

然后再看看保存存檔(寫文件)的那個(gè)函數(shù)吧: 

  1. void WRITE_USER(char *filename)  
  2.  
  3. int i;  
  4. FILE *fp;  
  5. fp=fopen(user.filename,"w");//以寫的模式打開文件流,如果文件不存在則新建一個(gè)。  
  6. fprintf(fp,"%s ",user.bagname);//輸出游戲版本名稱  
  7. fprintf(fp,"%s ",user.name);//輸出玩家姓名  
  8. fprintf(fp,"%lld %d %d ",user.money,user.storage,user.day);//金錢、倉庫、天數(shù)  
  9. fprintf(fp,"%d ",user.cargo_amount);//商品數(shù)量  
  10. for(i=0;i<goods_amount;i++)//循環(huán)輸出商品信息  
  11.  
  12. if(user.cargo[i].amount!=0) fprintf(fp,"%d %d %lld ",i,user.cargo[i].amount,user.cargo[i].total_price);  
  13.  
  14. fclose(fp);//關(guān)閉文件流  
  15.  

就是這么簡單粗暴的辦法,自己規(guī)定文件結(jié)構(gòu),用簡單的文件讀寫函數(shù)進(jìn)行操作,就可以實(shí)現(xiàn)簡單的數(shù)據(jù)存儲(chǔ)功能。我另一個(gè)背單詞的小軟件也是用這個(gè)思路處理的,當(dāng)時(shí)還特意寫了一個(gè)轉(zhuǎn)換程序,把我從百度文庫搞下來的單詞詞庫(復(fù)制到txt里的),轉(zhuǎn)換成程序需要的格式。

②數(shù)據(jù)庫操作

當(dāng)然了,這種簡單粗暴的方法,不適于大規(guī)模的數(shù)據(jù)存儲(chǔ),因?yàn)椴环奖悴樵兒托薷模荒苁浅鯇W(xué)階段的“權(quán)宜之計(jì)”(當(dāng)然了,在實(shí)際開發(fā)中,小規(guī)模數(shù)據(jù),尤其是允許用戶自行修改的配置文件,也可以用類似的思路去處理)。如果要處理大規(guī)模數(shù)據(jù),還是規(guī)范一點(diǎn),操作數(shù)據(jù)庫吧。

操作數(shù)據(jù)庫,首先需要學(xué)習(xí)基本的SQL語法。這個(gè)不是很難,理解基本概念,然后照著格式寫就行。SQL教程_w3cschool

其次,就要考慮如何與數(shù)據(jù)庫連接。首先你要安裝一個(gè)數(shù)據(jù)庫,比如MySQL……然后需要學(xué)習(xí)C語言連接數(shù)據(jù)庫的方法,這塊我也沒試過(我一般拿Java和PHP對接數(shù)據(jù)庫,沒試過直接用C寫),所以抱歉沒法詳細(xì)介紹。給兩個(gè)鏈接大家感受一下吧。c語言連接mysql數(shù)據(jù)庫的實(shí)現(xiàn)方法_C 語言 , 用C語言操作MySQL數(shù)據(jù)庫,進(jìn)行連接、插入、修改、刪除等操作 。個(gè)人認(rèn)為,在初學(xué)階段的項(xiàng)目實(shí)踐中,不是非得死磕數(shù)據(jù)庫。最好換個(gè)更方便的語言去學(xué)數(shù)據(jù)庫,學(xué)明白了,真要深入探索,增加效率神馬的,再換回C繼續(xù)深入。

5、網(wǎng)絡(luò)通信

入門階段的項(xiàng)目實(shí)踐中,用到網(wǎng)絡(luò)通信的情況不多見,實(shí)在不建議大家剛上來就挑戰(zhàn)CS架構(gòu)(客戶端-服務(wù)端的架構(gòu))甚至BS架構(gòu)(瀏覽器前端-服務(wù)端的架構(gòu))的項(xiàng)目,要學(xué)的東西挺多的。

當(dāng)然,如果只是想簡單實(shí)現(xiàn)兩個(gè)程序的聯(lián)機(jī)通信,學(xué)習(xí)Socket編程接口,照著網(wǎng)上的樣例代碼改就可以了。今天本來想試試的,結(jié)果發(fā)現(xiàn)自己的IDE沒有對應(yīng)的庫文件,按網(wǎng)上的方法折騰了一下沒有搞定,過兩天折騰清楚了再跟大家分享吧。先丟幾個(gè)鏈接在這兒,感興趣的也可以一塊試一試。

socket(計(jì)算機(jī)專業(yè)術(shù)語)

C語言的Socket編程例子(TCP和UDP)

使用dev-c++做socket編程遇到的問題和解決過程

總之呢還是那句話,我覺得初學(xué)者可以暫時(shí)不接觸C語言的網(wǎng)絡(luò)通信,想做涉及網(wǎng)絡(luò)通信的程序,可以轉(zhuǎn)Java、PHP、Python之類的語言,更方便一些。然后需要輔以學(xué)習(xí)計(jì)算機(jī)網(wǎng)絡(luò)原理之類的理論基礎(chǔ)。初步掌握之后,再想深入底層原理,轉(zhuǎn)回C語言也不遲。

使用C語言圖形庫寫的“吃豆人”小游戲:  

為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序? 

關(guān)于C語言Socket編程,從網(wǎng)上找的代碼,調(diào)試通了,這是服務(wù)端,客戶端沒截圖:  

為什么學(xué)完了c語言,我只會(huì)寫計(jì)算機(jī)程序?

 

責(zé)任編輯:龐桂玉 來源: 今日頭條
相關(guān)推薦

2010-11-03 09:22:00

C語言

2023-09-27 23:38:29

C程序

2011-12-01 10:55:16

超級(jí)計(jì)算機(jī)高性能計(jì)算Top500

2024-02-22 08:17:31

十六進(jìn)制數(shù)字計(jì)算

2012-12-16 15:26:49

超級(jí)計(jì)算機(jī)LinuxHPC

2020-12-14 08:00:31

計(jì)算機(jī)計(jì)數(shù)程序

2013-03-04 09:46:06

2020-08-31 14:56:24

補(bǔ)碼存儲(chǔ)數(shù)據(jù)

2019-06-26 08:30:32

計(jì)算機(jī)互聯(lián)網(wǎng)iOS

2013-08-23 14:22:45

SA系統(tǒng)管理員運(yùn)維

2022-11-28 09:58:58

C++開發(fā)

2023-01-24 16:13:22

編程語言JavaIT

2012-06-20 10:40:36

量子計(jì)算機(jī)

2020-07-27 07:27:03

程序員技術(shù)編碼

2020-05-13 09:03:14

Python開發(fā)代碼

2020-04-01 17:50:02

Python編程語言

2011-10-14 09:20:48

Lisp

2023-07-07 10:53:08

2020-10-11 20:46:41

計(jì)算機(jī)人工智能技術(shù)

2019-09-10 12:58:03

電腦編程語言硬件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)