宏定義正確處理a++

今天c語言有一個題目,是宏實現一個數的平方,但是要正確處理a++這樣的參數。

這個我們正常使用還是不會有什麼問題,但是一旦參數改爲a++的話,這時候就不會得到跟我們理論的正確答案了。

#define   SOMETHING(b)	((b)*(b))

int main(void)
{
	int a=5;
	int b;

	b= SOMETHING (a)*8;

	printf("a = %d b = %d\n",a,b);
}

 

這時我們需要使用一個技巧 tfpeof

#define   SOMETHING(a)	({typeof(a) _b=a;(_b*=_b);})

int main(void)
{
	int a=5;
	int b;

	b= SOMETHING (a++)*8;

	printf("a = %d b = %d\n",a,b);
}

 



以下比較詳細的應用轉載自
https://www.cnblogs.com/emptyYPen/p/7872604.html


#define mul(a, b)  a*b
a = 2;
b = 3
mul(a+1, b+1);

結果是6。mul(a+1, b+1)被簡單的替代成 a+1*b+1 = 2+1*3+1 = 6。這個問題可以用()解決;

 

 

#define MAX(a, b)  (a) > (b)?(a) : (b)
int a = 5;
int b = 2;

MAX( a++, b );
//運行完後a = 7了,一下子自加了兩次。

 

宏替代後就是 (a++) > (b)? (a++) : (b);這明顯是違反了我們之前想要的。拿什麼來拯救宏。要不然宏也太垃圾了。答案是拿變量緩衝來解決這個問題。

 

#define MAX( a, b )  ({  \
    int _a = a;  \
    int _b = b;  \
    (_a) > (_b)? (_a) :(_b); \
  })

int a = 1, b = 3;
int c = MAX( a++, b);

複製代碼

完全解決了重複替代可能帶來的問題,我先將你的表達式賦值給一個變量,那傳入的表達式不就是一個普通的值了嗎。然後就可以進行各種操作了。

 

加強該宏 的能力,如果我的a,b不是int類型的呢?

使用typeof()來獲取傳入的量是什麼類型,終於找到一個獲取變量類型的操作了。

複製代碼

#define MAX( a, b )  ({ \
     typeof (a) _a = a;  \
     typeof (b) _b = b; \
     (_a)  > (_b)? (_a) : (_b); \
  )}

float a = 0.5, b = 1.2;

float c = MAX( a++, b);

複製代碼

再進行加強一下,進行數據類型檢測是否相同,相同不會出警告,不相同gcc        -Wall  會報警告。我們根據警告來查看我們程序是否有欠妥的地方。

複製代碼

#define MAX(a, b)  ({  \
    typeof (a)  _a = a;  \
    typeof (b)  _b = b;  \
    (void)( &_a == &_b);  \
    (_a) > (_b)?(_a) : (_b); \
  })

複製代碼

說明:{  ... }程序塊不能賦值,所以在外面加個(),就能實現int c = MAX(a, b)了;

          &_a 和&_b做比較,如果他們的指針類型不同,編譯器會報警告的,前面加(void)是防止編譯器報表達式&_a==&_b沒有被應用的警告。到這裏就搭建了一個健壯

的宏。

typeof ()也是66666,能用到void*身上嗎?

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章