2012-03-27 185 views
8

這是我在開源軟件中找到的一個用法,我不明白它是如何工作的。 當我輸出到標準輸出時,它是「版本0.8.0」。const char *初始化

const char version[] = " version " "0" "." "8" "." "0"; 
+0

非常感謝! – 2012-03-27 15:28:38

回答

7

這是C89和C++ 98的一個基本功能,稱爲'相鄰字符串連接'或其附近。

基本上,如果兩個字符串文字彼此相鄰且沒有標點符號,它們會合併爲單個字符串,如輸出所示。


在C++ 98標準,部分§2.1 '翻譯的相位[lex.phases]' 表示:

6相鄰的普通字符串文字令牌是級聯。相鄰的寬字符串文字標記是連接的。

這是在預處理器完成之後。

在C99標準,相應的部分是§5.1.2.1「轉換階段」,它表示:

6相鄰的字符串文字令牌是級聯。

的措辭將是任何其他C或C++標準,你可以躺在手非常相似的(我承認,這兩個C++ 98和C99是由C++ 11和C11取代;我只是不沒有最終標準的電子版本)。

3
const char version[] = " version " "0" "." "8" "." "0"; 

是相同:

const char version[] = " version 0.8.0"; 

編譯器串接的相鄰件字符串常量,使得一個大的一塊字串文本的。

作爲旁註,const char*(它在您的標題中)與char char[](它在您的發佈代碼中)不一樣。

9

它被稱爲字符串連接 - 當您在源代碼中放置兩個(或多個)帶引號的字符串時,它們之間沒有任何內容,編譯器將它們放在一起放入單個字符串中。這是最常用的長字符串 - 任何超過一週行長:

char whatever[] = "this is the first line of the string\n" 
    "this is the second line of the string\n" 
    "This is the third line of the string"; 

之前字符串連接被髮明出來,你必須這樣做有相當笨拙續行,把一個反斜槓在每年年底行(並確保它是最終的,因爲如果反斜槓後面有空格,大多數編譯器不會將它視爲續行)。還有一種醜陋的情況是它會縮小縮進,因爲後續行的開始處的任何空格都可能包含在字符串中。

如果您打算在字符串之間插入逗號,例如初始化指向char的指針數組時,這可能會導致一個小問題。如果你錯過逗號,編譯器不會提醒你 - 你只會得到一個字符串,其中包含了兩個單獨的字符串。

6

C++標準實現的一部分規定,彼此相鄰的字符串文字將被連接在一起。從C和C++標準

行情:

對於C(報價C99,C11,但在6.4.5p5類似的東西):

(C99,6.4.5p5)「在翻譯階段6,由任何相鄰字符序列指定的多字節字符 序列和 帶相同前綴的字符串文字標記連接成單個多字節字符序列的 。

對於C++:

(C++ 11,2.14.5p13) 「以轉換階段6(2.2),相鄰的字符串 文字是級聯」。

2

編譯器自動串接後彼此寫入字符串(由白色空間分離只)..這是因爲如果你寫

const char version[] = "version 0.8.0"; 

編輯:校正預處理器編譯器

+0

謝謝,糾正 – Attila 2012-03-27 15:21:49

2

相鄰字符串文字是concatenated

當指定字符串常量,相鄰串是級聯。 因此,此聲明:

char szStr [] =「12」「34」;與此聲明相同:

char szStr [] =「1234」;相鄰的字符串這串聯使得 容易在多個行指定長字符串:

COUT < <「四個得分和七年」
「以前,我們的祖先帶來了」
「在這個大陸一個新的國家。「;

0

乾脆把字符串一個接一個將其連接在編譯時間,所以:

"Hello" ", " "World!" => "Hello, World!" 

這是功能的一個奇怪的,通常它是允許使用#define字符串:

#define FOO "World!" 

puts("Hello, " FOO); 

將編譯到相同:

puts("Hello, World!");