為什麼學c語言我只會寫計算程序?

學了好幾個月c零零碎碎的,數組指針也知道,練手也練了不少計算型的玩具程序,接下來幹嘛?小遊戲程序比如貪食蛇這種,代碼看不太懂,是不是還要學其它什麼?


以前學C語言的時候,寫過幾個小程序,還算蠻有意思的。先上程序截圖,佔個坑,然後再慢慢講做這種小玩意的通用思路。

1、貪吃蛇:

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

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

4、C語言結合WindosAPI實現的圖形界面鬧鐘

-------先佔著坑,努力碼字中--------

首先我們需要知道,一款軟體究竟有哪幾個部分?

在這裡我們不談軟體架構神馬的專業知識,就站在入門水平能理解的角度思考,我覺得可以分為5個部分:

1、業務演算法

指的是解決具體問題的思路。比如做一款背單詞軟體,你怎麼隨機抽取單詞,用什麼規則去判斷用戶是否掌握了這個單詞,這就是業務演算法。

2、控制邏輯

控制邏輯是除了業務邏輯之外,關於整體程序控制層面的演算法,比如怎麼去實現一個鏈表,怎麼去實現圖的搜索,或者如何處理線程同步,等等。

3、人機交互

簡單來說就是界面。比如C語言的控制台(「黑框框」)最基本的人機交互就是輸入和輸出。圖形化界面就複雜得多,標籤、輸入框、按鈕、圖形繪製、事件監聽等等。如果做移動開發,還可能涉及到各種感測器。

4、數據存儲

小程序不需要外部的數據存儲,只有程序內部的變數、常量、靜態數值。想要功能豐富一點,比如小遊戲的排行榜、單詞軟體的單詞庫等等,就需要考慮數據存儲的問題。簡單一點可以用基本的文件讀寫,自己規定數據存儲的格式。複雜一點就需要用到資料庫了。

5、網路通信

普通單機程序用不到網路通信。但如果要做網路程序,比如區域網對戰遊戲、CS結構的企業管理軟體、BS結構的商城平台,等等,就需要考慮網路通信的功能。有各種網路協議,底層一點可以是TCP/IP,往上走的話有封裝好的Socket介面,再往上走還有HTTP、FTP等等具體的應用協議。

梳理清楚這五個部分,我們再來看看,入門階段我們學C語言學了什麼?

首先是基礎的程序語言知識,從輸入輸出、變數、分支語句、循環語句,到數組、函數、指針、結構體、文件讀寫,基本就學完了。

然後可能還接觸了一些簡單的演算法和數據結構,比如排序、遞歸、棧、隊列等等。再複雜一些,可能會接觸樹的遍歷、圖的搜索、甚至是動態規劃。

我們看看這些知識屬於哪些模塊?

1、它們解決業務邏輯不成問題,畢竟我們做的很多習題,都是真實情境抽象出來的演算法。

2、它能解決一部分簡單的控制邏輯。這主要看你演算法與數據結構學的如何。當然,涉及到設計模式、多線程、事件監聽、以及系統層面的控制內容,我們還沒學到。

3、人機交互,只學了簡單的輸入輸出。

4、數據存儲,可以用文件讀寫。

5、網路通信,暫時沒接觸。

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

--------佔個坑,明天再來簡單介紹一些具體的解決方案--------

還是昨天提到的5個方面,我們一個一個來解決。

1、業務演算法

這個不需要額外的技術了,入門階段學到的知識基本夠用,但我們要學會歸納項目需求,並把它們抽象出來,轉化為平常做的習題的形式,「能獲取什麼數據、進行怎樣的計算、要得到什麼結果」。當然了,思考的時候並不是這個順序,而是「要得到什麼結果,需要什麼數據,要進行怎樣的計算」。

2、控制邏輯

前面說到,首先這需要你的演算法與數據結構基礎。至少要學會數組、結構體、排序、鏈表、遞歸等等,掌握得越多,這塊就越輕鬆一些。當然了,這畢竟不是競賽,自己做項目實踐的時候,沒有人強制規定你「在1s內完成,內存空間不超過65535KB」,所以哪怕入門階段會的少,效率低一些,也沒關係,首先做到「能用」,再考慮優化。

那麼複雜一些的控制邏輯問題怎麼處理呢?

①多線程

需要調用系統介面。以windows系統為例,需要調用WindosAPI,也就是windows.h庫中的函數。初學階段,我們可以「不知其所以然」,會套用就行。

舉例:

問題情境:在貪吃蛇遊戲中,我們需要一遍不停的讓蛇向當前的方向移動,一邊獲取用戶輸入的控制信息。我們知道,C語言在使用任何一個輸入函數的時候,都會等待用戶的輸入,然後再進行下面的語句。所以我們必須在一個單獨的線程里監聽用戶的輸入,否則會導致「用戶不輸入內容,蛇就不移動」的情況。

實現方法(部分代碼):

#include &
#include &
#include &
char c;//存儲用戶輸入的按鍵字元的全局變數。
DWORD WINAPI getOrder();//子線程調用的方法,用來等待用戶輸入控制命令
int main()
{
CreateThread(NULL,NULL,getOrder,NULL,0,NULL);
while(1){ //控制貪吃蛇不停的移動
switch(c){
//處理wsad四個字元的情況,像上下左右移動
}
}
return 0;
}
DWORD WINAPI getOrder(){
while(1){
c=getch();//不停的等待用戶的輸入
//此處默認用戶按的肯定是wsad四個按鍵,沒有處理錯誤情況。真正寫代碼需要考慮。
}
}

此處關於多線程的部分,是我當年寫貪吃蛇程序時,臨時上網搜索,直接按人家的格式套用的。說實話,我到現在也不明白CreateThread裡面的幾個NULL和0分別需要設置什麼(後來深入研究Java去了,一入Java深似海,沒再深究C語言WindowsAPI的問題)。

至於說CreateThread不穩定不安全,實際編程里不推薦使用,而是要用_beginthread。對於初學階段,這有什麼關係呢?就像我們小學、初中學數學的時候,課本里也把很多概念簡化了,並不嚴謹。我們使用它,是為了幫助我們邁過項目實踐里的攔路虎,實現自己想要的功能,真要是以後打算深入研究,再搞明白「為什麼」、「什麼好」也不遲。(當然了,如果願意多花一些時間,按網上的說法,去學習_beginthread怎麼使用,一步到位,也沒有問題,此處給個鏈接: C語言多線程編程windows多線程CreateThread與_beginthreadex本質區別 )。

②實現一些與操作系統相關的功能

這個當然也可以通過WindowsAPI來實現。但還是那句話,初學階段,沒有必要。說起來有個更簡單的方法,只要會用system("");函數就行了。別看一個小小的system函數,通過它,我們可以讓系統執行各種dos命令,什麼開機關機,文件刪查,都不在話下。

當然了,要玩轉system函數也有些技巧。首先是要學會拼接字元串,比如我們要實現定時關機的命令,讓用戶輸入一個時間,我們就要把時間數字轉換成字元串,再拼接到命令裡面。

樣例代碼如下:

#include &
#include &
int main()
{
int x,t;
char command[100]="shutdown -s -t ";
char time[100];

printf("輸入1:設置定時自動關機
");
printf("輸入2:取消自動關機
");
scanf("%d",x);
if(x==1){
printf("請輸入關機時間(分鐘數):");
scanf("%d",t);
t=t*60;//把分鐘數化成秒數
itoa(t,time,10);//把數字轉換成字元串,存在time字元數組裡
strcat(command,time);//拼接命令
system(command);//調用system函數來執行拼接好的命令
}
else if(x==2){
system("shutdown -a");//取消自動關機的dos命令
}
system("pause");
return 0;
}

這段代碼里,我們使用itoa函數,把數字轉換為字元串,再是有那個strcat函數進行拼接,最後調用system函數執行命令。一定要深究的話,itoa並不是標準的C語言函數,但大多數編譯器里都有它。

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

就算這樣效率比較低,還是那句話,「有什麼關係呢?」我反對讓新手一開始就糾結效率和優化的問題,這樣會抹殺對編程的興趣,或者變得不敢寫代碼。只有通過大量的實踐,找到「成功實現一個功能」的成就感,積累足夠的信心和經驗,才能取得長足的進步。學得深了,再逐步探究更好的辦法,我覺得這才是合適的順序。

------------暫時就增加這麼多,後續內容有空再來寫----------------------

(睡前來寫一點內容,最近經常忙到凌晨兩點,實在有點撐不住,今兒早點睡)

3、人機交互

①黑框框(控制台界面)

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

01. getch語句

getch語句是一個「無回顯的、即時獲取用戶按鍵字元」的函數。也就是說,我們按一個按鍵,它不會顯示在屏幕上,也不需要按回車鍵,就能直接被getch接收到。接收的方法是:

char c;
c=getch();

(最前面別忘了#include&

這麼一個小玩意兒,它能讓我們實現很多的功能:遊戲按鍵控制(有時需要結合上文提到的多線程)、菜單選擇輸入、輸入密碼的星號功能。此處我們來看看輸入密碼的函數實現吧:

//輸入密碼的函數。傳入一個字元數組,以及這個字元數組的大小
void getPassword(char password[],int length){
char c;
int i=0;
do{
c=getch();//用getch來讀取用戶輸入
if(c==" "){//密碼里是不能有空格的
continue;
}
if(c==""){//退格鍵的處理
if(i==0){
continue;
}
printf(" ");
i--;
continue;
}
if(c=="
"){//回車鍵的處理
break;
}
if(i&>=length-1){//達到最大長度時的處理
continue;
}
password[i]=c;//存入數組
printf("*");//顯示一個星號
i++;
}while(c!="
");
password[i]="";//字元串末尾要添加""
}

當我們需要輸入密碼時,直接調用這個函數就可以了。測試它的主函數此處就不寫啦。效果如圖(輸入的內容自動變成星號,而且可以任意退格,按回車鍵完成輸入)

02. system("cls");

還記得我們剛才說的,用system函數調用DOS命令嗎。「cls」是DOS里的「清除控制台屏幕上的已有內容」的命令,可以清除我們已經輸出的全部內容。這有什麼用呢?

許多人小時候都玩過「連環畫」,在一個本子的每一頁畫上變化的圖案,快速翻動每一頁,圖像就動了起來。

我們也可以通過system("cls");實現簡單的「動畫」效果,當然了,刷新太快難免出現閃屏的現象,這個沒辦法,畢竟這就是個土辦法……

舉個例子,不知道大家有沒有聽說過「生命遊戲」,也就是是英國數學家約翰·何頓·康威在1970年發明的細胞自動機。給個鏈接,大家去了解一下生命遊戲(遊戲作品) 我們用C語言來實現它:

#include &
#include &
#include &
#include &
const int type_live=1;
const int type_dead=0;
const int map_size=20;

int map[20][20];

void initGame();//初始化
void run();//每一輪的運行
int getLivingNum(int x, int y);//判斷某個格子周邊有幾個存活的細胞
void show_map();//把地圖的狀態列印到屏幕上

int main()
{
initGame();
while(1&>0){
run();
show_map();
system("cls");
}
system("pause");
return 0;
}
void initGame(){//初始化
int i,j;
srand((unsigned) time(NULL));
for(i=0;i&=map_size){//防止數組下標越界
continue;
}
for(j=y-1;j&<=y+1;j++){ if(j&<0 || j&>=map_size){//防止數組下標越界
continue;
}
if(map[i][j]==type_live){
num++;
}
}
}
if(map[x][y]==type_live){
num--;
}
return num;
}
void show_map(){//把地圖狀態輸出到屏幕上
int i,j;
for(i=0;i&

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

03.其它一些小技巧

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

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

9=淡藍色 A=淡綠色 B=淡藍綠色 C=淡紅色 D=淡紫色 E=淡黃色 F=亮白色

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

#include &
#include &
int main()
{
system("title hello,world");
system("color B1");
system("pause");
return 0;
}

運行效果:

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

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

③圖形界面

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

====撐不住了得去睡覺了====

今天去中關村參加了一個小型創業分享沙龍,北京高校畢業生就業指導中心辦的,雖然人少,但收穫頗多,講者大兵老師(鄒秀峰(大兵老師))很有思想。在大會上我把大家拉了一個群,會後希望把這個群擴大起來,認真去辦成一個優質的大學生創業交流社群。

所以忙到現在,抱歉沒來得及更新。看到大家這麼期待,我真是受寵若驚啊~所以還是熬夜更新一段,剩下的明天繼續寫。

至於社群那個事兒,因為暫時還沒有想好完善的社群規則,所以不好做推廣,有心往創業方向走的大學生可以私信我~

====今晚我會寫的,佔個位====

(話說之前提到的要寫C語言圖形庫(graphics.h)的樣例,明天盡量補上,如果實在沒精力,下周肯定補)

4、數據存儲

提到數據存儲這塊,大家第一反應就是「資料庫」,想到SQL語言,以及眼花繚亂的一個個數據表,好像很麻煩的樣子。其實咱們入門階段不需要這麼複雜嘛,完全可以用自定義的文件讀寫格式來代替。(話說就算是用SQL,也沒有想像中那麼複雜,這東西是「會用」容易,想「優化好」需要更深的學問)

①文件讀寫

大家在C語言入門階段的學習中,大概是學到指針部分的前面或後面一點(不同的教程順序不一樣),就會學到文件讀寫的基本操作,咱們先簡單複習一下:

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

fprintf函數,簡單理解就是往文件里寫入內容的「printf」函數fprintf_百度百科

fscanf函數,簡單理解就是從文件里讀取內容的「scanf"函數,注意「讀字元串時遇到空格或換行結束」fscanf_百度百科

fgets函數,從文件里讀字元串,一次讀一行,遇到換行結束,遇到空格不結束fgets_百度百科

fclose函數,關閉文件流fclose_百度百科

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

這些函數就是咱們處理數據存儲的基本工具~

說白了,數據存儲,就是把我們想要保存的數據儲存在硬碟上,留著下次(或者每次)使用,不會像那些臨時存在內存空間里的變數那樣,隨著程序的關閉而Say Goodbye。在入門階段的項目實踐中,我們只需要自己規定好數據存儲的格式,然後在程序里按照格式讀取或寫入文件,就OK了。

老規矩,拿例子說話~還記得開篇我做的那個「都市浮生記」嗎?它涉及到用戶遊戲數據存檔功能,玩遊戲玩到一半,可以存檔,然後下次接著玩~我們就來看看這部分功能的實現:

首先,設計一個文件存儲結構:

我們來分析,在這個遊戲中,玩家重要的臨時數據有哪些:

01. 玩家名稱Name

02. 當前金錢數額Money

03. 當前倉庫容量Capacity

04. 遊戲進行的天數Day

05. 庫存貨物數量Num

06. 這些具體庫存貨物的信息(貨物編號ID,數量N,進貨價格M)

07. 由於我這個遊戲當時設計的思路,是支持別人更改數據,寫擴展包的,所以增加了一個「遊戲版本名稱Version」的數據存儲,位置放在文件開頭。

怎麼樣,是不是有一種做輸入輸出練習題的既視感。其實這玩意兒改一改,添加一點需求,就可以是一道編程習題了。。。我們先來結合遊戲和文件內容看一看效果

遊戲天數不一樣是因為「存檔的時候是第4天,但再次開始遊戲時直接進入了下一天」。

這邊沒有完整顯示對應的數據,反正就是這個意思,大家意會一下~

接下來看看代碼是怎麼實現的(兩年前的源碼了,不是很規範,我大致加了一下注釋,大家領會思路就好)(注意,我項目里用到了bool類型,C本身是沒有的,需要引用stdbool.h頭文件c語言中&的使用 )。

bool READ_USER(char *filename)
{
int i,n;
FILE *fp;
fp=fopen(user.filename,"r");//以只讀模式打開文件
if(fp==NULL) return false;//文件打開失敗……
fgets(user.bagname,100,fp);//讀取版本號
user.bagname[strlen(user.bagname)-1]="";/*我忘了當年寫這句話是幹嘛了,莫非fgets不會自動添加""嗎,還是我自作多情?現在有點忘了,大家可以自己測試一下,評論里告訴我。*/
if(strcmp(user.bagname,area[0])!=0)//對比存檔的版本和當前遊戲版本是否相同
{
printf("存檔文件與當前擴展數據包不匹配!
");
return false;//版本不同,再見吧~
}
fgets(user.name,100,fp);//讀取玩家名字
user.name[strlen(user.name)-1]="";//同上面那個""的注釋
fscanf(fp,"%lld %d %d
",user.money,user.storage,user.day);//讀取金錢、倉庫容量、遊戲天數
fscanf(fp,"%d
",user.cargo_amount);//讀取庫存商品數量
user.be_used=0;//忘了是幹嘛的了
for(i=0;i&

然後再看看保存存檔(寫文件)的那個函數吧:

void WRITE_USER(char *filename)
{
int i;
FILE *fp;
fp=fopen(user.filename,"w");//以寫的模式打開文件流,如果文件不存在則新建一個。
fprintf(fp,"%s
",user.bagname);//輸出遊戲版本名稱
fprintf(fp,"%s
",user.name);//輸出玩家姓名
fprintf(fp,"%lld %d %d
",user.money,user.storage,user.day);//金錢、倉庫、天數
fprintf(fp,"%d
",user.cargo_amount);//商品數量
for(i=0;i&

就是這麼簡單粗暴的辦法,自己規定文件結構,用簡單的文件讀寫函數進行操作,就可以實現簡單的數據存儲功能。我另一個背單詞的小軟體也是用這個思路處理的,當時還特意寫了一個轉換程序,把我從百度文庫搞下來的單詞詞庫(複製到txt里的),轉換成程序需要的格式。

②資料庫操作

當然了,這種簡單粗暴的方法,不適於大規模的數據存儲,因為不方便查詢和修改,只能是初學階段的「權宜之計」(當然了,在實際開發中,小規模數據,尤其是允許用戶自行修改的配置文件,也可以用類似的思路去處理)。如果要處理大規模數據,還是規範一點,操作資料庫吧。

操作資料庫,首先需要學習基本的SQL語法。這個不是很難,理解基本概念,然後照著格式寫就行。SQL教程_w3cschool

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

剩下的內容不多了,因為我也沒試過用C寫網路通信,明天簡單寫完最後一部分內容,然後改天有空再花時間試一試C的網路通信和那個圖形庫,後續一定會補充進來。最近這幾天忙瘋了,創業階段事情太多。。。

======大家晚安,明天見=====

5、網路通信

入門階段的項目實踐中,用到網路通信的情況不多見,實在不建議大家剛上來就挑戰CS架構(客戶端-服務端的架構)甚至BS架構(瀏覽器前端-服務端的架構)的項目,要學的東西挺多的。

當然,如果只是想簡單實現兩個程序的聯機通信,學習Socket編程介面,照著網上的樣例代碼改就可以了。今天本來想試試的,結果發現自己的IDE沒有對應的庫文件,按網上的方法折騰了一下沒有搞定,過兩天折騰清楚了再跟大家分享吧。先丟幾個鏈接在這兒,感興趣的也可以一塊試一試。

socket(計算機專業術語)

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

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

總之呢還是那句話,我覺得初學者可以暫時不接觸C語言的網路通信,想做涉及網路通信的程序,可以轉Java、PHP、Python之類的語言,更方便一些。然後需要輔以學習計算機網路原理之類的理論基礎。初步掌握之後,再想深入底層原理,轉回C語言也不遲。

==========

要回答的內容差不多就是這些,過幾天有空了回來填前面幾個坑。感謝大家的支持和點贊~

==========

最新進展:前面留下的兩個坑都研究得差不多了,但這兩天有點忙,可能要周四左右才能詳細去寫。先放兩張圖吧:

使用C語言圖形庫寫的「吃豆人」小遊戲:

關於C語言Socket編程,從網上找的代碼,調試通了,這是服務端,客戶端沒截圖:

大家等星期四左右來看我的更新吧~

================

上圖的圖形程序,我是用C語言EGE圖形庫寫的。IDE用的是DevC++。說實話,寫程序只花了不到兩小時,但配置編譯環境折騰了不止兩小時……

先給一個EGE的官網地址: Easy Graphics Engine

然後我把DevC++的安裝包、EGE相關文件都上傳到網盤了,也自己寫了一份完整的安裝配置教程,大家可以跟著做應該就能裝好:鏈接:http://pan.baidu.com/s/1jIbOu2M 密碼:bbse

EGE的官網有詳細的使用教程,說實話只要環境搭起來,「怎麼用」就特別簡單了。大家可以自行學習。最近忙成狗,短期內就不重複造輪子了,回頭抽空把那個吃豆人遊戲代碼優化一下,寫好注釋,再提供給大家下載。

=================

我有個編程交流QQ群,歡迎來水。

群號87675086

http://qm.qq.com/cgi-bin/qm/qr?k=O-nR6qK4Ll0O9nE8MwPuqpFQfUjXFkXQ (二維碼自動識別)


可以試試這個例子,用wasd控制行走的小人,看看會不會有啟發

知乎專欄


其實我也和題主有過類似的經歷。

個人覺得純粹的c,對於一個新手入門來說做比較有意思的程序很難,而通過學習windowsAPI或則遊戲引擎練習編程,又不是純粹的去學習語言。

如果單純的想鍛煉自己的編程能力,真心推薦去學習下數據結構。而且基本上很多數據結構書都是用c實現的。

在實現各種數據結構的過程中,你會對指針、二級指針、函數壓棧方式、演算法的掌握都會爛熟於心,這樣不僅僅鍛煉了編程能力,也形成了自己的一套編程風格。

推薦書籍《數據結構與演算法分析(c語言描述)》或則《演算法導論》。

其實作為初學者最喜歡懷疑自己學的東西的實用性。單獨的說C這門語言,它的庫太少了,如果想實現比較具體的功能的程序很難,特別是在沒學其他東西的情況下就只能在控制台內進行輸入輸出。與其被這些花紅柳綠的工具迷惑,還不如安分的學習演算法,去實現各種數據結構。漸漸的你就會發現,你對語言的掌握越來越熟練,進而也形成了一套屬於自己的編程思維,並且演算法思想是通用的,學習數據結構的性價比肯定遠大於寫一些有的沒的「玩具」遊戲。

願題主沉下心去學習編程,不要跟風新技術,不要去站語言的隊!


謝邀。

我猜題主是想說怎麼寫桌面應用程序,窗口帶UI,滑鼠點一點,這種吧。

說實在我也不知道怎麼用C寫窗口,現在應該也沒有用c干這個活的。

學學c++,然後上框架或者遊戲引擎吧。


2017.06.15更新

花了一周時間做出並完善了Flappy Bird,目前功能如下:

1. 背景的顯示

2. 加入小鳥image

3. 小鳥自由下落,按空格鍵/滑鼠右鍵後上升

4. 加入靜態的障礙物

5. 障礙物向左移動

6. 判斷碰撞

7. 障礙物移動出左邊界後,在右邊重新出現

8. 記分模塊

9. 加入開始界面、結束界面

10. 加入背景音樂

11.加入最高分統計(待完成)

途中用到的lib、dll、頭文件如下:

1.#include &

2.#include &

#include &

#include &

#include &

#include &

#include "mmsystem.h"

winmm.lib

EasyX圖形庫

成品 Flappy bird 截圖如下:

不過也有瑕疵 ,柱子左移偏慢,利用putimage會造成明顯的位移效果,以後有空再修改

做完之後感覺還挺爽的2333,打算下次做國際象棋的Game

原答案如下:

不邀自來,題主可以學習EasyX的使用,渣作如下:

1.國際象棋棋盤繪製

2.彈球(七彩漸變,且遇屏幕反彈,反彈方向隨機)

3.時鐘(精確到秒,準備完善程序,畫上刻度)

運用EasyX圖形庫,利用圖形素材做一些簡單的遊戲,給C語言學習增加一些樂趣。

下面貼乾貨鏈接:

EasyX安裝包下載鏈接:

下載 -- EasyX Library for C++

怎樣安裝 EasyX? -- EasyX Library for C++

怎樣使用 EasyX?(Visual C++ 6.0) -- EasyX Library for C++

怎樣使用 EasyX?(Visual C++ 2008) -- EasyX Library for C++

官網還提供了一套非常好的入門教程,大家可以自學:
VC繪圖/遊戲簡易教程--前言 -- EasyX Library for C++
對應的目錄:
–前言
–1:創建新項目
–2:簡單繪圖,學習單步執行
–3:熟悉更多的繪圖語句
–4:結合流程式控制制語句來繪圖
–5:數學知識在繪圖中的運用
–6:實現簡單動畫
–7:捕獲按鍵,實現動畫的簡單控制
–8:用函數簡化相同圖案的製作
–9:繪圖中的位運算
–10:用滑鼠控制繪圖/遊戲程序
–11:隨機函數
–12:數組
–13:getimage / putimage / loadimag / saveimage / IMAGE 的用法
–14:通過位運算實現顏色的分離與處理
–15:窗體句柄(Windows 編程入門)
–16:設備上下文句柄(Windows 編程入門2)

另外推薦關注河海大學C語言老師,童晶老師,非常嚴謹踏實、致力於入門教學的老師,比我渣郵的本科老師在精力上投入真的是不能比。

他的賬戶:

童晶 - 知乎

他在知乎有專欄:

做遊戲,學編程(C語言) 2016大一上同學開發的部分遊戲效果 - 知乎專欄

正在學習中,望共勉:-)

以上。


為什麼你會有這種感受?因為c語言本身就是辦大事的。比如寫操作系統。優勢是在於性能。在於代碼轉換成彙編以後。在邏輯上能夠用機器指令比較好的對應。這是c編譯器的功勞。debug可靠。這一點是c家家做不到的。

也許在你心中很多軟體很多程序,是和王者榮耀一樣的。是QQ軟體一樣的。計算機的世界是超級複雜的。應用軟體和系統軟體和操作系統是完全不同的抽象。

越是上層的東西,就越容易理解,越接近人的現實生活。底層的東西不過是數字標誌對應的映射關係。

在你理解了那些基礎的c語言的語法以後。你完全可以看懂linux內存管理模塊的很多東西了。操作系統根本就沒有用到c那麼多 lib的東西。你可以去嘗試一下。

一旦嘗試,你就會發現,簡單的規則,可以創造出複雜的邏輯,高級別的抽象。就像鋼琴的88個鍵可以彈出多少個不同曲子。c語言的美在於他給了你一個最簡單的工具,去體會這個計算機的體系是怎麼回事。

最核心的不是那些語法。那些語法是可以查工具書,查網路資料都搞的明白的。而是你寫好的程序到底是怎樣運行的?在操作系統的級別上是怎樣運行的,在彙編語言的程度上是怎樣運行的呢?怎樣使用各種系統調用和外設的。這些才是真正考驗功夫的地方。

c語言函數調用對應的棧指針的運動,曾經讓我震撼。

棧指針,怎麼把硬體,內存與(編譯器演化的代碼來運算的)聯繫起來的。真的是一個天才的設計。而且居然連操作系統都可以很好的利用棧指針的這種設計。一點都不需要改動。這些東西就像空氣一樣被你忽略了。其實非常的重要。

等你把這些東西搞清楚以後,這些東西很多人都搞清楚了。雖然比例不是很高。那就是高手了。才能夠談後面更複雜的演算法的設計。演算法的設計是純數學的反而顯得簡單。


寫貪食蛇,俄羅斯方塊等需要更改字元輸出坐標的遊戲,一,用一個可以佔滿屏幕的字元串填,哪個位置該填什麼需要自己計算,你可以寫個函數專門負責計算把坐標轉換成相應的字元串位置。二,藉助win32api,但是年代太久遠了,我已經忘了是哪個api了。。。百度一下吧,還有更改字元顏色的api,想當年我寫了一個控制台彩色版的俄羅斯方塊就是藉助這個api


C語言和操作系統 編譯器 CPU這幾個聯繫很緊,單純C語言不藉助os提供的API 寫不出什麼有意思的東西

你要列印都要藉助printf函數,我大一就學了C語言,然後以為這個語言沒什麼用,直到大四做單片機畢業設計 才第一次真正意義上 將C語言應用到實踐中


「小遊戲程序比如貪食蛇這種,代碼看不太懂」...

只能說~基礎還沒學好...

對控制台(黑框?)有怨念的話去試試MFC吧


刷題的意義在哪裡


@Milo Yip可以關注葉先生的專欄,其中有從零開始的json庫教程,定位就是剛入門c的beginner


QQ連連看的自動消除外掛(很基礎很簡單)。

各種網遊用moust_event, keybd_event做模擬登錄。


C++小白,問個問題哈,c=a0xff 這個是什麼意思?


推薦閱讀:

c語言中x*x和pow(x,2)哪個計算更快一點?
2==c會導致的這樣的異常嗎?
c語言可以釋放數組中的單個元素結構么?
怎麼用c語言實現分形圖形?
如何通俗地解釋 C 語言中 #include<> 的用途?

TAG:程序員 | C編程語言 | 自學編程 |