小程序解釋.docx_第1頁
小程序解釋.docx_第2頁
小程序解釋.docx_第3頁
小程序解釋.docx_第4頁
小程序解釋.docx_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

C語言 筆記1:學(xué)會的第一個程序hello,world!此題為在屏幕上輸入hello world!運行結(jié)果:2:此題是求兩個數(shù)的和:運行結(jié)果:3:此題是求三個數(shù)的最大值:運行結(jié)果:4:此題為輸入圓錐體的高度(hight)和半徑(radius)來求體積(volume):運行結(jié)果:5:此題是將分鐘數(shù)輸入,然后換算成小時(hour)和分鐘(minute)。運行結(jié)果:6:此題是為了了解和掌握算術(shù)表達式的運算順序。(注意+i,和i+的區(qū)別:+i是先用后加一,i+是先加一,在用。)運行結(jié)果:這是HR面試我的一道題,沒技術(shù)上含量,不過細(xì)想起來,還是C語言的最基本的知識!俗話說,目標(biāo)決定動力,細(xì)節(jié)決定成?。?C文件就是C語言系列的源文件,而H文件則是C語言的頭文件,即C系列中存放函數(shù)和全局變量的文件,因為C中的函數(shù)是被封裝起來的,即無法看到其代碼。 子程序不要定義在*.h中。函數(shù)定義要放在*.c中,而*.h只做聲明.否則多引用幾次,就會發(fā)生函數(shù)重復(fù)定義的錯誤。*.h只做聲明,編譯后不產(chǎn)生代碼。這樣做目的是為了實現(xiàn)軟件的模塊化,使軟件結(jié)構(gòu)清晰,而且也便于別人使用你寫的程序。 純粹用 C 語言語法的角度,你當(dāng)然可以在*.h 中放任何東西,因為 #include 完全等價于把*.h 文件 Ctrl-C Ctrl-V 到*.c 中,*.h 中應(yīng)該都是一些宏定義和變量、函數(shù)聲明,告訴別人你的程序“能干什么、該怎么用”。*.c 中是所有變量和函數(shù)的定義,告訴計算機你的程序“該怎么實現(xiàn)”。當(dāng)然,如果一個*.h 被多個*.c 包含,而且*.h 中有對象(變量或函數(shù))的定義,就會發(fā)生重復(fù)定義的錯誤了,聲明可以無窮多次,定義只能一次。一般來說,一個C文件應(yīng)該是一個模塊,如果你的程序僅僅有一個模塊(僅僅一個C文件),就可以不用建立H文件了。否則你的模塊肯定不是獨立的,你的模塊里面的實現(xiàn)要被別的模塊調(diào)用。這個時候你最好生成一個頭文件(H文件),在頭文件里面可以聲明你的那些函數(shù)是公共的。當(dāng)別的模塊包含你的頭文件后,就可以使用你的公共聲明了。一個C對應(yīng)一個H,這樣管理起來方便,比如你有一個my.c,那么就再添加一個my.h:#ifndef _MY_H#define _MY_Hextern void my(void);#endif其實在H文件里寫函數(shù)也無所謂,只是不符合習(xí)慣而已。只要按照以上的格式寫,一個H文件添加多少次都無所謂,呵Come from:/t/20060429/15/4723725.html簡單的說,其實要理解C文件與H文件有什么不同之處,首先需要弄明白編譯器的工作過程,一般說來編譯器會做以下幾個過程:1.預(yù)處理階段 2.詞法與語法分析階段 3.編譯階段,首先編譯成純匯編語句,再將之匯編成跟CPU相關(guān)的二進制碼,生成各個目標(biāo)文件 4.連接階段,將各個目標(biāo)文件中的各段代碼進行絕對地址定位,生成跟特定平臺相關(guān)的可執(zhí)行文件,當(dāng)然,最后還可以用objcopy生成純二進制碼,也就是去掉了文件格式信息。編譯器在編譯時是以C文件為單位進行的,也就是說如果你的項目中一個C文件都沒有,那么你的項目將無法編譯,連接器是以目標(biāo)文件為單位,它將一個或多個目標(biāo)文件進行函數(shù)與變量的重定位,生成最終的可執(zhí)行文件,在PC上的程序開發(fā),一般都有一個main函數(shù),這是各個編譯器的約定,當(dāng)然,你如果自己寫連接器腳本的話,可以不用main函數(shù)作為程序入口!有了這些基礎(chǔ)知識,再言歸正傳,為了生成一個最終的可執(zhí)行文件,就需要一些目標(biāo)文件,也就是需要C文件,而這些C文件中又需要一個main函數(shù)作為可執(zhí)行程序的入口,那么我們就從一個C文件入手,假定這個C文件內(nèi)容如下:#include #include mytest.hint main(int argc,char *argv) test = 25;printf(test.%dn,test);mytest.h文件的內(nèi)容:int test; 現(xiàn)在以這個例子來講解編譯器的工作:1.預(yù)處理階段:編譯器以C文件作為一個單元,首先讀這個C文件,發(fā)現(xiàn)第一句與第二句是包含一個頭文件,就會在所有搜索路徑中尋找這兩個文件,找到之后,就會將相應(yīng)頭文件中再去處理宏,變量,函數(shù)聲明,嵌套的頭文件包含等,檢測依賴關(guān)系,進行宏替換,看是否有重復(fù)定義與聲明的情況發(fā)生,最后將那些文件中所有的東東全部掃描進這個當(dāng)前的C文件中,形成一個中間“C文件”。2.編譯階段,在上一步中相當(dāng)于將那個頭文件中的test變量掃描進了一個中間C文件,那么test變量就變成了這個文件中的一個全局變量,此時就將所有這個中間C文件的所有變量,函數(shù)分配空間,將各個函數(shù)編譯成二進制碼,按照特定目標(biāo)文件格式生成目標(biāo)文件,在這種格式的目標(biāo)文件中進行各個全局變量,函數(shù)的符號描述,將這些二進制碼按照一定的標(biāo)準(zhǔn)組織成一個目標(biāo)文件 。 3.連接階段,將上一步成生的各個目標(biāo)文件,根據(jù)一些參數(shù),連接生成最終的可執(zhí)行文件,主要的工作就是重定位各個目標(biāo)文件的函數(shù),變量等,相當(dāng)于將個目標(biāo)文件中的二進制碼按一定的規(guī)范合到一個文件中 。再回到C文件與頭文件各寫什么內(nèi)容的話題上: 理論上來說C文件與頭文件里的內(nèi)容,只要是C語言所支持的,無論寫什么都可以的,比如你在頭文件中寫函數(shù)體,只要在任何一個C文件包含此頭文件就可以將這個函數(shù)編譯成目標(biāo)文件的一部分(編譯是以C文件為單位的,如果不在任何C文件中包含此頭文件的話,這段代碼就形同虛設(shè)),你可以在C文件中進行函數(shù)聲明,變量聲明,結(jié)構(gòu)體聲明,這也不成問題!那為何一定要分成頭文件與C文件呢?又為何一般都在頭件中進行函數(shù),變量聲明,宏聲明,結(jié)構(gòu)體聲明呢?而在C文件中去進行變量定義,函數(shù)實現(xiàn)呢?原因如下: 1.如果在頭文件中實現(xiàn)一個函數(shù)體,那么如果在多個C文件中引用它,而且又同時編譯多個C文件,將其生成的目標(biāo)文件連接成一個可執(zhí)行文件,在每個引用此頭文件的C文件所生成的目標(biāo)文件中,都有一份這個函數(shù)的代碼,如果這段函數(shù)又沒有定義成局部函數(shù),那么在連接時,就會發(fā)現(xiàn)多個相同的函數(shù),就會報錯 。 2.如果在頭文件中定義全局變量,并且將此全局變量賦初值,那么在多個引用此頭文件的C文件中同樣存在相同變量名的拷貝,關(guān)鍵是此變量被賦了初值,所以編譯器就會將此變量放入DATA段,最終在連接階段,會在DATA段中存在多個相同的變量,它無法將這些變量統(tǒng)一成一個變量,也就是僅為此變量分配一個空間,而不是多份空間,假定這個變量在頭文件沒有賦初值,編譯器就會將之放入BSS段,連接器會對BSS段的多個同名變量僅分配一個存儲空間 。 3.如果在C文件中聲明宏,結(jié)構(gòu)體,函數(shù)等,那么我要在另一個C文件中引用相應(yīng)的宏,結(jié)構(gòu)體,就必須再做一次重復(fù)的工作,如果我改了一個C文件中的一個聲明,那么又忘了改其它C文件中的聲明,這不就出了大問題了,程序的邏輯就變成了你不可想象的了,如果把這些公共的東東放在一個頭文件中,想用它的C文件就只需要引用一個就OK了!這樣豈不方便,要改某個聲明的時候,只需要動一下頭文件就行了。 4.在頭文件中聲明結(jié)構(gòu)體,函數(shù)等,當(dāng)你需要將你的代碼封裝成一個庫,讓別人來用你的代碼,你又不想公布源碼,那么人家如何利用你的庫呢?也就是如何利用你的庫中的各個函數(shù)呢?一種方法是公布源碼,別人想怎么用就怎么用,另一種是提供頭文件,別人從頭文件中看你的函數(shù)原型,這樣人家才知道如何調(diào)用你寫的函數(shù),就如同你調(diào)用printf函數(shù)一樣,里面的參數(shù)是怎樣的?你是怎么知道的?還不是看人家的頭文件中的相關(guān)聲明??!當(dāng)然這些東東都成了C標(biāo)準(zhǔn),就算不看人家的頭文件,你一樣可以知道怎么使用 。例子:/a.hvoid foo();/a.c#include a.h /我的問題出來了:這句話是要,還是不要?void foo() return;/main.c#include a.hint main(int argc, char *argv) foo();return 0;針對上面的代碼,請回答三個問題:1.a.c中的#include a.h這句話是不是多余的?為什么經(jīng)常見xx.c里面include對應(yīng)的xx.h?2.如果a.c中不寫,那么編譯器是不是會自動把.h文件里面的東西跟同名的.c文件綁定在一起?3.第三個問題我給他改了一下:如果a.c中不寫include,那么編譯器是不是會自動把.h文件里面的東西跟同名的.c文件綁定在一起?下面是一位牛人的原話:從C編譯器角度看,.h和.c皆是浮云,就是改名為.txt、.doc也沒有大的分別。換句話說,就是.h和.c沒啥必然聯(lián)系。.h中一般放的是同名.c文件中定義的變量、數(shù)組、函數(shù)的聲明,需要讓.c外部使用的聲明。這個聲明有啥用?只是讓需要用這些聲明的地方方便引用。因為#include xx.h這個宏其實際意思就是把當(dāng)前這一行刪掉,把xx.h中的內(nèi)容原封不動的插入在當(dāng)前行的位置。由于想寫這些函數(shù)聲明的地方非常多(每一個調(diào)用xx.c中函數(shù)的地方,都要在使用前聲明一下子),所以用#include xx.h這個宏就簡化了許多行代碼讓預(yù)處理器自己替換好了。也就是說,xx.h其實只是讓需要寫xx.c中函數(shù)聲明的地方調(diào)用(可以少寫幾行字),至于include這個.h文件是誰,是.h還是.c,還是與這個.h同名的.c,都沒有任何必然關(guān)系。這樣你可能會說:???那我平時只想調(diào)用xx.c中的某個函數(shù),卻include了xx.h文件,豈不是宏替換后出現(xiàn)了很多無用的聲明?沒錯,確實引入了很多垃圾,但是它卻省了你不少筆墨,并且整個版面也看起來清爽的多。魚與熊掌不可得兼,就是這個道理。反正多些聲明(.h一般只用來放聲明,而放不定義,參見拙著“過馬路,左右看”)也無害處,又不會影響編譯,何樂而不為呢?翻回頭再看上面的3個問題,很好解答了吧?它的解答如下:1.不一定。這個例子中顯然是多余的。但是如果.c中的函數(shù)也需要調(diào)用同個.c中的其它函數(shù),那么這個.c往往會include同名的.h,這樣就不需要為聲明和調(diào)用順序而發(fā)愁了

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論