国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

如何組織構(gòu)建多文件C語(yǔ)言程序(一)

開(kāi)發(fā) 后端
準(zhǔn)備好你喜歡的飲料、編輯器和編譯器,放一些音樂(lè),然后開(kāi)始構(gòu)建一個(gè)由多個(gè)文件組成的 C 語(yǔ)言程序。

[[319002]]

準(zhǔn)備好你喜歡的飲料、編輯器和編譯器,放一些音樂(lè),然后開(kāi)始構(gòu)建一個(gè)由多個(gè)文件組成的 C 語(yǔ)言程序。

大家常說(shuō)計(jì)算機(jī)編程的藝術(shù)部分是處理復(fù)雜性,部分是命名某些事物。此外,我認(rèn)為“有時(shí)需要添加繪圖”是在很大程度上是正確的。

在這篇文章里,我會(huì)編寫(xiě)一個(gè)小型 C 程序,命名一些東西,同時(shí)處理一些復(fù)雜性。該程序的結(jié)構(gòu)大致基于我在 《如何寫(xiě)一個(gè)好的 C 語(yǔ)言 main 函數(shù)》 文中討論的。但是,這次做一些不同的事。準(zhǔn)備好你喜歡的飲料、編輯器和編譯器,放一些音樂(lè),讓我們一起編寫(xiě)一個(gè)有趣的 C 語(yǔ)言程序。

優(yōu)秀 Unix 程序哲學(xué)

首先,你要知道這個(gè) C 程序是一個(gè) Unix 命令行工具。這意味著它運(yùn)行在(或者可被移植到)那些提供 Unix C 運(yùn)行環(huán)境的操作系統(tǒng)中。當(dāng)貝爾實(shí)驗(yàn)室發(fā)明 Unix 后,它從一開(kāi)始便充滿了設(shè)計(jì)哲學(xué)。用我自己的話來(lái)說(shuō)就是:程序只做一件事,并做好它,并且對(duì)文件進(jìn)行一些操作。雖然“只做一件事,并做好它”是有意義的,但是“對(duì)文件進(jìn)行一些操作”的部分似乎有點(diǎn)兒不合適。

事實(shí)證明,Unix 中抽象的 “文件” 非常強(qiáng)大。一個(gè) Unix 文件是以文件結(jié)束符(EOF)標(biāo)志為結(jié)尾的字節(jié)流。僅此而已。文件中任何其它結(jié)構(gòu)均由應(yīng)用程序所施加而非操作系統(tǒng)。操作系統(tǒng)提供了系統(tǒng)調(diào)用,使得程序能夠?qū)ξ募?zhí)行一套標(biāo)準(zhǔn)的操作:打開(kāi)、讀取、寫(xiě)入、尋址和關(guān)閉(還有其他,但說(shuō)起來(lái)那就復(fù)雜了)。對(duì)于文件的標(biāo)準(zhǔn)化訪問(wèn)使得不同的程序共用相同的抽象,而且可以一同工作,即使它們是不同的人用不同語(yǔ)言編寫(xiě)的程序。

具有共享的文件接口使得構(gòu)建可組合的的程序成為可能。一個(gè)程序的輸出可以作為另一個(gè)程序的輸入。Unix 家族的操作系統(tǒng)默認(rèn)在執(zhí)行程序時(shí)提供了三個(gè)文件:標(biāo)準(zhǔn)輸入(stdin)、標(biāo)準(zhǔn)輸出(stdout)和標(biāo)準(zhǔn)錯(cuò)誤(stderr)。其中兩個(gè)文件是只寫(xiě)的:stdoutstderr。而 stdin 是只讀的。當(dāng)我們?cè)诔R?jiàn)的 Shell 比如 Bash 中使用文件重定向時(shí),可以看到其效果。

  1. $ ls | grep foo | sed -e 's/bar/baz/g' > ack

這條指令可以被簡(jiǎn)要地描述為:ls 的結(jié)果被寫(xiě)入標(biāo)準(zhǔn)輸出,它重定向到 grep 的標(biāo)準(zhǔn)輸入,grep 的標(biāo)準(zhǔn)輸出重定向到 sed 的標(biāo)準(zhǔn)輸入,sed 的標(biāo)準(zhǔn)輸出重定向到當(dāng)前目錄下文件名為 ack 的文件中。

我們希望我們的程序在這個(gè)靈活又出色的生態(tài)系統(tǒng)中運(yùn)作良好,因此讓我們編寫(xiě)一個(gè)可以讀寫(xiě)文件的程序。

喵嗚喵嗚:流編碼器/解碼器概念

當(dāng)我還是一個(gè)露著豁牙的孩子懵懵懂懂地學(xué)習(xí)計(jì)算機(jī)科學(xué)時(shí),學(xué)過(guò)很多編碼方案。它們中的有些用于壓縮文件,有些用于打包文件,另一些毫無(wú)用處因此顯得十分愚蠢。列舉最后這種情況的一個(gè)例子:哞哞編碼方案

為了讓我們的程序有個(gè)用途,我為它更新了一個(gè) 21 世紀(jì) 的概念,并且實(shí)現(xiàn)了一個(gè)名為“喵嗚喵嗚” 的編碼方案的概念(畢竟網(wǎng)上大家都喜歡貓)。這里的基本的思路是獲取文件并且使用文本 “meow” 對(duì)每個(gè)半字節(jié)(半個(gè)字節(jié))進(jìn)行編碼。小寫(xiě)字母代表 0,大寫(xiě)字母代表 1。因?yàn)樗鼤?huì)將 4 個(gè)比特替換為 32 個(gè)比特,因此會(huì)擴(kuò)大文件的大小。沒(méi)錯(cuò),這毫無(wú)意義。但是想象一下人們看到經(jīng)過(guò)這樣編碼后的驚訝表情。

  1. $ cat /home/your_sibling/.super_secret_journal_of_my_innermost_thoughts
  2. MeOWmeOWmeowMEoW...

這非常棒。

最終的實(shí)現(xiàn)

完整的源代碼可以在 GitHub 上面找到,但是我會(huì)寫(xiě)下我在編寫(xiě)程序時(shí)的思考。目的是說(shuō)明如何組織構(gòu)建多文件 C 語(yǔ)言程序。

既然已經(jīng)確定了要編寫(xiě)一個(gè)編碼和解碼“喵嗚喵嗚”格式的文件的程序時(shí),我在 Shell 中執(zhí)行了以下的命令 :

  1. $ mkdir meowmeow
  2. $ cd meowmeow
  3. $ git init
  4. $ touch Makefile     # 編譯程序的方法
  5. $ touch main.c       # 處理命令行選項(xiàng)
  6. $ touch main.h       # “全局”常量和定義
  7. $ touch mmencode.c   # 實(shí)現(xiàn)對(duì)喵嗚喵嗚文件的編碼
  8. $ touch mmencode.h   # 描述編碼 API
  9. $ touch mmdecode.c   # 實(shí)現(xiàn)對(duì)喵嗚喵嗚文件的解碼
  10. $ touch mmdecode.h   # 描述解碼 API
  11. $ touch table.h      # 定義編碼查找表
  12. $ touch .gitignore   # 這個(gè)文件中的文件名會(huì)被 git 忽略
  13. $ git add .
  14. $ git commit -m "initial commit of empty files"

簡(jiǎn)單的說(shuō),我創(chuàng)建了一個(gè)目錄,里面全是空文件,并且提交到 git。

即使這些文件中沒(méi)有內(nèi)容,你依舊可以從它的文件名推斷每個(gè)文件的用途。為了避免萬(wàn)一你無(wú)法理解,我在每條 touch 命令后面進(jìn)行了簡(jiǎn)單描述。

通常,程序從一個(gè)簡(jiǎn)單 main.c 文件開(kāi)始,只有兩三個(gè)解決問(wèn)題的函數(shù)。然后程序員輕率地向自己的朋友或者老板展示了該程序,然后為了支持所有新的“功能”和“需求”,文件中的函數(shù)數(shù)量就迅速爆開(kāi)了。“程序俱樂(lè)部”的第一條規(guī)則便是不要談?wù)?ldquo;程序俱樂(lè)部”,第二條規(guī)則是盡量減少單個(gè)文件中的函數(shù)。

老實(shí)說(shuō),C 編譯器并不關(guān)心程序中的所有函數(shù)是否都在一個(gè)文件中。但是我們并不是為計(jì)算機(jī)或編譯器寫(xiě)程序,我們是為其他人(有時(shí)也包括我們)去寫(xiě)程序的。我知道這可能有些奇怪,但這就是事實(shí)。程序體現(xiàn)了計(jì)算機(jī)解決問(wèn)題所采用的一組算法,當(dāng)問(wèn)題的參數(shù)發(fā)生了意料之外的變化時(shí),保證人們可以理解它們是非常重要的。當(dāng)在人們修改程序時(shí),發(fā)現(xiàn)一個(gè)文件中有 2049 函數(shù)時(shí)他們會(huì)詛咒你的。

因此,優(yōu)秀的程序員會(huì)將函數(shù)分隔開(kāi),將相似的函數(shù)分組到不同的文件中。這里我用了三個(gè)文件 main.cmmencode.cmmdecode.c。對(duì)于這樣小的程序,也許看起來(lái)有些過(guò)頭了。但是小的程序很難保證一直小下去,因此哥忒拓展做好計(jì)劃是一個(gè)“好主意”。

但是那些 .h 文件呢?我會(huì)在后面解釋一般的術(shù)語(yǔ),簡(jiǎn)單地說(shuō),它們被稱為頭文件,同時(shí)它們可以包含 C 語(yǔ)言類型定義和 C 預(yù)處理指令。頭文件中不應(yīng)該包含任何函數(shù)。你可以認(rèn)為頭文件是提供了應(yīng)用程序接口(API)的定義的一種 .c 文件,可以供其它 .c 文件使用。

但是 Makefile 是什么呢?

我知道下一個(gè)轟動(dòng)一時(shí)的應(yīng)用都是你們這些好孩子們用 “終極代碼粉碎者 3000” 集成開(kāi)發(fā)環(huán)境來(lái)編寫(xiě)的,而構(gòu)建項(xiàng)目是用 Ctrl-Meta-Shift-Alt-Super-B 等一系列復(fù)雜的按鍵混搭出來(lái)的。但是如今(也就是今天),使用 Makefile 文件可以在構(gòu)建 C 程序時(shí)幫助做很多有用的工作。Makefile 是一個(gè)包含如何處理文件的方式的文本文件,程序員可以使用其自動(dòng)地從源代碼構(gòu)建二進(jìn)制程序(以及其它東西!)

以下面這個(gè)小東西為例:

  1. 00 # Makefile
  2. 01 TARGET= my_sweet_program
  3. 02 $(TARGET): main.c
  4. 03    cc -o my_sweet_program main.c

# 符號(hào)后面的文本是注釋,例如 00 行。

01 行是一個(gè)變量賦值,將 TARGET 變量賦值為字符串 my_sweet_program。按照慣例,也是我的習(xí)慣,所有 Makefile 變量均使用大寫(xiě)字母并用下劃線分隔單詞。

02 行包含該步驟recipe要?jiǎng)?chuàng)建的文件名和其依賴的文件。在本例中,構(gòu)建目標(biāo)targetmy_sweet_program,其依賴是 main.c

最后的 03 行使用了一個(gè)制表符號(hào)(tab)而不是四個(gè)空格。這是將要執(zhí)行創(chuàng)建目標(biāo)的命令。在本例中,我們使用 C 編譯器C compiler前端 cc 以編譯鏈接為 my_sweet_program

使用 Makefile 是非常簡(jiǎn)單的。

  1. $ make
  2. cc -o my_sweet_program main.c
  3. $ ls
  4. Makefile  main.c  my_sweet_program

構(gòu)建我們喵嗚喵嗚編碼器/解碼器的 Makefile 比上面的例子要復(fù)雜,但其基本結(jié)構(gòu)是相同的。我將在另一篇文章中將其分解為 Barney 風(fēng)格。

形式伴隨著功能

我的想法是程序從一個(gè)文件中讀取、轉(zhuǎn)換它,并將轉(zhuǎn)換后的結(jié)果存儲(chǔ)到另一個(gè)文件中。以下是我想象使用程序命令行交互時(shí)的情況:

  1. $ meow < clear.txt > clear.meow
  2. $ unmeow < clear.meow > meow.tx
  3. $ diff clear.txt meow.tx
  4. $

我們需要編寫(xiě)代碼以進(jìn)行命令行解析和處理輸入/輸出流。我們需要一個(gè)函數(shù)對(duì)流進(jìn)行編碼并將結(jié)果寫(xiě)到另一個(gè)流中。最后,我們需要一個(gè)函數(shù)對(duì)流進(jìn)行解碼并將結(jié)果寫(xiě)到另一個(gè)流中。等一下,我們?cè)谟懻撊绾螌?xiě)一個(gè)程序,但是在上面的例子中,我調(diào)用了兩個(gè)指令:meowunmeow?我知道你可能會(huì)認(rèn)為這會(huì)導(dǎo)致越變?cè)綇?fù)雜。

次要內(nèi)容:argv[0] 和 ln 指令

回想一下,C 語(yǔ)言 main 函數(shù)的結(jié)構(gòu)如下:

  1. int main(int argc, char *argv[])

其中 argc 是命令行參數(shù)的數(shù)量,argv 是字符指針(字符串)的列表。argv[0] 是包含正在執(zhí)行的程序的文件路徑。在 Unix 系統(tǒng)中許多互補(bǔ)功能的程序(比如:壓縮和解壓縮)看起來(lái)像兩個(gè)命令,但事實(shí)上,它們是在文件系統(tǒng)中擁有兩個(gè)名稱的一個(gè)程序。這個(gè)技巧是通過(guò)使用 ln 命令創(chuàng)建文件系統(tǒng)鏈接來(lái)實(shí)現(xiàn)兩個(gè)名稱的。

在我筆記本電腦中 /usr/bin 的一個(gè)例子如下:

  1. $ ls -li /usr/bin/git*
  2. 3376 -rwxr-xr-x. 113 root root     1.5M Aug 30  2018 /usr/bin/git
  3. 3376 -rwxr-xr-x. 113 root root     1.5M Aug 30  2018 /usr/bin/git-receive-pack
  4. ...

這里 gitgit-receive-pack 是同一個(gè)文件但是擁有不同的名字。我們說(shuō)它們是相同的文件因?yàn)樗鼈兙哂邢嗤?inode 值(第一列)。inode 是 Unix 文件系統(tǒng)的一個(gè)特點(diǎn),對(duì)它的介紹超越了本文的內(nèi)容范疇。

優(yōu)秀或懶惰的程序可以通過(guò) Unix 文件系統(tǒng)的這個(gè)特點(diǎn)達(dá)到寫(xiě)更少的代碼但是交付雙倍的程序。首先,我們編寫(xiě)一個(gè)基于其 argv[0] 的值而作出相應(yīng)改變的程序,然后我們確保為導(dǎo)致該行為的名稱創(chuàng)建鏈接。

在我們的 Makefile 中,unmeow 鏈接通過(guò)以下的方式來(lái)創(chuàng)建:

  1. # Makefile
  2. ...
  3. $(DECODER): $(ENCODER)
  4. $(LN) -f $< $@
  5. ...

我傾向于在 Makefile 中將所有內(nèi)容參數(shù)化,很少使用 “裸” 字符串。我將所有的定義都放置在 Makefile 文件頂部,以便可以簡(jiǎn)單地找到并改變它們。當(dāng)你嘗試將程序移植到新的平臺(tái)上時(shí),需要將 cc 改變?yōu)槟硞€(gè) cc 時(shí),這會(huì)很方便。

除了兩個(gè)內(nèi)置變量 $@$< 之外,該步驟recipe看起來(lái)相對(duì)簡(jiǎn)單。第一個(gè)便是該步驟的目標(biāo)的快捷方式,在本例中是 $(DECODER)(我能記得這個(gè)是因?yàn)?@ 符號(hào)看起來(lái)像是一個(gè)目標(biāo))。第二個(gè),$< 是規(guī)則依賴項(xiàng),在本例中,它解析為 $(ENCODER)

事情肯定會(huì)變得復(fù)雜,但它還在管理之中。 

 

責(zé)任編輯:龐桂玉 來(lái)源: Linux中國(guó)
相關(guān)推薦

2020-03-18 12:23:49

C語(yǔ)言編程語(yǔ)言

2020-12-15 11:23:09

數(shù)據(jù)驅(qū)動(dòng)企業(yè)數(shù)字化

2023-08-17 20:13:42

2011-07-05 17:07:14

C語(yǔ)言

2018-02-24 12:17:56

C程序內(nèi)存方式

2015-08-17 17:57:43

IT性能運(yùn)維

2012-06-27 10:28:12

編程語(yǔ)言語(yǔ)言學(xué)習(xí)多門(mén)語(yǔ)言

2019-07-29 08:00:18

文件容器Docker Comp

2009-07-31 17:14:19

C#語(yǔ)言Web程序

2011-07-22 15:10:51

Objective-C 文件

2009-08-13 17:04:09

C#語(yǔ)言C#程序

2025-03-21 08:00:00

大型語(yǔ)言模型視覺(jué)語(yǔ)言微調(diào)

2023-12-08 14:32:02

C語(yǔ)言編程文件操作

2023-09-27 23:38:29

C程序

2023-09-21 08:00:00

ChatGPT編程工具

2009-06-15 11:03:10

Java語(yǔ)言C#語(yǔ)言

2025-04-18 08:37:09

2012-08-13 09:31:33

程序

2010-01-22 11:23:06

C++程序

2016-08-10 10:18:55

點(diǎn)贊
收藏

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

一区二区中文字| 日韩一区电影| 欧美日韩一区二区在线观看 | 99久久久国产精品免费调教网站| 国产无遮挡裸体视频在线观看| 日本二三区不卡| 成人激情视频免费在线| 制服诱惑亚洲| 亚洲人成网7777777国产| 麻豆视频久久| 亚洲欧美日韩久久久久久| wwwav在线| 欧美日韩视频在线一区二区| 黄色在线小视频| 欧美日韩中国免费专区在线看| 国语对白在线视频| 综合欧美一区二区三区| 91亚洲午夜精品久久久久久| 少妇免费毛片久久久久久久久| 91精品国产视频| 成人网欧美在线视频| 欧美军人男男激情gay| 热久久免费国产视频| 亚洲va久久| 91视视频在线观看入口直接观看www| 久久这里精品国产99丫e6| 欧美日韩一区二区高清| 国产v亚洲v天堂无码| 宅男噜噜噜66一区二区| 欧美黑人xxxxx| 精品一区二区免费| 欧美性猛交内射兽交老熟妇| 不卡电影一区二区三区| www.日日操| 亚洲精品亚洲人成人网在线播放| 国产中文字幕第一页| 午夜欧美2019年伦理| 第一页在线观看| 精品久久久久久久人人人人传媒| 丁香花在线电影小说观看| 亚洲欧美精品在线| 日韩在线你懂得| 久久久久久久久久婷婷| 国内黄色精品| 久久精品国产美女| 国产精品一区二区三区网站| 黄色高清无遮挡| 亚洲一区二区三区中文字幕 | 成人性生活视频| 欧美精品一区二| 精品久久99| 97在线观看视频| 欧洲乱码伦视频免费| 国产精品午夜av在线| 美女国产一区二区| 亚洲成熟丰满熟妇高潮xxxxx| 亚洲桃色在线一区| 在线观看av的网站| 色av中文字幕一区| 精品国产中文字幕第一页| 国产精品一区二区三区不卡| 久久 天天综合| 激情综合网五月激情 | 一级毛片在线观| 欧美日韩午夜电影网| 国产精品观看在线亚洲人成网| 国产精品porn| 成人免费性视频| 五月天网站亚洲| 性欧美18xxxhd| 国产伦精品一区二区三区精品视频| 美女看a上一区| 久草在线新视觉| 亚洲日本欧美中文幕| 99久久精品网| 日本精品一区二区三区四区| 欧美日韩激情一区| 精品女人视频| 日韩国产精品毛片| 欧美日韩国产在线| 亚洲精品自拍| 欧美成人免费在线| 亚洲婷婷在线视频| 国产精品一区二区av影院萌芽| 国产美女精品视频| 成a人片国产精品| 风间由美一区| 97国产在线视频| 性伦欧美刺激片在线观看| v888av成人| 亚洲视频一区二区| 亚洲精品护士| 激情综合网五月激情 | 亚洲色图五月天| 亚洲人成精品久久久| 天天做天天躁天天躁| 欧美在线观看视频在线| 欧美日韩一本| 国产乱淫av片杨贵妃| 欧美情侣在线播放| 国产影视精品一区二区三区| 亚洲人成无码网站久久99热国产| 欧美日韩精品免费观看视频| 丝袜连裤袜欧美激情日韩| 色哺乳xxxxhd奶水米仓惠香| 欧美日本高清视频在线观看| 天堂一区二区三区四区| 1024av视频| 精品视频在线播放色网色视频| 亚洲一级影院| 屁屁影院在线观看| 97视频在线观看亚洲| 久久久久久久综合色一本| 激情开心成人网| 伊人久久大香线蕉午夜av| 91精品在线免费观看| 欧美日韩调教| 污黄色在线观看| 国产欧美日韩最新| 亚洲精品欧美二区三区中文字幕| 人人爱人人干婷婷丁香亚洲| 免费看一级大黄情大片| 在线观看国产欧美| 国产一区二区伦理| 9765激情中文在线| 日韩理论片在线观看| 欧美军同video69gay| 亚洲精品精选| av毛片在线| 色噜噜狠狠一区二区三区| 欧美一级黄色录像| 国产一区二区你懂的| 在线观看麻豆蜜桃| 久久精品人成| 欧美一区二区在线免费播放 | 92看片淫黄大片看国产片| 亚洲国产精品天堂| 99久久久久国产精品| 四虎电影院在线观看| 亚洲一区中文字幕| 欧美日韩国产三级| 欧美aaaaaa午夜精品| 精精国产xxxx视频在线野外| 国产美女视频免费| 日韩性xxxx爱| 国产精品乱码久久久久久| 视频一区中文| 国产精品99999| 久久精品国产综合精品| 日韩欧美国产一区二区在线播放| 日韩精品每日更新| 在线毛片观看| 国产97在线 | 亚洲| 欧美有码在线视频| 黑人狂躁日本妞一区二区三区| 亚洲欧洲日本mm| 性欧美又大又长又硬| caopor在线视频| 国产精品香蕉在线观看| 欧美亚洲日本国产| 国产一区二区影院| 国产乱人伦精品一区| 国产在线日本| 中文字幕中文字幕一区三区| 久久av红桃一区二区小说| 亚洲免费视频中文字幕| 黄色欧美成人| 精品久久免费| 又色又爽又高潮免费视频国产| 欧美www在线| sm国产在线调教视频| 91精品视频播放| 正在播放亚洲一区| 成人午夜视频在线| 国产一区三区在线播放| 日本三级视频在线播放| 青草网在线观看| 国产精品久久久久av| 欧美一区二区三区视频在线| 成人综合在线网站| 色天下一区二区三区| 在线免费观看的av网站| 日韩极品视频在线观看| 日韩av免费看| 精品国产乱码久久久久久老虎| 国产三级精品在线| 中文在线播放一区二区| 最新日韩精品| 中文在线а√在线| 欧美久久久久久久久久久久久久| 天天精品视频| 美女被人操视频在线观看| 欧美成人综合一区| 欧美国产一区二区三区| 欧美日韩日本视频| 91美女片黄在线观看| 99精品久久久| 中文字幕一区二区精品区| 久久久久久久久成人| 青青一区二区|