Posted on 2007-08-06 17:00
daiybh 閱讀(79)
評論(0) 編輯 收藏 引用
轉自紫羅蘭茶館(http://blog.vckbase.com/lishengg_blog/)
我在學習VC,或者在閱讀別人寫的文章的時候,偶爾碰到下面很多有趣的,并且很奇怪的語句,整理起來,以備后忘. 其實有些是不大容易想到的技巧,貼出來權當大伙飯后沒事的小品文,當然不要過多的看重類似的語句學習,而忽略了基礎知識。
一. 奇怪的宏定義
(1) #define for if(0); else for
按照c++標準,for中定義的變量的作用域應該只在for循環中有效,而VC卻不行,比如這樣定義是不對的
for(int i=0;i<90;i++)
{
...;
}
for(int i=0;i<90;i++) //重復定義i變量
{
...;
}
如果加上標題的那句,那么就可以了,就是讓i作用域局限在else中. 這個問題在net中已經得到解決。
二、宏定義怪圈
#define wait_event(wq,condition) \
do{ \
if(condition) \
break; \
__wait_event(wq,condition); \
}while(0)
明明這句話只執行一次,為什么還還用do-while語句呢?
假設有這樣一個宏定義
#define macro(condition) \
if(condition) dosomething();
現在在程序中這樣使用這個宏:
if(temp)
macro(i);
else
doanotherthing();
一切看起來很正常,但是仔細想想。這個宏會展開成:
if(temp)
if(condition) dosomething();
else
doanotherthing();
這時的else不是與第一個if語句匹配,而是錯誤的與第二個if語句進行了匹配,編譯通過了,但是運行的結果一定是錯誤的。為了避免這個錯誤,我們使用do{….}while(0) 把它包裹起來,成為一個獨立的語法單元,從而不會與上下文發生混淆。同時因為絕大多數的編譯器都能夠識別do{…}while(0)這種無用的循環并進行優化,所以使用這種方法也不會導致程序的性能降低。
這個用法在linux源碼中很常見。
三、功能強大的解釋
除了/* */和 //解釋以外,你見過這樣的解釋方法了嗎?
#if(0)
........
#endif
這樣是為了解釋掉某段程序,而不影響其中的/*...*/的作用,便于調試,而/*.....*/是不能嵌套的,編譯會出錯.
四、數組變臉 a[i]和i[a]
在程序里本應該用a[i],但i[a]竟然和a[i]輸出的結果一樣。為什么。今天把問題整理如下:
i[a]是標準語法。“[]”稱為下標運算符,其語法為:
postfix_expression [ expression ]
其中“postfix_expression”和“expression”之中必須有一個是指針類型(或數組),而另一個是整型。
例如下面的程序是完全合法的:
int a[]={0,1,2,3,4};
printf("%d\n",3[a]);
下標運算符參與的表達式在求解時僅僅是做一個變換而已,將“postfix_expression [ expression ]”
改寫為“ * ( postfix_expression + expression ) ”,因此a[3]和3[a]分別改寫為*(a+3)和*(3+a),
可見二者是完全等價的。但注意不要用i[a]這種形式,因為它不符合日常習慣。
實驗代碼:
#include "stdafx.h"
#include "iostream.h"
int f();
int main(int argc, char* argv[])
{
int a[20]={1,2,3,4,5,6,7,8,9};
cout<