国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
[ZT]C程序怎樣組織更有結(jié)構(gòu)性
C程序怎樣組織更有結(jié)構(gòu)性(2007-07-21 17:12:08)
 在C語言的應(yīng)用領(lǐng)域,如通訊領(lǐng)域和嵌入式系統(tǒng)領(lǐng)域,一個的軟件項目通常包含很多復(fù)雜的功能,實現(xiàn)這個項目不是一個程序員單槍匹馬可以勝任的,往往需要一個團(tuán)隊的有效合作,另外,在一個以C代碼為主的完整的項目中,經(jīng)常也需要加入一些其他語言的代碼,例如,C代碼和匯編代碼的混合使用,C文件和C++的同時使用。這些都增加了一個軟件項目的復(fù)雜程度,為了提高軟件質(zhì)量,合理組織的各種代碼和文件是非常重要的。  
   
 組織代碼和文件的目的是為了使團(tuán)隊合作更加有效,使軟件項目有良好的可擴(kuò)展性、可維護(hù)性、可移植性、可裁減、可測試性,防止錯誤發(fā)生,提高軟件的穩(wěn)定性。通常情況下,軟件項目采用層次化結(jié)構(gòu)和模塊化開發(fā)的方法,例如,一個嵌入式軟件項目可能有驅(qū)動層,操作系統(tǒng)層,功能層,應(yīng)用程序?qū)?每一個層使用它的下層提供的接口,并為它的上層提供調(diào)用接口,模塊則是每一個層中完成一個功能的單元,例如驅(qū)動層的每一個設(shè)備的驅(qū)動就是一個模塊,應(yīng)用層的每個應(yīng)用程序就是一個模塊,模塊使用下層提供的接口和同層其他模塊提供的接口,完成特定功能,為上層和同層的其他模塊提供調(diào)用接口。  
   
 這里的接口是指一個功能模塊暴露出來的,提供給其他模塊的訪問具體功能的方法。根據(jù)C語言的特點,使用*.c文件實現(xiàn)模塊的功能,使用*.h文件暴露單元的接口,在*.h文件里聲明外部其他模塊可能是用的函數(shù),數(shù)據(jù)類型,全局變量,類型定義,宏定義和常量定義.外部模塊只需包含*.h文件就可以使用相應(yīng)的功能.當(dāng)然,模塊可以在細(xì)化為子模塊.雖然我們這里說的接口和COM(通用組件模型)里定義的接口不同,但是,根據(jù)COM里對接口的討論,為了使軟件在修改時,一個模塊的修改不會影響到其他模塊的一個模塊的修改不會導(dǎo)致其他模塊也需要修改,所以,接口第一次發(fā)布后,修改*.h文件不能導(dǎo)致使用這個接口的其他模塊需要重新編寫.  
   
 根據(jù)C語言的特點,并借鑒一些成熟軟件項目代碼,總結(jié)C項目中代碼文件組織的基本建議:  
 1,使用層次化和模塊化的軟件開發(fā)模型.每一個模塊只能使用所在層和下一層模塊提供的接口.  
 2,每個模塊的文件包存在獨立的一個文件夾中.通常情況下,實現(xiàn)一個模塊的文件不止一個,這些相關(guān)的文件應(yīng)該保存在一個文件夾中.  
 3,用于模塊裁減的條件編譯宏保存在一個獨立的文件里,便于軟件裁減.  
 4,硬件相關(guān)代碼和操作系統(tǒng)相關(guān)代碼與純C代碼相對獨立保存,以便于軟件移植.  
 5,聲明和定義分開,使用*.h文件暴露模塊需要提供給外部的函數(shù),宏,類型,常量,全局變量,盡量做到模塊對外部透明,用戶在使用模塊功能時不需要了解具體的實現(xiàn),文件一旦發(fā)布,要修改一定要很慎重,  
 6,文件夾和文件命名要能夠反映出模塊的功能.  
 7,正式版本和測試版本使用統(tǒng)一文件,使用宏控制是否產(chǎn)生測試輸出。  
 8,必要的注釋不可缺少。  
   
 理想的情況下,一個可執(zhí)行的模塊提供一個公開的接口,即使用一個*.h文件暴露接口,但是,有時候,一個模塊需要提供不止一個接口,這時,就要為每個定義的接口提供一個公開的接口。在C語言的里,每個C文件是一個模塊,頭文件為使用這個模塊的用戶提供接口,用戶只要包含相應(yīng)的頭文件就可以使用在這個頭文件中暴露的接口。所有的頭文件都建議參考以下的規(guī)則:  
   
  1,頭文件中不能有可執(zhí)行代碼,也不能有數(shù)據(jù)的定義,只能有宏、類型(typedef,struct,union,menu),數(shù)據(jù)和函數(shù)的聲明。例如以下的代碼可以包含在頭文件里:  
  #define  NAMESTRING  “name”  
  typedef  unsign  long  word;  
  menu{  
  flag1;  
  flag2;  
  };  
  typedef  struct{  
  int  x;  
  int  y;  
  Piont;  
  extent  Fun(void);  
  extent  int  a;  
 全局變量和函數(shù)的定義不能出現(xiàn)在*.h文件里。例如下面的代碼不能包含在頭文件:  
  int  a;  
  void  Fun1(void)  
  
         a++;  
  
   
 2,頭文件中不能包本地數(shù)據(jù)(模塊自己使用的數(shù)據(jù)或函數(shù),不被其他模塊使用)。這一點相當(dāng)于面向?qū)ο蟪绦蛟O(shè)計里的私有成員,即只有模塊自己使用的函數(shù),數(shù)據(jù),不要用extent在頭文件里聲明,只有模塊自己使用的宏,常量,類型也不要在頭文件里聲明,應(yīng)該在自己的*.c文件里聲明。  
 3,含一些需要使用的聲明。在頭文件里聲明外部需要使用的數(shù)據(jù),函數(shù),宏,類型。  
 4,防止被重復(fù)包含。使用下面的宏防止一個頭文件被重復(fù)包含。  
  #ifndef  MY_INCLUDE_H  
  #define  MY_INCLUDE_H  
 <頭文件內(nèi)容>  
  #endif  
  5,包含extern  "C",使的程序可以在C++編譯器被編譯  
  #ifdef  __cplusplus  
         extern  "C"{  
  #endif  
 <函數(shù)聲明>  
  #ifdef  __cplusplus  
          
  #enfif  
    被extern  "C"修飾的變量和函數(shù)是按照C語言方式編譯和連接的;未加extern  “C”聲明時的編譯方式,作為一種面向?qū)ο蟮恼Z言,C++支持函數(shù)重載,而過程式語言C則不支持。函數(shù)被C++編譯后在符號庫中的名字與C語言的不同。例如,假設(shè)某個函數(shù)的原型為:    
  void  foo(  int  x,  int   );該函數(shù)被C編譯器編譯后在符號庫中的名字為_foo,而C++編譯器則會產(chǎn)生像_foo_int_int之類的名字(不同的編譯器可能生成的名字不同,但是都采用了相同的機(jī)制,生成的新名字稱為“mangled  name”)。_foo_int_int這樣的名字包含了函數(shù)名、函數(shù)參數(shù)數(shù)量及類型信息,C++就是靠這種機(jī)制來實現(xiàn)函數(shù)重載的。例如,在C++中,函數(shù)void  foo(  int  x,  int   )與void  foo(  int  x,  float   )編譯生成的符號是不相同的,后者為_foo_int_float?!⊥瑯拥?,C++中的變量除支持局部變量外,還支持類成員變量和全局變量。用戶所編寫程序的類成員變量可能與全局變量同名,我們以"."來區(qū)分。而本質(zhì)上,編譯器在進(jìn)行編譯時,與函數(shù)的處理相似,也為類中的變量取了一個獨一無二的名字,這個名字與用戶程序中同名的全局變量名字不同。加extern  "C"聲明后的編譯和連接,強(qiáng)制C++連接器按照C編譯器產(chǎn)生的符號_foo鏈接。  
 6,保證在使用這個頭文件時,用戶不用再包含使用此頭文件的其他前提頭文件,即要使用的頭文件已經(jīng)包含在此頭文件里。例如:area.h頭文件包含了面積相關(guān)的操作,要使用這個頭文件不需同時包含了關(guān)于點操作的頭文件piont.h。用戶在使用area.h時不需要手動包含piont.h,因為我們已經(jīng)在area.h中用#include  “point.h”包含了這個頭文件。  
   
 有一些頭文件是為用戶提供調(diào)用接口,這種頭文件中聲明了模塊中需要給其他模塊使用的函數(shù)和數(shù)據(jù),鑒于軟件質(zhì)量上的考慮,處理參考以上的規(guī)則,用來暴露接口的頭文件還需要參考更多的規(guī)則:  
 1,一個模塊一個接口,不能幾個模塊用一個接口。  
 2,文件名為和實現(xiàn)模塊的c文件相同。abc.c--abc.h  
 3,盡量不要使用extern來聲明一些共享的數(shù)據(jù)。因為這種做法是不安全的,外部其他模塊的用戶可能不能完全理解這些變量的含義,最好提供函數(shù)訪問這些變量。  
 4,盡量避免包含其他的頭文件,除非這些頭文件是獨立存在的。這一點的意思是,在作為接口的頭文件中,盡量不要包含其他模塊的那些暴露*.C文件中內(nèi)容的頭文件,但是可以包好一些不是用來暴露接口的頭文件。  
 5,不要包含那些只有在可執(zhí)行文件中才使用的頭文件,這些頭文件應(yīng)該在*.c文件中包含。這一點如同上一點,為了提高接口的獨立性和透明度。  
 6,接口文件要有面向用戶的充足的注釋。從應(yīng)用角度描述個暴露的內(nèi)容。  
 7,接口文件在發(fā)布后盡量避免修改,即使修改也要保證不影響用戶程序。  
   
 多個代碼文件使用一個接口文件:這種頭文件用于那些認(rèn)為一個模塊使用一個文件太大的情況。對于這種情況對于這種情況在參考上述建議后,也要參考以下建議。  
 1,多個代碼文件組成的一個模塊只有一個接口文件。因為這些文件完成的是一個模塊。  
 2,使用模塊下文件命名<系統(tǒng)名><模塊名命名>  
 3,不要濫用這種文件。  
 4,有時候也會出現(xiàn)幾個*.c文件用于共向數(shù)據(jù)的*.h文件,這種文件的特點是在一個*.c文件里定義全局變量,而在其他*.c文件里使用,要將這種文件和用于暴露模塊接口的文件區(qū)別。  
 5,一個模塊如果有幾個子模塊,可以用一個*.h文件暴露接口,在這個文件里用#include包含每個子模塊的接口文件。  
   
 還有一種頭文件,說明性頭文件,這種頭文件不需要有一個對應(yīng)的代碼文件,在這種文件里大多包含了大量的宏定義,沒有暴露的數(shù)據(jù)變量和函數(shù)。這些文件給出以下建議:  
 1,包含一些需要的概念性的東西.  
 2,命名方式,定義的功能.h  
 3,不包含任何其他的頭文件.  
 4,不定義任何類型.  
 5,不包含任何數(shù)據(jù)和函數(shù)聲明.  
   
 上面介紹了C頭文件的一些建議,下面介紹C代碼文件*.c文件的一些建議,*.c文件是C語言中生成匯編代碼和機(jī)器碼的內(nèi)容,要注意以下建議:  
  1.命名方式  模塊名.c  
 2,用static修飾本地的數(shù)據(jù)和函數(shù)。  
 3,不要使用external。這是在*.h中使用的,可以被包含進(jìn)來。  
 4,無論什么時候定義內(nèi)部的對象,確保獨立與其他執(zhí)行文件。  
 5,這個文件里必須包含相應(yīng)功能函數(shù)。  
   
 上面介紹了一些C文件組織的建議,用于提高C語言項目的質(zhì)量,在以后的C項目組織中,學(xué)習(xí)面向?qū)ο蠛虲OM的思想,將這些思想加入到C程序中,能夠?qū)懗龈哔|(zhì)量的代碼。上面的建議在具體的項目里應(yīng)該靈活運用,附錄里有*.h頭文件和*.c代碼文件的模版,在工程中可以作為參考。另外,C工程中經(jīng)常有一些匯編代碼文件,這些文件也要使有*.h頭文件暴露其中的數(shù)據(jù)和函數(shù),以便其他*.c文件包含使用。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
extern "C" 解析
結(jié)合extern談?wù)勵^文件的作用
extern “C”的作用詳解
C語言的頭文件包含,竟然有那么多講究!
C++中extern “C”含義深層探索
C interview
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服