2012-03-27 3 views
8

Это одно использование, которое я нашел в программном обеспечении с открытым исходным кодом. И я не понимаю, как это работает. Когда я выхожу на стандартный вывод, это была «версия 0.8.0».const char * initialization

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

Большое спасибо! –

ответ

7

Это основная особенность C89 и C++ 98, называемая «смежная конкатенация строк» ​​или около нее.

В принципе, если два строковых литерала смежны друг с другом без пунктуации между ними, они объединяются в одну строку, как показывает ваш вывод.


В стандарте C++ 98, "Этапы перевода [lex.phases] Раздел п.2.1 говорит:

6 Прилегающие обычная строка лексемы, сцепляются. Смежные широкоформатные литеральные жетоны объединены.

Это после того, как препроцессор завершил работу.

В стандарте C99, соответствующий раздел §5.1.2.1 «Перевод Фаза», и он говорит:

6 соседней строка лексема, сцепляется.

формулировка будет очень похож на любой другой стандарт C или C++, вы можете заложить руки на (и я признать, что и C++ 98 и С99 вытесняются C++ 11 и С11, я просто дон пока нет электронных копий окончательных стандартов).

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"; 

Перед конкатенация была изобретена, вы должны были сделать это с довольно неуклюжей продолжение строки, поставив обратную косую черту в конце каждого (и убедиться, что это был конец, поскольку большинство компиляторов не рассматривали его как продолжение линии, если после обратной косой черты были пробелы). Было также уродство, когда он отбрасывал отступы, потому что любые пробелы в начале последующих строк могут быть включены в строку.

Это может вызвать небольшую проблему, если вы намеревались поместить запятую между строками, например, при инициализации массива указателей на символ. Если вы пропустите запятую, компилятор не предупредит вас об этом - вы просто получите одну строку, которая включает в себя то, что было предназначено для двух отдельных.

6

Часть стандартной реализации C++ утверждает, что строковые литералы, которые находятся рядом друг с другом, будут объединены вместе.

Цитаты из C и C++ Standard:

Для 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"; 

EDIT: исправлены препроцессор компилятора

+0

Спасибо, исправлено – Attila

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!"); 
Смежные вопросы