你用 C 語言做過哪些有意思的事?
這兩天瀏覽知乎,發現了很多類似於用**做過什麼有意思的事,所以,就想問問大家自己用C語言做過哪些有意思的是呢?
我自己先來吧,說來貽笑大方了,就是用C寫過一個很簡單的猜數字的遊戲,比如0-100,先輸入一個數字,然後判斷大了還是小了,然後提醒糾正...
你呢,用 C 做過什麼有意思的事呢?很想看看各種奇思妙想!
用C寫了一個圖形界面的2048遊戲給老婆玩。
老婆酷愛2048,於是在網上找PC版給她玩,結果網上的全是嵌入廣告,怒寫一個!
為了方便開局,又增加了隨機開局的功能,直接從中途開始打,原始積累太慢了。
隨時可以中斷,遊戲帶存檔功能。


源碼1000+行,完全是C+winAPI,沒有MFC,沒有QT……
界面是用windows API畫的,按鈕是用CreateWindow後自繪的,沒有類,沒有對象,完全面向過程編程……
歡迎圍觀(源代碼):GitHub - tomwillow/2048: No Ads, More Advanced 2048 Game
2016.10.14補充:
有C的基礎又想學習C+Win SDK編程的小夥伴讀《Windows程序設計 第5版》就可以了,讀到一半就可以寫我這個東西了,歡迎大家與我交流。
想打遊戲的點這裡下載:http://pan.baidu.com/s/1dEHEFCH
上初中的時候,寫過一個XV格式視頻文件的轉換器。差不多7、8年了,搜索還能看到好多下載的地方:xv轉換器 - 必應,也不知道現在是否還能用了。
當時電影資源還沒有像現在這樣遍地開花,有些片子只有在迅雷看看上面才能找到。你可以選擇把一個視頻緩存到本地,但這個緩存文件的擴展名是XV,沒法複製到MP4上面看呀。
所以我想,想辦法轉換一下吧。
那時候還不會反彙編,怎麼辦呢?我試著在在線播放的時候抓包,設想有可能在下載這一步是正常的視頻,而保存到文件的時候才變成這種XV文件。這時意外地發現有一個localhost的連接(HTTP協議)一直在傳輸數據。把地址輸到瀏覽器里,竟然直接就下載到了完整的視頻文件。
也就是說,迅雷看看在播放XV文件的時候,簡單地開了一個HTTP伺服器,按照需要去讀取XV的內容並轉換成正常視頻;再讓它的播放器去打開這個網路地址……
至此已經可以寫個程序,幫助用戶在開始播放XV文件時下載到真實視頻。不過我還想從文件的級別直接解決。
把XV和真實視頻放在一起對比,可以發現二者大小差了剛好2MB。果斷跳轉到XV文件的2MB處,發現大部分位元組都是一個固定的數字,而視頻文件的對應位置都是0。於是猜想是所有位元組都加了一個固定值,試驗一下不對。又想到可能是異或運算,因為以前看到過別人這樣「加密」文本文件。馬上驗證,果然從XV文件得到了正確的視頻。
那怎麼讓程序從任給的XV文件,找出這個異或運算的「密鑰」呢?正常的想法是從XV的前2MB文件頭裡面找,或者直接統計2MB處出現最多的位元組(這不可靠)。不過我想了個更方便的方法:
枚舉0~255,對2MB處的前幾個位元組做一下異或,看是否得到了常見視頻格式(FLV、MP4……)的文件頭(例如FLV的前三個位元組應該是FLV)。
於是把這個特別簡單的小程序發到網上,莫名其妙地火起來了。每天有很多人發郵件來,可惜沒有一個統計用戶數的設計。
然後覺得這樣做太危險了,就跑去學了數學。
看到這個問題,情不自禁想起了大學時光。大學的時候自己一個人在寢室悶頭搞了幾個月寫的遊戲,滿滿都是回憶。廢話不說先上圖。






當時開了windows程序設計的課程,玩夠了黑框框,終於接觸到UI的時候忍不住想大幹一場。那幾個月每天都早上7點起來一直搞到晚上11點寢室熄燈。躺下了還在想該怎麼設計劇情,有新想法的時候激動到睡不著。
也是做完了這個遊戲開始讓我開始熱衷於遊戲開發,後面繼續學了一些dx的東西,也寫了一些3d的遊戲。滿懷期待的參加校招,結果陰差陽錯進了一家搞linux開發的公司,現在已經很久沒開發windows程序了,徹底和遊戲開發分道揚鑣了。
現在工作上的項目都高大上,但是要說有趣第一時間還是想到了在學校的日子。真懷念在學校踢球和擼代碼的時光!???????????
想體驗遊戲的請猛擊
http://pan.baidu.com/s/1hrIur0g
代碼在這裡
https://github.com/whiletest/zombie
前兩天一時興起加一個lua擴展,用來定義不同物品的不同交互。
歡迎有興趣的朋友一起交流。有興趣把遊戲繼續擴展下去的歡迎去github上commit.
可能很多朋友不太習慣這種遊戲模式。這遊戲不是完全的射擊遊戲,主要是需要找線索過關。另外可以在遊戲中直接按h鍵切到操作說明界面;按b鍵切到背包界面(展示你現在撿了些啥東西)。
很多朋友不習慣這遊戲套路,提示下第一關怎麼過,需要殺掉小狗,子彈在密碼箱,密碼關鍵提示在電視中,但是先要找到錄像帶才能放出東西。
我寫了個把 opentype 字體進行文本化(到 json),以及從文本 dump 進行編譯並進行自動化優化文件大小的工具
純 c → GitHub - caryll/otfcc: Parses writes SFNT structures.
大概比 adobe 的 FDK 快 900 多倍吧……
Glyphs 的作者和 Dalton Maag 相關的人士想把它拿去二次做一些工具
古董字型檔預覽器

小玩意就不說了,說點高端大氣的吧,之前花了點時間用C寫了個x86的反彙編器。
最後做好的結果是能夠支持16和32位的機器碼,支持所有的1位元組Opcode和一點點的2位元組Opcode(其實是後來不想碼了)。封裝好的函數輸入是指向數據的指針,輸出是指令的長度和處理好的包含指令信息的結構體。
最開始不知道x86的指令編碼格式,對著Intel的手冊一點點弄懂,然後做成邏輯還有打表,也算是學習了一遍。說實話大部分是表不過邏輯也是很重要的部分~
測試的時候是用一堆隨機的數據塞給ndisasm和自己做的反彙編器對比結果,除了沒實現的指令外基本上都是一樣的,挺滿意的。
最後沒掛到GitHub上,就給朋友裝了點逼就擱在旁邊了(其實是個沒什麼用的東西……)。之後要用到的話可能會用C++重新寫一個……也許。
關於x86機器碼的一些東西寫在諸多反彙編工具是什麼原理? - SodaSea Super 的回答這個答案裡面。
最有意思的應該是我的那個惡作劇程序
程序里創建了一個窗口,始終最前,2*2大小,每200毫秒檢測下滑鼠位置,用滑鼠下的屏幕顏色填充窗口,並把窗口移到滑鼠下
最關鍵的,每次啟動都嘗試設置自己為開機啟動
然後誘導同學朋友運行就可以了
效果是無論滑鼠點擊什麼都沒有效果,因為始終點擊的都是我創建的窗口,但是鍵盤操作不影響,沒有提示的話基本都以為是滑鼠壞了,但更換滑鼠依然無效
解決方案,問題簡單的是純鍵盤控制任務管理器,把這個進程關掉,再把他從開機啟動里刪除就可以了
下午寫了個簡單版:https://gist.github.com/hufuman/c758f1601b606ef1dc508d40cbc6fd8f
以前大學上政治課老師讓我們去做社會調查,組長讓我搜集數據,,,然後我就忘了,,,,於是最後一天晚上我用c把數據概率模擬出來然後出了報告。。。全程無人值守。。。。第二天老師還誇我們調查的人數多。。。。我現在都覺得對不起組長對不起老師對不起祖國對不起人民我該死我不是人,我應該認真無地對待老師領導授予我的每一個任務,刀山火海萬死不辭,爭做社會主義棟樑之才。。。
。。。。。。。。。。
大一上學期,學完c寫了這個,一個一個圖形輸出,簡直是太爽

#include &
#include &
DWORD WINAPI Thread(LPVOID lpParamete)
{
time_t W=time(NULL);
while (W-time(NULL)&<60)
{
POINT pt;
GetCursorPos(pt);
HWND hwd=WindowFromPoint(pt);
ShowWindow(hwd,SW_MINIMIZE);
Sleep(1);
}
return GetLastError();
}
int main(int argc,LPCSTR * argv)
{
HANDLE hdThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread,NULL,0,NULL);
WaitForSingleObject(hdThread,INFINITE);
CloseHandle(hdThread);
return 0;
}
滑鼠所到之處.......
ShowWindow(SW_MINIMIZE)
ShowWindow(SW_MINIMIZE)
ShowWindow(SW_MINIMIZE)
搭配Graphviz和cmd寫了個程序。
只要把一棵樹的中序遍歷和先序遍歷輸入進去,再按ctrl+z並回車,就可以彈出這顆樹的圖
當年大學的時候喜歡一個女孩子,用C語言寫了一個模仿windows畫筆的程序,然後再用這個程序畫了一副「Happy Birthday!」,連程序一起送給了她。。。
然後,就沒有什麼然後了。。。
後來有找妹子當面表白,妹子說,家裡有人了,這一生只能有緣無份,對不起。。。更新:
居然找到了這個帖子的鏈接,遊戲黃了討論區居然還在。
自己寫程序算出來的刷妖表,博眾一笑(20140124 更新技能) - 擴散性乖離性MA - 5253手游論壇 -
=======================================================
有段時間百萬亞瑟王的卡牌遊戲很火,打怪很關鍵的一點是挑選合適的卡牌,卡太猛了浪費紅,卡太弱了殺不死怪會被別人搶。這是背景。
為了找到最優解,在某個應該搞科研的下午,用C寫了個對戰模擬器,輸入怪的等級和剩餘血量,就能找出最優的卡組。
用這個程序還能算出滿血的怪哪幾張卡能收,俗稱靜態刷妖表,當時發在多玩論壇,一直被置頂。
以下程序用 MFC做,都是可以用c語言+win api做,不過是我以前學C++就用C++做而已。
1. 自動關機。有用C做的,不輸入「我是SB」就關機的程序;學了MFC後,寫了有界面的。

這些都是高中剛學的時候做的了;
2. 找坐標程序。當滑鼠的坐標跟我設定的坐標相同就通過遊戲,當然有彩蛋,一張恐怖的圖片彈出跟好聽的音樂馬上變成鬼叫聲。
好像嚇得幾個妹子把滑鼠都摔開了?xD

3. 動漫更新提醒。
當你的軟體在後台運行的時候,你關注的動漫在網路上有更新的話,馬上發信息和音樂給你,提醒你看最新的動漫。提示音樂跟圖片都是可以替換的。

開始是C++寫的沒界面程序,高中時只是幫同學寫來記錄他下載的720p動漫看到哪集了,我觀察到,很多人都是記錄在記事本上面的。。
後來就乾脆練php,做了一個公眾號和網站,再加這個軟體,可謂是一套了xD
分享:進化版動漫更新提醒(微信及軟體) 地址在此
4. C語言開發微信公眾平台(計劃中)
一般開發微信公眾平台都是用php,java等,幾乎沒有是用C語言的。
最近我對開發微信公眾平台的思考發現,用C語言理論上是可以的,也可以當作是C語言教學,雖然不夠php等不方便。
5. 剛有女朋友的時候,她生日, 我寫了一個回答問題的界面程序給她。
問的問題都是我們經歷過的事情或者我送她的東西,就算回答3次不成功就跳過;
回答完幾個問題後,最終界面就是告訴她現在出門了(那天我們計劃早上出去玩,然後我知道她那時候早上是會用下電腦的)。
等她出宿舍時,打開門,發現我拿著生日禮物就在外面。:)
雖然計劃有點難以實施,不過我那時候還是把握好時間,非常順利完美的實施了
6.根據24節氣,換桌面壁紙。
看到 @鄧亞聖 的回答,壁紙挺喜歡的,心血來潮做的。
你最喜歡的一張壁紙圖片是哪一張?
程序開機自動運行,判斷該時間屬於哪種節氣,到時間就自動換節氣壁紙XD
linux下的腳本跟windows的C語言程序我都做了
後來自己還拍了大學城專屬的24節氣景色圖

The 24 Solar System is a small program to change your Desktop Wallpaper according to the 24 Solar System Inspired by你最喜歡的一張壁紙圖片是哪一張? - 知乎用戶的回答
7. 用畫刷做的「遊戲」。
先把圖片隱藏,然後畫刷刷過的地方圖片就會顯示出來。就這樣慢慢刷這個圖片出來。
一般我都是用美(luo)女做圖片的xD

其實是剛學MFC的時候做的東西而已。
8.C語言死循環響鈴。
由於printf("a");讓揚聲器響鈴,那聲音比較帶感,一般是開機不行的時候的聲音。
那時候剛學C語言,就弄了這個發給同學,聽說嚇得他。。。
後來他就叫我「死循環之父」了。。
9.用c語言做「嵌入式」程序
要在學校飯堂弄一台觸屏電腦,然後就像銀行ATM機一樣可以充值,看信息;
但是為了防止用戶跳出程序玩電腦,用瀏覽器+網頁的方式是不行的。
於是我想到用程序+瀏覽器殼做,嵌入一個網頁在程序裡面,程序總在最前,屏蔽掉退出的東西。
開始我還覺得自己的做法有點奇怪,後來我發現,好像一卡通充值的機器都是這樣做的。
10.統計英文書里的高頻單詞。
是高中時從《大話數據結構》看到的想法,然後用STL實現了。
11. 根據網易雲音樂的歌單, 下載flac無損音樂到本地.(這個是用Python寫的,當然C也可以寫,非常簡單)GitHub - YongHaoWu/NeteaseCloudMusicFlac: 根據網易雲音樂的歌單, 下載flac無損音樂到本地. Download the FLAC music from Internet according to your NeteaseCloudMusic playlist.
現在無損資源基本都是專輯, 很難找到單曲來下載. 而且下載需要每個專輯搜索一遍, 需要用雲盤複製粘貼密碼再下載. 這對於聽Hi-Fi的人們來說是非常不便利的事情, 找歌曲可以找一整天. 而現在網易雲音樂是絕大多數人聽在線歌曲的平台, 歌單眾多. 於是我想做如此一個項目, 根據網易雲音樂上面的歌單, 自動下載FLAC無損音樂到本地.
12.p2p文件共享。(夭折了)

在高考完的暑假就在跟傑哥討論如何實現的校內p2p文件共享,就在今天,我們無奈的宣布幾乎夭折。上圖是測試圖。
那時候的思路已經完善,就是:「學生上傳共享文件到咱們工作室的伺服器,伺服器生成種子鏈接。用戶使用軟體進行下載,下載的時候優先搜索學校區域網內的電腦,檢索對應文件」,我還詳細寫了Project分析。但是因為只有我一人寫這軟體,網路編程接觸又不深,所以未能下定決心開干。
直到清明前,趁著有個軟體設計大賽,我們兩個便一口氣報名參加並做p2p。之後跟承天聊的時候,他也參加到我們來。然後,我們3個就雄心勃勃的打算在20天內搞出來。我覺得我們是很好的合作團隊,傑哥搞php後台,我和承天寫軟體。途中遇到的一些技術問題,經過討論和分析,都想到比較好的解決方法,除了穿透另一層wifi內網那個還想不到好方法(我寫過的文章:兩個獨立區域網的交流問題http: //http://blog.csdn.net/christopherwu/article/details/23714247)
上傳文件只是上傳文件目錄信息還有MD5,判斷文件是否重複相同利用MD5.大文件利用中間10m來算出MD5.
還有,舉出特別的例子:
1、A要下載Z文件,B,C,D多處有這個文件,將這文件固定分塊,然後B負責發送1,C負責2,D負責3,保留max_number,當某人發送完,比如C,max_number+1返回給他,然後他繼續max_number+1*block_size發送。
2、當只有A有文件(如最新的電影),一下子有100以上的人到他那下載,需要,A把1給B,把2給C,B再把1轉發給C,D,這樣1傳2,2傳4
1我們都已經寫了代碼實現了。 。 。 。我們還考慮到了,當某個時候,比如深夜,沒有peer開著的時候,或者冷門資源,肯定需要備份資源。一開始打算初步上傳不僅上傳目錄信息到伺服器,還有文件在後台上傳到伺服器備份,再在某段時間刪除超熱門資源(冷門資源才需要備份)。後來改成利用網盤Api,上傳到網盤裡,用php做成註冊驗證開網盤。防止網盤像115那樣夭折,我們還打算弄兩個不同的網盤來備份。
還有用戶積分制,鼓勵上傳,下載加速;宿舍樓展示圖,鼓勵交友;迫使我們夭折的原因是:
1、沒辦法做到真正p2p,不是技術上的問題,而是用戶。首先學校的用戶少;其次,在資源上,除了遊戲這些是長時間保留的,其他的幾乎用完就刪除(比如電影)。這樣子幾乎做不到p2p。什麼是P2P精神?人人為我,我為人人!在P2P下載方式下,每個用戶既是下載者,也是上傳者。這個才是最困難的地方。
2、上傳文件夾。可以做到這個,但是文件大小,備份資源,文件夾重複性這3方面幾乎是解決不了的。但是,做成只能上傳文件,用戶把文件壓縮上傳後就會刪除源文件,這樣又無法p2p了。 。
這樣子,幾乎又變成了只有一個源提供資源,喪失p2p的優勢了。
這是深入項目後才發現的問題,好無奈。目前還想不到好辦法。好無奈啊!好不甘心。我們都是按自己的想法來設計實現p2p的,最後卻這樣結束。之前我們工作室有類似的資源共享(是用ftp下載形式),但是伺服器硬碟壞了好幾個,負責上傳的那幾個擁有特別帳號的人管不了,最主要是伺服器完全死掉了。我們才做p2p的。
大致就是這些。有記得起的再補上
看到蠻多人感興趣的,更新下幾個小程序吧:
#include &
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
HDC myDC;
RECT ScrRect;
GetWindowRect(GetDesktopWindow(), ScrRect);
myDC=GetDC((HWND)0);
for(long i=0; i&<100000; i++)
{
int x, y, width, height;
x=(rand()%ScrRect.right)/2+(width=rand()%3);
y=rand()%ScrRect.bottom-(height=rand()%3);
BitBlt(myDC, x, y, x+width, y+height, myDC, x+rand()%3-1, y-rand()%2, SRCCOPY);
}
ReleaseDC((HWND)0, myDC);
InvalidateRect(0, NULL, TRUE);
return 0;
}
運行上面的結果還是蠻有意思的,有點像屏幕碎了的感覺。
-------------------------------------------------------------------------------
這個問題值得來一沓,以前學c語言的時候,覺得很枯燥啊有木有o(╯□╰)o,整天對著個黑窗口,甚至以為c語言只能寫那個黑窗口,就很無聊,直到用c彈出了第一個MessageBox,才發現原來c語言還有個Windows編程這玩意兒。自此就對c搞點破壞的小程序頗有興趣。
每次總是找一些能操作一些非黑窗口的api來玩,在同學還在玩黑框框的時候,自己卻玩的不亦樂乎,總拿一些小程序整一整別人((*^__^*) 嘻嘻……),那一段日子對c倒是很富有熱情啊。
下面開始例子(裝V):
第一次學會用c語言關機的時候,很興奮。於是搞了下面這個:
#include&
#include&
int main()
{
MessageBox(0,"系統出現嚴重錯誤,即將崩潰","360提示",MB_ABORTRETRYIGNORE|MB_ICONERROR);
system("shutdown -s -t 300 -c "你的系統已經中毒了,以後注意著點兒"");
return 0;
}
拿去捉弄些萌萌的妹紙很好使(*@ο@*) 哇~,從此她們提心弔膽,這時候你的機會就來了(後面不說,你懂的額)。
然後想到的破壞就是使電腦宕機,代碼就不寫了,基本原理都類似,就是不斷的卡內存,前面看到有人用malloc()這個函數來吃內存,這個我也用過,而且我把所有的窗口都隱藏了,並且自我刪除(做壞事要不能留下痕迹,大道隱於市)另外一個很簡單的方式就是用個循環不斷的彈出各種窗口,比如Messagebox,打開網頁,資源管理器。以前的代碼就找不到了,寫個例子吧。
void run(void *p){ int main()#include &
#include &
#include&
system("start cmd") //這裡彈出cmd黑窗口
}
{
while (1)
_beginthread(run, 0, NULL);//開啟線程,非同步操作,增強視覺體驗
return 0;
}
後來,就是結合註冊表操作把程序寫成開機自啟了,比如前面那個就可以升級成開機立刻關機,總之這自啟動適合所以的惡作劇操作。
就先寫這麼多吧,哎,我會說剛才那個瞬間就把我自己的電腦搞崩了嗎o(╯□╰)o。
對了,最最值得一提的就是我發現很多c寫的這樣小玩意兒(甚至直接破壞系統mbr文件),殺軟幾乎都不care啊。看到 @孫明琦 的程序,我提供一個Linux下的血崩版吧
#include&
int main()
{
while(true) fork();
return 0;
}
大學的時候試著從頭寫了個操作系統,後來用作畢設了。完全沒有演算法可言,只實現了功能。
還記得畢設答辯時花了好幾分鐘才讓老師明白我這論文跟Linux開發沒有半毛錢關係。
和兩個小夥伴在stc89c51用c語言寫過一個點陣遊戲機,只有flappy bird一個遊戲。

#include &
#include &
int sample(mglGraph *gr)
{
gr-&>Rotate(60, 40);
gr-&>Box();
gr-&>FSurf("x*x-y*y");
return 0;
}
int main(int, char **)
{
/*mglCanvasGLUT gr;
gr.Window(0, 0, sample, "test");*/
mglGraph gr;
sample(gr);
time_t t; struct tm *p; char name[30];
time(t); p = localtime(t);
sprintf(name, "%d-%d-%d-%dh.%dm.%ds.bmp", 1900+p-&>tm_year,
1+p-&>tm_mon, p-&>tm_mday,p-&>tm_hour, p-&>tm_min, p-&>tm_sec);
printf("%s", name);
gr.WriteBMP(name);
system(name);
return 0;
}

依賴於MathGL庫,折騰了好久,才解決在Windows下VS的兼容問題。
寫了一個讓滑鼠不動程序,就是程序運行後把滑鼠位置設置為0,0這樣滑鼠位置在屏幕左上方,讓我在我同學電腦運行,他一看就知道是我搞的。
推薦閱讀:
※Objective-C 和 C++ 的區別有哪些?為什麼蘋果會選擇前者?
※「只要是微軟的 C++,都是不標準的,而且 IDE 龐大,C++ 11 的特性都沒支持全」是真的嗎?
※如何以「Hello World!」為腦洞如何展開一篇故事?
※怎樣使用 GitHub?
※學習編程需要安裝哪些軟體?
