久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5471|回復: 2
打印 上一主題 下一主題
收起左側

C語言頭文件編寫方法

  [復制鏈接]
跳轉到指定樓層
樓主
ID:563265 發表于 2019-6-15 22:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
認真說起來,頭文件(Header File)是個短命的家伙——就整個編譯過程來說,它的壽命是最短的。
為什么這么說呢?關于頭文件的話題,討論起來那可是孩子沒娘,說來話長了,既然是閑聊、你也不
是等著這篇文章救命,那就不妨從頭開始說起——先假設讀者們都是不了解編譯基本過程的初學者。

   
一個編譯(Compilation)過程通常至少分為三個階段:預編譯(Precompiling)、編譯(Make)和鏈接
Linking)。他們就像一個流水線一環套一環——前一工序的輸出是后一工序的輸入。這本沒有什么稀奇的,
但對于程序員來說,這個過程中有幾個基本常識是需要記住的:


1. C
語言編譯的基本單位(Compilation Unit)是 C源文件(而并沒有頭文件)
2.
同一個工程中,不同C源文件的編譯是彼此獨立的(毫不相干的)
3.
頭文件在預編譯階段就已經合并到對應的C源文件中了,和所有的宏以及條件編譯一樣,到了編譯階段,所有的頭文件、宏都是不存在的,已經被替換為對應的內容和常量了。


   
理解這三點,基本上已經可以解決很多我們日常編碼過程中存在的很多疑問,比如:


- Q1
:為什么不能C語言頭文件里面定義變量或者函數的實體?
- Q2
:為什么有的時候宏的先后順序并不那么重要?
- Q3
:為什么可以在源代碼的任意位置(另起一行后)定義宏,甚至是include別的頭文件?

   
推薦大家基于前面的三個事實自己思考,答案在附錄中介紹。
   
   
頭文件里可以放什么呢?這是個值得討論的問題:


-  各類宏
-  函數的聲明(也就是 extern xxxxx
-  全局變量的聲明(也就是 extern xxxx
   然而,值得說明的是,這里有一個編碼規則值得你去遵守:頭文件里堅決不要放全局變量有關的任何東西(硬要加,也必須是const類型的,比如各類接口)
-  類型定義(typedef, struct,union 之類的)
-  static 的變量實體和函數實體。
   這個可以有,為啥呢?因為即便多個c源文件包含同一個頭文件導致同樣的函數和變量實體存在多份,但
   static 的另外一個名字 "private" 可以保證每一份變量和函數實體都是彼此獨立的,都是每個c源代碼的
   私人財產——你可以有,我也可以有!鞍?你也有啊,真巧哎,我也有……”
-  inline 的函數
   這個和static是一個道理。


   
頭文件里面不能放函數的實體,想必原因大部分人都知道了,這里就不再贅述。但頭文件里不放(非const)的全局變量的聲明,
這怎么玩?這里需要說明一下,頭文件里不是不能放(非const)的全局變量聲明,而是我提供了一個人為的規定(規范),建議
不要放任何(非const)的全局變量到頭文件里,具體原因和解決方案,我們在別的帖子里再討論(其實有人討論過,大約就是,
如何避免使用全局變量)——是的,避免使用(非const)的全局變量是可以做到的——這里也不再贅述。說了這么多廢話,我們
真正要討論的內容還沒有開始:


- 如何建立頭文件的使用規則,使其即靈活、使用方便,又靈活且便于擴展(模塊化)——符合面向接口開發的要求,方便我們
  
建立黑盒子?
簡而言之,
-
如何讓頭文件的使用不再頭疼;永遠告別循環包含;方便代碼的移植?



      
首先,思考一個簡單的問題?為什么我們要用頭文件?答案其實很簡單,因為每個.c文件都是獨立編譯的,因此需要在源代碼
級別傳遞一些信息,類似一群人在嘮嗑:

   
   
源代碼A             我定義了一個函數,你們哥幾個要用么?
   
源代碼B和源代碼C 我們要用啊,函數原型(prototype)什么樣子啊?
   
源代碼A              你們不用費腦經記(抄下來),我都寫好了,放在一個頭文件里了,你們直接include就可以了。
   
源代碼B和源代碼C 這個敢情方便。那你頭文件放哪里了?
   
源代碼A              有兩種方式,要么你直接到我這里來拿(指定路徑);要么你找編譯器問(編譯器指定搜索路徑)。
   
源代碼D              你們整這么麻煩做什么?你直接告訴我原型,我抄下來,不就不用問這個問那個,還包含文件什么的,真麻煩。
   
源代碼A              D啊,你老想耍小聰明,萬一我更新了你不知道怎么辦?我有義務告訴你么?并沒有。
   
源代碼B和源代碼C 是啊,是啊,A以后估計要外包了,不在這里了,到時候有變化,都記錄在頭文件里,你本地放一個,沒法
                                       
及時同步的。
   
源代碼D             我不聽!我不聽!我不聽……


   
是不是很有畫面感?拋開捂著耳朵的D,我們回到討論的話題——既然頭文件是用來交換信息的,那么如果把所有的信息都放在一起,大家
需要的時候各取所需,豈不美哉?——基于這種思想,幾乎所有人都見過把所有變量、函數、宏、類型定義都放到一個叫做system.h的頭文件
里的做法。你有這么做過么?不要不好意思,幾乎所有人都這么做過——因為實在太方便了,世界大同,挺好,直到你嘗試和別人一起合作開發
系統,并試圖在不同項目間復用一些代碼的時候:

    “
何首烏藤和木蓮藤纏絡著”……對于這種情況,我們叫做耦合。是要找個時間來理一理了,你對自己說,然后長嘆了一口氣,發現這句話其
實很早之前就說過了。想到還有更奇葩的循環包涵的問題,你不得不感嘆,頭文件真的是個頭疼的東西——要不我們還是不用了吧?直接抄下來
貌似更簡單啊——源程序D癡癡的笑了。

   
那么,如何解決這個問題呢?其實,從實踐經驗來看,頭文件的用途分為兩大類:

   
站在C源文件的視角上:


- 從 外部向C源文件內部 輸入配置信息——我們把這類頭文件叫做配置頭文件(Configuration HeaderFile)。
  需要強調的是,信息的流動方向是 從外向內,所以又可以簡單的理解為輸入性的頭文件(Header File for information input)。常見的app_cfg.h
  就是典型的配置頭文件。

- 從 C源文件內部向外 輸出接口信息(全局函數、類型,宏定義等信息)——我們把這類頭文件叫做接口頭文件(Interface Header File)。
  需要強調的是,信息的流動方向是 從內向外,所以又可以簡單的理解為輸出性的頭文件(Header File for information output)。常見的, spi.h
  usart.h, device.h, stdint.h 就是典型的接口頭文件。


   
輸入和輸出兩個不同的職能如果被放在同一個頭文件里,就有極大的風險產生循環包含(兩個相反方向的箭頭產生閉合的圓圈)。system.h實際
上就是一個混淆信息流動方向的例子。這就是本質上依賴system.h的工程 模塊不好拆分的原因。根據上述原理,這里引入頭文件使用的第一條原則:


   
對一個C源代碼來說,站在它的視角上,隸屬于它自己的接口頭文件(Output)和配置頭文件(Input)永遠不要同時包含(include)在當前
C源文件中。

全部資料51hei下載地址:
頭文件編寫.docx (332.33 KB, 下載次數: 52)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:18591 發表于 2019-6-23 14:24 | 只看該作者
下來看看,感謝分享
回復

使用道具 舉報

板凳
ID:253767 發表于 2019-9-4 07:49 | 只看該作者
謝謝分享。!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二区自拍 | 日韩在线观看网站 | 一级片视频免费 | 天天操操操操操 | 99re视频在线| 久久国产精品久久久久 | 久久精品中文字幕 | 国产日韩欧美中文 | 成人精品国产一区二区4080 | wwww.8888久久爱站网 | 欧美精品一区二区三区在线 | 激情六月丁香婷婷 | 色999视频| 超碰97人人人人人蜜桃 | 欧美日韩久久 | 天天操网 | 在线观看中文字幕一区二区 | 99re6在线视频精品免费 | 久久久久久久久久久91 | 欧美日韩一区二区在线 | 亚洲综合国产 | 成人精品久久 | 国产视频精品在线观看 | 久久久精品 | 人人射人人 | 亚洲综合色视频在线观看 | 日韩一区二区三区av | 成人亚洲视频 | 在线免费观看黄色av | 亚洲精品乱码久久久久久蜜桃 | 成人区一区二区三区 | 91视频一区| 在线观看的av | 亚洲精品不卡 | 一区二区三区国产精品 | 羞羞视频网站免费看 | 国产精品a一区二区三区网址 | 久久久久成人精品免费播放动漫 | 亚洲成人午夜电影 | 国产精品国产三级国产a | 欧美成人一区二区三区 |