三字符組與雙字符組
此條目沒有列出任何參考或來源。 (2017年3月20日) |
三字符組(trigraph)與雙字符組(Digraph)是程式語言(如C語言)中3個或者2個字符的序列,在編譯器預掃描源程序時被替換為單個字符。以解決某些鍵盤不能輸入某些編程必須的字符問題。
緣起
C語言的源程序的最低必須的字符集是基於7位ASCII碼字符集,是ISO 646-1983 Invariant Code Set的一個超集。ISO 646最初是1972年頒佈的一項國際化的7位ASCII標準,規定了12個字符所對應的碼位保持對各國標準開放:# $ @ [ \ ] ^ ` { | } ~
。
因為法國標準AFNOR NF Z 62010-1982把碼位0x7c(ASCII碼的 | )定義為ù,用法文鍵盤就難以輸入C語言的位或運算符 | ;碼位0x7e(ASCII碼的 ~)定義為 ¨ (即分音符),法文鍵盤就難以輸入C語言的位非運算符 ~ 。
加拿大法語標準CSA Z243.4-1985中把碼位0x5e(ASCII碼的 ^ )在定義為É,導致難以輸入C語言的異或運算符 ^ 。
三字符組
為解決上述的C語言原始碼輸入問題,C語言標準規定預處理器(C preprocessor)在掃描處理C語言源文件時,替換下述的3字符出現為1個字符
三字符組 | 替換為 |
---|---|
??= |
#
|
??/ |
\
|
??' |
^
|
??( |
[
|
??) |
]
|
??! |
|
|
??< |
{
|
??> |
}
|
??- |
~
|
如果希望在源程序中有兩個連續的問號,且不希望被預處理器替換,這種情況出現在字符常量、字符串字面值或者是程序註釋中,可選辦法是用字符串的自動連接:"...?""?..."
或者轉義序列:"...?\?..."
。
從Microsoft Visual C++ 2010版開始,該編譯器默認不再自動替換三字符組。如果需要使用三字符組替換(如為了兼容古老的軟件代碼),需要設置編譯器命令行選項/Zc:trigraphs
g++仍默認支持三字符組,但會給出編譯警告。
雙字符組
1994年公佈了一項C語言標準的修正案,引入了更具有可讀性的5個雙字符組。這也包括進了C99標準。
雙字符組 | 替換為 |
---|---|
<: |
[
|
:> |
]
|
<% |
{
|
%> |
}
|
%: |
#
|
不同於三字符組在源文件的任何出現都會被預處理器替換,雙字符如果出現在字符串字面值(quoted string)、字符常量、程序註釋中將不被替換。雙字符組的替換發生在編譯器對源程序的tokenization階段(即識別出關鍵字、標識符等,類似於自然語言的「斷詞」),僅當雙字符組作為一個token或者token的組成部分時(如%:%:
被替換為預處理運算符##
),雙字符組才被替換為單字符。
g++支持上述雙字符組替換。但Microsoft Visual C++不支持雙字符組替換。
C++
C++標準支持C語言的三字符組與雙字符組(包括C99中的增補)。C++自身還提供了下述內置的關鍵字:
關鍵字 | 等價於 |
---|---|
and
|
&&
|
bitor
|
|
|
or
|
||
|
xor
|
^
|
compl
|
~
|
bitand
|
&
|
and_eq
|
&=
|
or_eq
|
|=
|
xor_eq
|
^=
|
not
|
!
|
not_eq
|
!=
|
Microsoft Visual C++編譯器要求如果使用上述關鍵字,必須包含頭文件ciso646,否則編譯報錯。如「 error C2065: 'not' : undeclared identifier」。而g++編譯器就不要求包含頭文件ciso646。