巨集的一些副作用

2022-08-29 09:18:07 字數 1334 閱讀 6344

**:

1、優先順序問題

1) 傳入變數優先順序

#define multi(a,b) a * b

multi(1+2,3) => 1 + 2 * 3 其實是想要(1 + 2) * 3

2) 作為值返回時,類似1)

#define add(a,b) (a) + (b)

int c = add(a,b) * 3; => (a) + (b) * 3  其實是想要(a + b) * 3

所以,一般的規則是:巨集裡面引數全部用括號括起來;如果作為值返回,整個表示式也用括號括起來

所以,上面最好這麼寫:

#define multi(a,b) ((a) * (b))

#define add(a,b) ((a) + (b))

2、實際使用引數和巨集內部變數同名

#define hash(str,sz,rst) dowhile(0)

這是乙個hash的巨集實現,其中定義了乙個臨時變數n,根據str計算n,然後對sz求模並把返回值賦給傳進來的rst.

這麼呼叫:

int n;

hash("hello",7,n);

不會達到改變n的效果,因為實際使用引數n和巨集內部的變數n同名。巨集擴充套件中最後一條語句是:n = n % sz;因為巨集內部n有更小作 用域,實際賦值的是巨集內部的那個臨時變數n。外面呼叫的n不會有任何改變。

這個***有些隱蔽,一般的規則是:巨集內部變數使用一種不同風格的命名方式。

比如:#define hash(str,sz,rst) do)

也就是:保證傳入巨集的引數在內部只使用一次。(注意:傳入a++或++a都能得到各自正確的效果)

這裡的內部變數__x,__y是不需要用括號包起來的,原因可以自己想想。

另外對巨集中括號的使用補充說明兩點:

因為巨集中定義了臨時變數,所以要用{}括起來;

因為要返回值,所以外面還要用()括起來({}不返回值);

另外,這裡還有乙個問題:實際中a,b不一定是int的,這個巨集中的臨時變數宣告為int,不通用。

改進:#define max(a,b,type) ()

使用:max(1,2,int);  max(1.1,1.2,double);

是不是感覺怪怪的,有點c++的感覺~~ 這樣的使用太複雜了,而且也會給**的閱讀帶來難度。

我覺得好的態度是多了解些巨集的可能的***,在實際編碼中遵守第1、2條規則,不要往巨集中傳入自增自減的東西,就夠了。不要把過多的複雜度全扔給巨集,"通用"也不能盲目,因為畢竟:yy是沒有極限的。

補充:今天看到有人用typeof,很好的解決了上面的問題。

一些藥物的副作用

1。解熱鎮痛成分 如阿司匹林 對乙醯氨基酚 雙氯芬酸 氨基比林等,這些成分具有發汗退熱 緩解頭痛及關節疼痛等作用。在我們現在常用的感冒藥 如泰諾 白加黑 日夜百服寧等 中大部分藥皆含對乙醯氨基酚,而對乙醯氨基酚對肝臟損害嚴重,所以肝 腎功能不全者要慎用,並且3歲以下小兒最好不用。本藥又能通過胎盤,所...

巨集的副作用

巨集定義在實際使用中如果不稍加注意,如果表示式有 就可能導致返回的結果跟預期不符。下面是幾種常見的問題 define multi a,b a b multi 1 2,3 1 2 3 define add a,b a b int c add 1,2 3 1 2 3因此巨集的引數和返回值最好是用 擴起來...

C C 巨集 巨集的作用 副作用

基礎 巨集是預處理指令 巨集的本質是簡單的字串替換,預處理時進行巨集替換 可在定義巨集時要求它接收引數,巨集替換時會代入引數 巨集的名字不允許過載 巨集預處理 沒有能力處理遞迴呼叫。作用 看一段math.h中的巨集定義 if defined use math defines defined math...