1、
# (stringizing
)字串化操作符。其感化是:將巨集定義中的傳入引數名轉換成用一對雙引號括起來引數名字串。其只能用於有傳入引數的巨集定義中,且必須置於巨集定義體中的引數名前。
< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />
如:#define example(instr) printf("the input string is:\t%s\n",#instr)
#define example1(instr) #instr
注意:對空格的處理 a
。忽略傳入引數名前面和後面的空格。 如:
str=example1( abc )
;將會被擴充套件成
str="abc";
b.當傳入引數名間存在空格時,編譯器將會自動連線各個子字串,用每乙個子字串中只以乙個空格連線,忽略其中多餘乙個的空格。 如:
str=exapme( abc def);
將會被擴充套件成
str="abc def";
} 2、
## (
token-pasting
)符號連線操作符
巨集定義中:引數名,即為形參,如
#define sum(a,b) (a+b);中a
和b均為某一引數的代表符號,即形式引數。 而
##的感化則是將巨集定義的多個形參成乙個實踐引數名。 如:
#define examplenum(n) num##n
int num9=9; 3
、@#
(charizing
)字元化操作符。
int num=examplenum(9);
將會擴充套件成
int num=num9;
注意:只能用於有傳入引數的巨集定義中,且必須置於巨集定義體中的引數名前。感化是將傳的單字元引數名轉換成字元,以一對單援用括起來。 如:
#define examplenum(n) num ## n
相當於#define examplenum(n) num##n
example(abc)
;在編譯時將會展開成:
printf("the input string is:\t%s\n","abc");
// preprocessor_token_pasting.cpp
#include
#define paster( n ) printf_s( "token" #n " = %d", token##n )
int token9 = 9;
int main()
輸出為[leshy@leshy src]$ ./a.out
token 9 = 10
巨集定義的特殊符號# ## - [c++]
1. 使用巨集引數建立字串:
# 運算子
在類函式巨集(
function-like macro
)的替換部門中,
「#」符號用作乙個預處理運算子,它可以把語言符號(
token
)轉化為字串。例如,若是
x 是乙個巨集參量,那麼
#x 可以把引數名轉化為相應的字串。該歷程稱為字串化。
說明:類函式巨集就是帶引數的巨集。類函式巨集的定義中,用圓括號括起來乙個或多個引數,隨後這些引數出如今替換部門。
#include
#define psqr(x) printf("the square of " #x " is %d. \r\n", (x) * (x))
int main(void)
// 輸出:the square of y is 25. //
用"y"
代替#x
the square of 2 + 4 is 36. //
用"2 + 4"
代替#x
#include
#define psqr(x) printf("the square of " #x " is %d. \r\n", (x) * (x))
int main(void)
// 輸出:
the square of y is 25. //
用"y"
代替#x
the square of 2 + 4 is 36. //
用"2 + 4"
代替#x
#define string2(x) #x
#define string(x) string2(x)
#define wq wangqi
#pragma message(string2(wq)) // wq
(字串)
#pragma message(string(wq)) // wangqi
(字串)
#define string2(x) #x
#define string(x) string2(x)
#define wq wangqi
#pragma message(string2(wq)) // wq
(字串)
#pragma message(string(wq)) // wangqi
(字串)
2. 預處理器的粘合劑:
## 運算子和#
運算子一樣,
## 運算子可以用於類函式巨集的替換部門。另外,
## 運算子還可用於類物件巨集(
object-like macro
)的替換部門。這個運算子把兩個語言符號組合成單個語言符號。例如,可以定義如下巨集:
#define xname(n) x ## n
#define xname(n) x ## n
巨集挪用xname(4)
會展開成
x4 。
說明:類物件巨集就是用來代表值的巨集。如,
#define pi 3.141593
中的pi
。#include
#define xname(n) x ## n
#define print_xn(n) printf("x" #n " = %d\r\n", x ## n);
int main(void)
// 輸出:x1 = 14
x2 = 20
#include
#define xname(n) x ## n
#define print_xn(n) printf("x" #n " = %d\r\n", x ## n);
int main(void)
// 輸出:
x1 = 14
x2 = 20
#define __t(x) l ## x
#define _t(x) __t(x)
#define _text(x) __t(x)
#define wq "wangqi"
#pragma message(__t(wq)) // lwq (
識別符號)
wcout << _t(wq); // wangqi
(寬位元組字串)
#define __t(x) l ## x
#define _t(x) __t(x)
#define _text(x) __t(x)
#define wq "wangqi"
#pragma message(__t(wq)) // lwq (
識別符號)
wcout << _t(wq); // wangqi
(寬位元組字串)
3. 語言符號
從手藝方面看,系統把巨集的主體當作語言符號(
token
)型別字串,而不是字元型字串。
c 預處理器中的語言符號是巨集定義主體中的單獨的「詞(
word)」
。用空白字元把這些詞分隔隔離渙散。例如:
#define four 2*2
#define four 2*2
這個定義中有乙個語言符號:即序列
2*2
。但是:
#define six 2 * 3
#define six 2 * 3
這個定義中有三個語言符號:2、
* 和3 。
在處理主體中的多個空格時,字元型字串和語言符號型字串採用不同方法。考慮下面的定義:
#define eight 4 * 8
#define eight 4 * 8
把主體解釋為字元型字串時,預處理器用
4 * 8
替換eight
。也就是說,額外的空格也當作替換文字的一部門。但是,當把主體解釋為語言符號型別時,預處理器用由單個空格分隔的三個語言符號,即
4 * 8
來替換eight
。換句話說,用字元型字串的觀點看,空格也是主體的一部門;而用語言符號字串的觀點看,空格只是分隔主體中語言符號的符號。在實踐使用中,有些
c 編譯器把巨集主體當作字串而非語言吊絲男士第3季符號。在比這個例項更複雜的環境下,字元與語言符號之間的差異才有實踐意義。
順便提一下,
c 編譯器處理語言符號的方式比預處理器的處理方式更加複雜。編譯器能理解
c 的劃定規矩,不需要用空格來分隔語言符號。例如,
c 編譯器把
2*2
當作三個語言符號。原因是
c 編譯器認為每乙個
2 都是乙個常量,而
* 是乙個運算子。
a = makechar(b);
c 中的巨集定義
一 不帶引數的巨集定義 巨集定義又稱為巨集代換 巨集替換,簡稱 巨集 格式 define 識別符號 字串 其中的識別符號就是所謂的符號常量,也稱為 巨集名 預處理 預編譯 工作也叫做巨集展開 將巨集名替換為字串。掌握 巨集 概念的關鍵是 換 一切以換為前提 做任何事情之前先要換,準確理解之前就要 換...
C中的巨集定義
01 防止乙個標頭檔案被重複包含 ifndef comdef h define comdef h 標頭檔案內容 endif 02 重新定義一些型別,防止由於各種平台和編譯器的不同,而產生的型別位元組數差異,方便移植。typedef unsigned char boolean boolean valu...
C 中的巨集定義
二 define中的三個特殊符號 define conn x,y x y define tochar x x define tostring x x 1 x y 表示什麼?表示x連線y,舉例說 int n conn 123,456 結果就是n 123456 char str conn asdf ad...