c c 未知的陷阱 2元 3元轉義字元

2021-06-16 09:00:59 字數 4333 閱讀 5866

在編寫程式時需要時時提防編譯器揹著我們幹一些沒有通知我們做的事,下面列舉轉義字元對程式的影響。

首先列出二字元組和三字元組對應的意思。

二元字元

等價字元

<:[

:>]

<%

%:或者%%

#

三元字元  等價字元

??=#

??/\

??'^

??([

??)]

??!|

??<

??-~

值得慶幸的是,二元字元或者三元字元轉義之後不能再與二元字元或者三元字元結合,要不然程式設計師可能會瘋了。閒話少說,那麼為什麼會c++標準允許出現這種情況呢?

根據intention to deprecate trigraphs in the next c++ standard可以知道這有兩個原因:

1.由於類似「#\」等這些字元在ebcdic的**頁中用來區分**點的。在所有的ebcdic的**頁中使用「?」和"="不會分割**頁,而會共享同乙個**點。

2.其次是因為一些國際化的鍵盤設定原因,有些鍵盤沒有這些字元對應的按鍵,而這些字元又必須在一些文字中使用,因此採用一些替代方法。

知道了原因,接下來看看讓程式設計師摸不著頭腦的錯誤**(其實不是語法錯誤,而是程式執行的結果會讓你大吃一驚)。

情形1:  

#include int main()

程式執行前,聰明的讀者可以猜猜結果是多少?改變上面的程式,僅僅是一點點的一點點。

情形2:

#include int main()

最終的結果又是多少呢?

未執行前,你是否認為情形1的結果與情況2的結果一樣,輸出的結果都是101呢?細心的讀者,會認為情形1的最終結果是2,而情形2的結果是101呢?

當然你認為的結果在有些編譯器下確實是對的,這是因為有些編譯器在預設情況將3元轉義字元是禁止的。例如我在mac的g++編譯器下編譯上面的程式時它會提醒乙個警告,如下:

warning: trigraph ??/ ignored, use -trigraphs to enable

即要使用trigraphs在編譯時需要新增上-trigraphs引數。因此未加-trigraphs引數時,得出的結果與細心的讀者預料的結果一致。而加上-trigraphs引數之後,那麼結果你可能就得好好分析了。這裡我們知道了注釋行存在乙個三元轉義符"??/",其對應得符號為"\",而"\"將其下面得一行**也作為注釋,所以情形1實際的**為:

#include int main()

情形2實際執行的**為:

#include int main()

因此情形1的輸出為: 1 

情形2的輸出為:11111111111。。。1(一共為100個1)。

或許你認為上面的錯誤出現的概率極其小,其實這是由於"?"與"/"只相差乙個shift鍵而已。本來程式設計師是想列印出多個「???」,卻在最後乙個「?」鬆開了shift鍵,而將「???」變成了「??/」。最終的結果你也看到了吧!

還有更多的2元、3元轉義字元造成的一些莫名其妙的結果參見:

最後,不得不提一下c++標準委員會已經在2023年對是否取消3元轉義符號問題進行了投票,雖然沒有完全取消三元轉義字元,但是增加一些使用的限制。具體可參考:中的解答。

ps:前面提到了ebcdic碼,而我們學習的基本上都是基於asc碼的,那麼他們之間的區別為什麼呢?

使用得最多的、最普遍的是ascii字元編碼, 即american standard code for information interchange, 如表1所示。

從表中可以看到:

每個字元是用7位基2碼表示的, 其排列次序為b6b5b4b3b2b1b0, 在表中的b6b5b4為高位部分, b3b2b31b0為低位部分。而乙個字元在計算機內實際上用8位表示。正常情況下, 最高一位b7為 "0"。在需要奇偶校驗時, 這一位可用於存放奇偶校驗的值, 此時稱這一位為校驗位。

表1 ascii字元編碼表

b6b5b4

000   001   010   011   100   101   110   111

b3b2b1b0

-

0 0 0 0 

0 0 0 1 

0 0 1 0 

0 0 1 1

0 1 0 0 

0 1 0 1

0 1 1 0

0 1 1 1 

1 0 0 0 

1 0 0 1

1 0 1 0

1 0 1 1

1 1 0 0

1 1 0 1

1 1 1 0

1 1 1 1

nul   dle   sp    0    @    p    、   p

soh   dc1   !     1    a    q    a    q

stx   dc2   "     2    b    r    b    r

etx   dc3   #     3    c    s    c   s

eot   dc4   $    4    d    t    d    t

enq   nak   %    5    e    u    e   u

ack   syn   &     6    f    v    f   v

bel   etb   '     7    g    w    g   w

bs    can   (     8    h    x    h   x

ht    em   )    9    i    y    i   y

lf    sub    *    :    j    z    j   z

vt   esc   +    ;    k    [    k   

so    rs    .    >    n    ↑    m   ~

si    us    /    ?    o     -    o    del

ascii是128個字元組成的字符集。其中編碼值0-31不對應任何可印刷(或稱有字形)字元, 通常稱它們為控制字元, 用於通訊中的通訊控制或對計算機裝置的功能控制。編碼值為32的是空格(或間隔)字元sp。編碼值為127的是刪除控制del碼。其餘的94個字元稱為可印刷字元,有人把空格也計入可印刷字元時,則稱有95個可印刷字元。請注意, 這種字元編碼中有如下兩個規律:

(1)字元0-9這10個數字元的高3位編碼為011, 低4 位為000-1001。當去掉高3位的值時, 低4位正好是二進位制形式的0-9。這既滿足正常的排序關係, 又有利於完成ascii碼與二進位製碼之間的型別轉換。

(2)英文本母的編碼值滿足正常的字母排序關係, 且大、小寫英文本母編碼的對應關係相當簡便, 差別僅表現在b5一位的值為0或1, 有利於大、小寫字母之間的編碼變換。

另有一種字元編碼,是主要用在ibm計算機中的ebcdic**(extended binary coded decimal interchange code)。它採用8位碼, 有256個編碼狀態, 但只選用其中一部分。0-9十個數字符的高4位編碼為1111, 低4位仍為0000-1001。大、小寫英文本母的編碼同樣滿足正常的排序要求, 而且有簡單的對應關係, 即同乙個字母的大小寫的編碼值僅最高的第二位的值不同, 易於識別與變換。

google收錄,注意元標記的陷阱!

相信很多站長都知道robots吧,不知道的搜一下 但是很多站長卻忽略了www.cppcns.com元標記也可以阻止 的收錄。我的部落格位址是www.cppcns.comourys.com,網域名稱原來是乙個電影 最後我沒有做電影 一心做自己的部落格 但是過了乙個多月,google收錄的還是我以前的 ...

轉 D3D中的四元數

在3d程式中,通常用quaternion來計算3d物體的旋轉角度,與matrix相比,quaternion更加高效,占用的儲存空間更小,此外也更便於插值。在數學上,quaternion表示複數w xi yj zk,其中i,j,k都是虛數單位 i i j j k k 1 i j k,j i k 可以把...

python3元類 python3元類的呼叫順序

在嘗試理解元類建立類例項的順序時,我感到困惑.根據該圖 source 我鍵入以下 進行驗證.class meta type def call self print meta call super meta,self call def new mcs,name,bases,attrs,kwargs p...