這要看你函數(shù)的作用域是全局還是局部,如果作用域是全局的話,編譯器會報錯:重復(fù)定義;如果函數(shù)只是作用于當(dāng)前的文件,函數(shù)定義前加上static修飾,函數(shù)僅僅作用于當(dāng)前文件
創(chuàng)新互聯(lián)建站長期為上1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為白堿灘企業(yè)提供專業(yè)的成都網(wǎng)站建設(shè)、網(wǎng)站制作,白堿灘網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
是這樣的,同一個函數(shù)內(nèi)定義的每個變量名(局部變量)是唯一的,其內(nèi)容的改變與本函數(shù)外的任何變量無關(guān)。
連接(link),是把目標(biāo)文件轉(zhuǎn)化為可執(zhí)行文件或動態(tài)庫的過程。
高級語言的代碼經(jīng)過編譯之后會生成目標(biāo)文件(linux上是.o文件)。
目標(biāo)文件不能直接運行,因為它并沒有把高級語言里的變量名、函數(shù)名等符號轉(zhuǎn)化為具體的內(nèi)存地址。
把符號名轉(zhuǎn)化成內(nèi)存地址的工具,就是連接器(linker)。
它還要生成一個程序頭,告訴操作系統(tǒng)怎么加載這個程序。
在Linux上常用的連接器是ld。如果gcc在報錯時打印了ld的錯誤信息,就說明是連接錯誤,而不是編譯錯誤。
如上圖,只有兩個函數(shù)add()和sub(),打印的信息是要引用的標(biāo)簽main沒有定義。也就是沒找到main函數(shù)。
“在函數(shù)_start中”,說明main函數(shù)是被_start調(diào)用的。它是匯編的入口函數(shù),一般匯編代碼的開頭要這么寫:
.text
.global _start
_start:
call main
call exit
第一個call是調(diào)用main函數(shù),開始運行C/C++代碼。
在main函數(shù)返回之后,要主動調(diào)用exit()函數(shù)退出進程。否則程序在main函數(shù)返回之后就不可控了,然后程序會訪問無效的內(nèi)存,再被操作系統(tǒng)干掉。
在C和C++中,這個_start函數(shù)是編譯器提供的。
python和perl之類的腳本語言,不會直接編譯成機器碼,而是被解釋器運行,所以不需要連接。只要它們的解釋器能搞明白它們的語法樹,就能直接運行,最多速度慢點。
一般會編譯為字節(jié)碼(例如java字節(jié)碼),在虛擬機上運行,比直接遍歷語法樹要快。
直接編譯為機器碼的C語言,肯定是速度最快的。
編譯為機器碼,就要把各種函數(shù)和變量轉(zhuǎn)化為具體的內(nèi)存地址,才可以運行。
CPU沒有數(shù)據(jù)結(jié)構(gòu)的概念,只有地址和字節(jié)的概念。
讀哪個位置的多少字節(jié),把多少字節(jié)寫到哪個位置,調(diào)用哪個位置的函數(shù)。
位置,就是內(nèi)存地址。字節(jié),就是內(nèi)存的內(nèi)容或大小。
所以,實際上匯編是遠比C簡單的(汗)。
匯編之所以難,在于匯編碼的信息含量太低,同樣的功能下代碼冗長,可讀性很差,所以才顯得難。
需要在連接時轉(zhuǎn)化為內(nèi)存地址的函數(shù)和變量,有這么幾類:
1,函數(shù),
不管是全局函數(shù),靜態(tài)函數(shù),還是成員函數(shù),都屬于代碼。都要存放在目標(biāo)文件的代碼段,即以.text命名的節(jié)。
Linux的可執(zhí)行文件,elf格式
(Linux上,目標(biāo)文件、動態(tài)庫、可執(zhí)行文件都是elf格式)
在編譯時,并不知道這些函數(shù)的具體地址。
因為編譯的文件只是其中一個.o文件,能確定的只是函數(shù)在這個.o文件里的位置。
如果函數(shù)調(diào)用了其他文件里的函數(shù),那
把程序的入口定義為一個main()函數(shù),其他你自己定義的函數(shù)就不要定義成這個名字,自己取個名字就可以了,然后在main()函數(shù)里面調(diào)用他就行了。程序只能有一個入口,而且C里面不支持有兩個名字相同的函數(shù),C++那些面向?qū)ο蟮木幊陶Z言才支持出現(xiàn)同名函數(shù)