巨集與函式哪家強?

2021-09-10 18:17:00 字數 2394 閱讀 7204

說到巨集與函式,我們首先來了解一下它們的定義:

#define包括乙個規定,即允許把某一特定輸入根據預定義的規則進行輸出,巨集即是一種規則與模式,也可以稱為語法替換。

在計算機中,函式是乙個固定的程式段,也可以成為乙個子程式,擁有自己特定的功能,在被呼叫時將傳入的引數進行運算,再返回值給呼叫它的程式。

在某種意義上,巨集與函式都具有將輸入給自己的值按照預定義的規則進行預算,再進行輸出的功能,那麼巨集與函式之間誰更勝一籌呢?

首先我們需要了解乙個程式是如何轉化乙個可執行檔案的:

1 .在預處理階段中,程式進行了注釋的刪除、將標頭檔案包含程序式、define定義的識別符號進行替換。

2.在編譯階段,則對程式中的語法、詞法、語意、符號進行分析。

3.在彙編階段,則是將生成的彙編**轉化為二進位制指令,同時形成符號表。

4.在連線階段、合併段表。符號表,為每個符號表進行重定位。

由此,我們不難看出,#define定義巨集早已在預處理階段就將引數替換了進去,而函式由於需要傳參,並返回值,這極大的延長了程式的執行時間,這使得在使用者體驗的過程中感覺到巨集要比函式的執行速度快很多。

那麼在其他方面,巨集還依然優於函式嗎?

●在**長度方面:由於#define巨集會在每次使用時將巨集**插入到程式當中,這使得當巨集**過長時,會極大地增加**長度;而函式從始至終只有乙個,被呼叫時,僅會傳參和返回引數,不會被替換到程式中去,這使得無論函式本身有多麼長,在程式中被呼叫了多少次,對不會影響程式的**長度,所以在這點上,函式要優於巨集.

●在操作符的優先順序上:巨集引數的求值是在所有周圍表示式的上下文環境,除非給巨集引數新增詳盡的括號符,否則極易受到周圍表示式符號優先順序影響,得到與預期結果不符的值!(如下例:),而函式引數則只在呼叫的時候求值一次,然後將值返回給函式,傳參時不易受到周圍符號影響,結果更易於**。在這點上,函式要優於巨集。

#include

#define square(x) x*x

#define double(x) (x)+(x)

intmain()

我們先來看第乙個巨集「square(x) x*x」如果你不假思索的認為「square(x+1)」的值等於49,那你可就大錯特錯了,將巨集引數替換後得到:

printf

(「square=

%d\n」,6+

1*6+

1)

所以最終的值等於13,是不是和想要的值有很大出入呢?

這時你可能會說我將square(x)定義成(x)*(x)不就可以了嗎,的確,在這個巨集引數上可以解決,但換乙個呢,比如第二個double,在對每一項都加了括號後如果在下列的式子中依然會出問題:

printf(「double=

%d\n」,10*

6+6);

答案依然不是我們想要的120,而是66.。。。。

是不是頓時有一股「用巨集遍地都是坑的念頭」湧上心頭t^t…

● 在引數求值上:由於引數每次用於巨集定義上時,都會重新求值,所以一些具有***的引數如「i++」就會是程式產生預料之外的結果。而引數在被函式被呼叫前之求值一次,而在函式內部多次使用引數則不會導致這種多次求值的問題,引數的***不會導致上述問題的發生。在這點上,函式要優於巨集。

● 在引數型別上:巨集在調取引數時不會考慮引數的型別,只要對於引數的操作是合法的,巨集可以使用任何型別的值。而函式則在宣告中已經明確了所需引數的型別,即使引數所執行的任務是形同的,函式也只使用宣告中規定的函式型別值。在這點上,巨集的適用性更廣泛一些,但不對引數的型別進行限制,常常會導致一些安全性的問題,而函式則更加明確與安全,這點上,我個人認為函式要優於巨集

● 在書寫靈活性上:巨集無法定義區域性變數,所有巨集必須在最外層定義,致使全域性可見,而且沒有類似namespace的功能,命名時超頭疼.(namespace可以讓相同命名的函式在不同的namespace中得以共同存在,使用時只需要宣告namespace的名稱即可,這使得程式設計師可以在命名不同情況下使用的同一功能的函式時不用絞盡腦汁想一些奇怪的名字,也方便了程式的讀寫效率),而函式不但可以使用namespace功能,而且可以將函式的主題放在**的任意區域。所以在這個方面函式更勝一籌。

● 而且,巨集無法像函式一樣的使用遞迴!所以在實現迴圈時,巨集與函式高低立見

● 在巨集引數被使用時,若遇到#、##便會停止展開,但巨集引數往往是先完全展開,再進行傳參,這時如果遇到「#」與「##」,勢必會造成傳參失敗,而函式則沒有字元限制,在這點上函式依然優於巨集。

總結了這麼多,希望能幫助到你!

Python Excel 模組哪家強?

從網頁爬下來的大量資料需要清洗?成堆的科學實驗資料需要匯入 excel 進行分析?有成堆的 等待統計?作為人生苦短的 python 程式設計師,該如何優雅地操作 excel?得益於前人的辛勤勞作,python 處理 excel 已有很多現成的輪子,使用較多的有 xlwings 由於設計目的不同,每個...

前端框架哪家強?

它就像是todomvc,只是使用全棧技術實現。realworld 向大家展示了如何使用 react angular 等框架在 node django 等平台上構建真實的部落格平台。開發者可以把它們混合起來,因為它們都遵循相同的 api 規範。realworld 基準測試始於 2017 年,最近更新了...

EOS API服務哪家強?

前段時間終於試著復活了下eosvoterstracker,過程艱辛 本文僅從該項目的需求來選擇的,讀者應按自己實際情況和應用來決定使用哪個 eosvoterstracker 在去年 6 月 eos 主網剛啟動,投票還未滿足 15 抵押的時候,我出於對投票行為的好奇,於是想能不能提供乙個工具來分析節點...