1、在一個預處理器宏中的參數前面使用一個#,預處理器會把這個參數轉換為一個字元數組。(原文:When you put a # before an argument in a preprocessor
macro, the preprocessor turns that argument into a character array. This,
combined with the fact that character arrays with no intervening punctuation are concatenated into a single character array, allows you to make a very convenient macro for printing the values of variables during debugging)
#include "iostream"
using namespace std;
#define P(A) cout<<#A<<": "<<(A)<<endl;
int main()
{
int a=1,b=2;
P(a);
P(b);
P(a+b);
return 1;
}
http://blog.163.com/zhoumhan_0351/blog/static/39954227201032124942513/
2、#define D(a) cout << #a "=[" << a << "]" << endl;
3、#是“字元串化”的意思。出現在宏定義中的#是把跟在後面的參數轉換成一個字元串
例如:
> #define FOO(arg) my##arg
則
> FOO(abc)
相當于 myabc
> #define STRCPY(dst, src) strcpy(dst, #src)
> STRCPY(buff, abc)
相當于 strcpy(buff, "abc")
另外,如果##後的參數本身也是一個宏的話,##會阻止這個宏的展開,也就是隻替換一次。
#define STRCPY(a, b) strcpy(a ## _p, #b)
int main()
{
char var1_p[20];
char var2_p[30];
/* 注意這裡 */
STRCPY(STRCPY(var1,var2),var2);
/* 這裡是否會展開為: strcpy(strcpy(var1_p,"var2")_p,"var2“)?
* 答案是否定的:
* 展開結果将是: strcpy(STRCPY(var1,var2)_p,"var2")
* ## 阻止了參數的宏展開!
* 如果宏定義裡沒有用到 # 和 ##, 宏将會完全展開
*/
}
http://blog.chinaunix.net/u/17855/showart_113663.html
4、about ## in common text
(1)關于記号粘貼操作符(token paste operator): ##
簡單的說,“##”是一種分隔連接配接方式,它的作用是先分隔,然後進行強制連接配接。
其中,分隔的作用類似于空格。我們知道在普通的宏定義中,預處理器一般把空格解釋成分段标志,對于每一段和前面比較,相同的就被替換。但是這樣做的結果是,被替換段之間存在一些空格。如果我們不希望出現這些空格,就可以通過添加一些##來替代空格。
另外一些分隔标志是,包括操作符,比如 +, -, *, /, [,], ...,是以盡管下面的
宏定義沒有空格,但是依然表達有意義的定義: define add(a, b) a+b
而其強制連接配接的作用是,去掉和前面的字元串之間的空格,而把兩者連接配接起來。
(2)舉列 -- 試比較下述幾個宏定義的差別
#define A1(name, type) type name_##type##_type 或
#define A2(name, type) type name##_##type##_type
A1(a1, int); /* 等價于: int name_int_type; */
A2(a1, int); /* 等價于: int a1_int_type; */
解釋:
1) 在第一個宏定義中,"name"和第一個"_"之間,以及第2個"_"和第二個"type"之間沒有被分隔,是以預處理器會把name_##type##_type解釋成3段:
“name_”、“type”、以及“_type”,這中間隻有“type”是在宏前面出現過
的,是以它可以被宏替換。
2) 而在第二個宏定義中,“name”和第一個“_”之間也被分隔了,是以
預處理器會把name##_##type##_type解釋成4段:“name”、“_”、“type”
以及“_type”,這其間,就有兩個可以被宏替換了。
3) A1和A2的定義也可以如下:
#define A1(name, type) type name_ ##type ##_type
<##前面随意加上一些空格>
#define A2(name, type) type name ##_ ##type ##_type
結果是## 會把前面的空格去掉完成強連接配接,得到和上面結果相同的宏定義
(3)其他相關 -- 單獨的一個 #
至于單獨一個#,則表示對這個變量替換後,再加雙引号引起來。比如
#define __stringify_1(x) #x
那麼
__stringify_1(linux) <==> "linux"
(5)#(stringizing)字元串化操作符。其作用是:将宏定義中的傳入參數名轉換成用一對雙引号括起來參數名字元串。其隻能用于有傳入參數的宏定義中,且必須置于宏定義體中的參數名前。
如:
#define example(instr) printf("the input string is:\t%s\n",#instr)
#define example1(instr) #instr
當使用該宏定義時:
example(abc); 在編譯時将會展開成:printf("the input string is:\t%s\n","abc");
string str=example1(abc); 将會展成:string str="abc";
注意:
對空格的處理
a。忽略傳入參數名前面和後面的空格。
如:str=example1( abc ); 将會被擴充成 str="abc";