為什麼 C 語言被設計成函式需要先宣告才能被使用?

時間 2021-05-29 23:18:09

1樓:李鵬

理論上,完全可以做到不宣告,直接使用。

但C語言非常古老,跟現在的高階語言相比,自然有很多原始的地方。

對函式進行宣告的好處是,能夠簡化編譯器的開發。

在最早的K&R標準裡,函式的宣告不需要宣告函式的引數,只需要告訴編譯器函式名和返回值就可以了。

這樣的話,在編譯器中,函式名被當做乙個指標,對編譯器來說,宣告乙個函式跟宣告乙個指標變數沒什麼區別,這樣就減少了開發編譯器的工作。

在後來的ANSI C中,標準制定者本著盡量相容K&R和儘量減少改動的前提,保留了函式宣告,只是嚴格了函式宣告的條件,即必須把函式引數型別在宣告中明確標出。

制定ANSI C標準的時候,是唯一的取消C函式宣告的機會,我們失去了。今後也不會再有這樣的機會了,C語言中的函式宣告將與我們相伴終生。

2樓:todd song

可以不宣告,但是不同廠家的編譯器可能會出問題,所以最好還是宣告了。在我大ST的編譯器上我就從來不宣告,不過後來在broadcast的編譯器上吃虧了,後來就不管在哪都宣告了。

3樓:

C是靜態語言, 且支援多檔案分別編譯,最後再鏈結成程式.

如果不先看到函式的宣告就呼叫, 可能會搞錯引數的實際型別和個數.

4樓:Belleve

你是沒用過 PASCAL 啊……這玩意有個 forward 關鍵字專門用來前置宣告。

其核心問題是——如果允許後置宣告那麼編譯就要多乙個 pass,在 PDP 那會估計就是不短的一段時間。

5樓:

仔細想一下,在靜態鏈結過程中,靜態庫檔案的符號表裡,儲存的是只是函式的位址,那麼當你的自己程式在引用這個靜態庫檔案的時候,必須加上個頭檔案才行,也就是所謂的宣告了.....

你想想如果沒有這個標頭檔案,編譯器怎麼判斷,你的引用的靜態庫中的函式簽名是對還是錯呀!

再智慧型的編譯器也判斷不出來啊!!

由於c/c++編譯鏈結機制本身的限制! 先宣告再使用,那是必須的!

6樓:

其實在ANSI C之前C語言是不需要宣告函式就能呼叫的。

在編譯階段,呼叫沒有宣告的函式會把這個問題拖延到鏈結階段,在鏈結階段找不到符號才由鏈結器報錯。那麼沒有宣告的情況下怎麼知道這個函式到底是怎樣的原型呢……他們把這叫做autoprototype,根據呼叫時傳入的形參的型別猜測函式的原型。

實際上在ANSI C中你還是不需要完整的宣告原型,可以在宣告的時候把引數列表忽略掉,讓編譯器去根據呼叫處猜測函式的原型。不過這樣寫出來之後根據不同的呼叫約定有時候會由於編寫者的錯誤而意外的破壞棧幀。

這樣對許多人來說還是留下乙個問題:古老的Turbo C並不遵循ANSI C的建議,它怎麼需要提前宣告函式?老實說Turbo C是乙個特例。

我相信貝爾實驗室那幫發明了C和UNIX的人都會認為Turbo C的這個設計很無聊,不符合使用的習慣以及實際的需要。

7樓:薛非

歷史上,C語言函式並非一定需要宣告,有些函式可以不宣告。當然最好宣告

其次,宣告是為了編譯。不正確地宣告,也不可能正確地編譯,甚至無法編譯。

樓主似乎有乙個誤區,就是以為原始檔都是同時編譯的,其實不是的。不同時編譯時,這個宣告的必要性是顯而易見的

8樓:隨時改名

標頭檔案只是乙個宣告檔案,而聲明確是程式查詢事務的最初索引。舉個簡單例子,你要見網友,見面之前要知道他的基本特徵吧?知道了才能找到真正的人。

C語言和C 中,為什麼malloc函式需要傳入申請的記憶體大小,而free時候卻不需要傳大小呢?

Hades 前面說書裡面說過,我忙猜,在申請記憶體的時候時間上申請的是乙個資料結構,包含頭部和可以位址資訊,free的時候去資料結構裡找就行了。比如裡要100記憶體,可能實際申請了110的記憶體多的就用來存放一些和記憶體相關的資訊了別。 白潔 多方面的因素 也許包括歷史因素 不存在對錯。c 的all...

為什麼 C 語言沒有被 C 取代?

avoidant 如果這個世界上只有c和c 那c早就被c 取代了。正是因為那些不認同c 理念的語言的存在,才讓c更加有了存在的必要 作為一種不同語言都願意接受的普通話。事實上,別說不同語言,就是不同c 編譯器也選擇了c作為彼此間溝通的普通話。 恆星 這就好像為什麼30系顯示卡都發布了卻還有人在用9系...

c語言中,形參就是變數嗎?為什麼說函式的形參可以是指標型別?

C語言答疑課堂 別說形參了,實參也是變數,傳遞給函式的引數都是變數。指標也是一種變數,跟int變數,char變數一樣,都是變數。既然都是變數,函式大爺全然接受。 形參就是函式的引數 什麼是引數?比如你在dos下敲個命令dir如果目錄太多的話一螢幕顯示不完。那麼敲 dir p就可以分屏顯示,這個 p就...