關於代引數的巨集定義函式的規模問題

2022-11-19 23:05:20 字數 1906 閱讀 6623

1樓:匿名使用者

1全部首先保險起見,為了減少巨集的***,最好寫成

#define s(a,b) ((a)*(b)),否則a和b是非單一物件的表示式可能出錯。

不過這樣也不能保證一定正確,例如a和b也是複雜的巨集時。

另外一點就是沒有引數的靜態型別檢查。a和b是否正確,需要寫呼叫**的人自己保證。

在使用上,其它方面和一般的函式沒什麼很大的區別。

由於它不是真正意義的函式,在每次函式呼叫時都會這段表示式,所以編譯出來的**可能會比較大。不過執行時的效率可能會稍微提高,因為編譯器沒有對引數列表生成棧操作——在迴圈體等呼叫次數較多的上下文中效果更明顯。

同樣由於它不是真正的函式,在目標檔案的符號表(如果有的話)中不會出現它的名稱。要重用這個「函式」,需要獲得完整的源**。動態連結(編譯成.dll之類)更是不可能的。

一般建議對於支援行內函數的編譯器(儘管iso c90中沒有規定,目前流行的絕大部分c語言和所有的c++編譯器都支援;iso c99/iso c++98及之後的標準中有規定),儘可能使用inline修飾函式,同樣可以達到函式體呼叫的目的,且沒有巨集的***,還有靜態型別檢查。而且,inline只是建議,當編譯器發現不適合內聯的函式(例如函式體太大),可以按照非內聯的普通函式編譯。

使用巨集唯一多了的一個功能是可以取消定義。#undef s以後,s可以作為未宣告的識別符號在同一個翻譯單元內再次被利用,例如定義另外的巨集。不過這並不一定是優點,例如可能使閱讀者混淆s的定義。

----

巨集本身是字串替換,幾個規則是很簡諧的,儘管結合之後會有一些***。而在c設計初實現了許多必要的功能,例如符號常量。巨集作為函式則是另外一種應用。

隨著語言的發展,新的特性被新增,可以取代巨集的部分功能。例如,const物件的引入可以部分地取代無引數巨集實現的符號常量。而inline函式的引入正是為了消除巨集函式的上述幾點不足。

但是,巨集還有其它一些功能無法被取代,例如條件編譯。

而要去除或修改語言特性所要花費的代價是很大的,尤其是像c這樣歷史悠久且被廣泛使用的語言。現有的**非常之多,如果語言升級導致這些**無法編譯,需要的維護成本極大,會使新的語言版本難以推廣,而失去了很大一部分升級的意義。(事實上,現在編譯器廠商對iso c99不怎麼熱衷,也就gcc等少數幾個編譯器有較完整的實現,像微軟就基本上對這此沒興趣,vs裡附帶的microsoft c & c++ compiler的c語言實現基本上是基於iso c90的)。

如果需要廢除某項語言特性,標準委員會對於可能在以後版本廢除的特性註明deprecated,提醒使用者慎用(暫時保留是為了目前可以相容現存的舊**)。

根本來說,使用合適的語言特性解決恰當的問題,是使用者的責任,設計者不可能全部包辦。

====

[原創回答團]

2樓:

巨集定義 是編譯之前的預處理階段被替換,注意只是替換(evaluation)不會有求值操作,故用巨集不能實現遞迴(看起來是,但執行不起來)。

函式 是編譯時才處理的,有求值。

巨集還可以實現些特殊的效果,如

#define swap(a,b,t)

。。。。。。。

巨集在預處理完後,就已經成了標量值,或者靜態**,這樣既讓程式(人)可讀性,又不影響機器效率。在這一點上函式在執行時還執行時需要動態的維護呼叫堆疊,這點不比巨集定義快。

(這是我到現在為止對它們的認識)

3樓:匿名使用者

可以把它當成函式來寫,不過不建議用巨集實現遞迴函式。

帶引數巨集會在編譯之前由前處理器做文字替換,所以在後面的執行階段沒有呼叫一般函式那樣的開銷,從而提高了速度。不過缺點是不能代替所有型別的函式。

4樓:板唱

可以,但不推薦。因為巨集只是簡單的替換,不檢驗引數合法性。

當然用的好,也可以實現很強大的功能。

在我blog裡有:用巨集實現的stack模板。

C語言關於巨集定義的習題,C語言中關於巨集定義的一道計算題

fudgf 5 x 等價於 2.84 y x,此時y 5,x 2 故結果為 2.84 5 2 12.84 轉為整型即為12,你理解錯了,如果將 define fudgf y 2.84 y 定義成 define fudgf y 2.84 y 這樣算出來的結果即為15 define fudgf y 2....

用陣列作函式引數,定義實現氣泡排序的函式,在主函式中完成資料的輸入和輸出

c語言的 如下 include void bubble sort int num 50 int n int main 其他排序演算法 1 插入排序 插入排序 已知一組升序排列資料a 1 a 2 a n 一組無序資料b 1 b 2 b m 需將二者合併成一個升序數列。首先比較b 1 與a 1 的值,若...

R語言hist函式中引數breaks的問題

1 函式 數學函式 函式的定義是給定一個數集a,假設其中的元素為x,對a中的元素x施加對應法則f,記作f x 得到另一數集b,假設b中的元素為y,則y與x之間的等量關係可以用y f x 表示。函式概念含有三個要素 定義域a 值域c和對應法則f。其中核心是對應法則f,它是函式關係的本質特徵。2 函式 ...