~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ 4A4A7443BDF65FE512AE7795AE12138A__1711952280 ✰
Заголовок документа оригинал.:
✰ String literal - Wikipedia ✰
Заголовок документа перевод.:
✰ Строковый литерал — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/String_literal ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/4a/8a/4a4a7443bdf65fe512ae7795ae12138a.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/4a/8a/4a4a7443bdf65fe512ae7795ae12138a__translat.html ✰
Дата и время сохранения документа:
✰ 21.06.2024 10:09:24 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 1 April 2024, at 09:18 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Строковый литерал — Википедия Jump to content

Строковый литерал

Из Википедии, бесплатной энциклопедии

Строковый литерал или анонимная строка [1] является литералом строкового значения в исходном коде компьютерной программы . Современные языки программирования обычно используют последовательность символов в кавычках, формально « разделителей в квадратных скобках », как в x = "foo", где "foo" представляет собой строковый литерал со значением foo. Такие методы, как escape-последовательности, можно использовать, чтобы избежать проблемы столкновения разделителей (проблемы с скобками) и позволить разделители встраивать в строку. Существует множество альтернативных обозначений для указания строковых литералов, особенно в сложных случаях. Точное обозначение зависит от языка программирования рассматриваемого . Тем не менее, существуют общие рекомендации, которым следуют большинство современных языков программирования.

Синтаксис [ править ]

Разделители в скобках [ править ]

В большинстве современных языков программирования используются разделители в скобках (также сбалансированные разделители ). для указания строковых литералов. Двойные кавычки являются наиболее распространенными разделителями кавычек:

 "Всем привет!"
 

Пустая строка буквально записывается парой кавычек без каких-либо символов между ними:

 ""
 

Некоторые языки либо разрешают, либо требуют использования одинарных кавычек вместо двойных (строка должна начинаться и заканчиваться кавычками одного и того же типа, а тип кавычек может давать или не давать немного разную семантику):

 'Всем привет!'
 

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

В терминах регулярных выражений базовый строковый литерал в кавычках задается как:

"[^"]*"
 

Это означает, что строковый литерал записывается как: кавычка, за которой следует ноль, один или несколько символов, не являющихся кавычками, а затем кавычка . На практике это часто усложняется экранированием, другими разделителями и исключением символов новой строки.

Парные разделители [ править ]

В ряде языков предусмотрены парные разделители, в которых открывающий и закрывающий разделители различны. Они также часто допускают вложенные строки, поэтому разделители могут быть встроены, если они парные, но все равно приводят к коллизии разделителей при внедрении непарного закрывающего разделителя. Примеры включают PostScript , в котором используются круглые скобки, как в (The quick (brown fox))и m4 , который использует обратную галочку (`) в качестве начального разделителя и апостроф (') в качестве конечного разделителя. Tcl допускает как кавычки (для интерполированных строк), так и фигурные скобки (для необработанных строк), как в "The quick brown fox" или {The quick {brown fox}}; это происходит из-за одинарных кавычек в оболочках Unix и использования фигурных скобок в C для составных операторов, поскольку блоки кода в Tcl синтаксически то же самое, что и строковые литералы - чтобы сделать это возможным, важно, чтобы разделители были парными.

Набор символов Юникода включает парные (отдельные открывающие и закрывающие) версии как одинарных, так и двойных кавычек:

"Всем привет!"
  'Всем привет!'
  "Всем привет!"
  "Всем привет!"
 

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

Разделители пробелов [ править ]

Строковые литералы могут заканчиваться символами новой строки.

Одним из примеров являются MediaWiki параметры шаблона .

{{Навбокс
  |имя=Нулевые значения
  |title=[[wikt:Null|Nulls]] в [[computing]]
  }} 

Для многострочных строк может быть специальный синтаксис.

В YAML строковые литералы могут указываться относительным расположением пробелов и отступ.

    -   title  :   пример многострочной строки в 
       теле  YAML :   | 
          Это многострочная строка. 
         могут появиться «специальные» метасимволы 
          Здесь  .  Размер этой строки 
         представлен отступом. 

Без разделителей [ править ]

Некоторые языки программирования, такие как Perl и PHP, в некоторых контекстах допускают строковые литералы без каких-либо разделителей. Например, в следующей программе Perl: red, green, и blue являются строковыми литералами, но не заключаются в кавычки:

%map   =   (  красный   =>   0x00f  ,   синий   =>   0x0f0  ,   зеленый   =>   0xf00  ); 

В большинстве контекстов Perl рассматривает незарезервированные последовательности буквенно-цифровых символов как строковые литералы. Например, следующие две строки Perl эквивалентны:

  =   "х"  ; 
  =   х  ; 

Декларативная нотация [ править ]

В исходном языке программирования FORTRAN (например) строковые литералы записывались в так называемой Холлерита нотации , где за десятичным числом символов следовала буква H, а затем символы строки:

35  HA   Пример   Холлерита   литерала   строкового 

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

Преимущества:

Недостатки:

Однако это не является недостатком, когда префикс генерируется алгоритмом, что наиболее вероятно. [ нужна цитата ]

Функции конструктора [ править ]

В C++ есть два стиля строк: один унаследован от C (разделен "), и тем безопаснее std::stringв стандартной библиотеке C++. std::stringclass часто используется так же, как строковый литерал в других языках, и его часто предпочитают строкам в стиле C из-за его большей гибкости и безопасности. Но это приводит к снижению производительности для строковых литералов, поскольку std::string обычно выделяет память динамически и должен копировать в нее строковый литерал в стиле C во время выполнения.

До C++11 не существовало литерала для строк C++ (C++11 позволяет "this is a C++ string"s с s в конце литерала), поэтому использовался обычный синтаксис конструктора, например:

  • std::string str = "initializer syntax";
  • std::string str("converting constructor syntax");
  • std::string str = string("explicit constructor syntax");

все они имеют одну и ту же интерпретацию. Начиная с C++11, появился новый синтаксис конструктора:

  • std::string str{"uniform initializer syntax"};
  • auto str = "constexpr literal syntax"s;

Столкновение разделителей [ править ]

Если при использовании кавычек кто-то хочет представить сам разделитель в строковом литерале, он сталкивается с проблемой коллизии разделителей . Например, если разделителем является двойная кавычка, нельзя просто представить саму двойную кавычку с помощью литерала """ поскольку вторая кавычка интерпретируется как конец строкового литерала, а не как значение строки, и аналогично нельзя написать "This is "in quotes", but invalid."поскольку средняя часть кавычек вместо этого интерпретируется как вне кавычек. Существуют различные решения, наиболее универсальным из которых является использование escape-последовательностей, таких как "\"" или "This is \"in quotes\" and properly escaped.", но есть много других решений.

Парные кавычки, такие как фигурные скобки в Tcl, допускают вложенные строки, например {foo {bar} zork} но не решайте иначе проблему коллизии разделителей, так как несбалансированный закрывающий разделитель нельзя просто включить, как в {}}.

Удвоение [ править ]

В ряде языков, включая Pascal , BASIC , DCL , Smalltalk , SQL , J и Fortran , конфликты разделителей избегаются за счет удвоения кавычек, которые должны быть частью строкового литерала. сам:

  'Эта строка Паскаля  ''  содержит два апострофа  ''  ' 
  «Я сказал: «Ты меня слышишь?»»» 

Двойное цитирование [ править ]

Некоторые языки, такие как Fortran , Modula-2 , JavaScript , Python и PHP , допускают использование более одного разделителя кавычек; в случае двух возможных разделителей это называется двойными кавычками . Обычно это означает, что программисту разрешено использовать как одинарные, так и двойные кавычки взаимозаменяемо — каждый литерал должен использовать то или другое.

  «Это яблоко Джона». 
    «Я спросил: «Ты меня слышишь?» 

Однако это не позволяет иметь один литерал с обоими разделителями. Эту проблему можно обойти, используя несколько литералов и конкатенацию строк :

  «Я сказал: «Это»   +   «Джона»   +   «яблоко». 

В Python есть конкатенация строковых литералов , поэтому последовательные строковые литералы объединяются даже без оператора, поэтому это можно сократить до:

  «Я сказал: «Это  Джона» .  яблоко 

Разделитель кавычек [ править ]

В C++11 появились так называемые необработанные строковые литералы . Они состоят, по существу, из

R" идентификатор конца строки ( содержание ) идентификатор конца строки ",

то есть после R"программист может ввести до 16 символов, за исключением пробелов, круглых скобок и обратной косой черты, которые образуют идентификатор конца строки (его цель состоит в том, чтобы повториться для обозначения конца строки, eos id для краткости ), а затем Требуется открывающая скобка (для обозначения конца идентификатора eos). Затем следует фактическое содержимое литерала: можно использовать любые символы последовательности (за исключением того, что они не могут содержать закрывающую скобку, за которой следует идентификатор eos после кавычки), и, наконец, для завершения строки — закрывающую скобку, идентификатор eos. , и требуется цитата.
Самый простой случай такого литерала — с пустым содержимым и пустым идентификатором eos: R"()".
Идентификатор eos сам может содержать кавычки: R""(I asked, "Can you hear me?")"" является допустимым литералом (идентификатор eos равен " здесь.)
Escape-последовательности не работают с необработанными строковыми литералами.

D поддерживает несколько разделителей в кавычках, причем такие строки начинаются с q" плюс открывающий разделитель и заканчивается соответствующим закрывающим разделителем и ". Доступные пары разделителей: (), <>, {}, и []; непарный разделитель, не являющийся идентификатором, является собственным закрывающим разделителем. Парные разделители вложены друг в друга, так что q"(A pair "()" of parens in quotes)"является допустимым литералом; пример с невложенностью / персонаж q"/I asked, "Can you hear me?"/".
Подобно C++11, D позволяет использовать литералы в стиле «здесь-документ» с идентификаторами конца строки:

q" -of-string-id строки содержимое новой end "

В D идентификатор конца строки должен быть идентификатором (буквенно-цифровыми символами).

В некоторых языках программирования, таких как sh и Perl , существуют разные разделители, которые обрабатываются по-разному, например, выполняется ли интерполяция строк или нет, и поэтому необходимо соблюдать осторожность при выборе того, какой разделитель использовать; см. различные типы строк ниже.

Множественное цитирование [ править ]

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

Например, в Perl :

qq^Я сказал: «Ты меня слышишь?»^ 
 qq@Я сказал: «Ты меня слышишь?»@ 
 qq§Я сказал: «Ты меня слышишь?»§ 

все дают желаемый результат. Хотя эта нотация более гибкая, ее поддерживают немногие языки; Помимо Perl, Ruby (под влиянием Perl) и C++11 их также поддерживают . Вариантом множественных кавычек является использование строк в стиле документа .

Lua (начиная с версии 5.1) предоставляет ограниченную форму множественного цитирования, в частности, для возможности вложения длинных комментариев или встроенных строк. Обычно используется [[ и ]]для разделения литеральных строк (начальная новая строка удалена, в противном случае - необработанная), но открывающие скобки могут включать в себя любое количество знаков равенства, и только закрывающие скобки с таким же количеством знаков закрывают строку. Например:

local   ls   =   [=[ 
 Эту запись можно использовать для путей Windows: 
 local path = [[C:\Windows\Fonts]] 
 ]=] 

Множественные кавычки особенно полезны для регулярных выражений , которые содержат обычные разделители, такие как кавычки, поскольку это позволяет избежать необходимости их экранирования. Ранний пример — sed , где в команде подстановки s/regex/replacement/ косая черта по умолчанию / разделители могут быть заменены другими символами, как в s,regex,replacement, .

Функции конструктора [ править ]

Другой вариант, который редко используется в современных языках, — использовать функцию для создания строки, а не представлять ее через литерал. Обычно это не используется в современных языках, поскольку вычисления выполняются во время выполнения, а не во время анализа.

Например, ранние версии BASIC не включали escape-последовательности или какие-либо другие обходные пути, перечисленные здесь, и поэтому вместо этого приходилось использовать CHR$функция, которая возвращает строку, содержащую символ, соответствующий ее аргументу. В ASCII кавычка имеет значение 34, поэтому для представления строки с кавычками в системе ASCII следует написать

«Я сказал:»   +   CHR$  (  34  )   +   «Вы меня слышите?»    +   CHR$  (  34  ) 

В C аналогичная возможность доступна через sprintf и %c Спецификатор формата «символ», хотя при наличии других обходных путей он обычно не используется:

 символов  буфер  [  32  ]; 
  snprintf  (  buffer  ,   sizeof   buffer  ,   «Это %cin quotes.%c»  ,   34  ,   34  ); 

Эти функции-конструкторы также можно использовать для представления непечатаемых символов, хотя вместо них обычно используются escape-последовательности. Похожий метод можно использовать в C++ с помощью std::string оператор стрингификации.

Escape-последовательности [ править ]

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

Один символ выбирается в качестве префикса, чтобы дать кодировку для символов, которые трудно или невозможно включить напрямую. Чаще всего это обратная косая черта ; Помимо других символов, ключевым моментом является то, что сама обратная косая черта может быть закодирована как двойная обратная косая черта. \\ а для строк с разделителями сам разделитель может быть закодирован путем экранирования, скажем, с помощью \" for ". Регулярное выражение для таких экранированных строк можно задать следующим образом, как указано в спецификации ANSI C : [2] [а]

"(\\.|[^\\"])*" 

означает «кавычку; за которой следует ноль или более экранированных символов (обратная косая черта, за которой следует что-то, возможно, обратная косая черта или кавычка), или неэкранирующийся символ, не являющийся кавычкой; заканчивающийся кавычкой» – единственная проблема заключается в различении завершающая цитата из цитаты, которой предшествует обратная косая черта, которую можно экранировать. За обратной косой чертой могут следовать несколько символов, например: \uFFFF, в зависимости от схемы экранирования.

Затем экранированную строку необходимо лексически проанализировать , преобразуя экранированную строку в неэкранированную строку, которую она представляет. Это делается на этапе оценки общего лексирования компьютерного языка: оценщик лексера общего языка выполняет свой собственный лексер для экранированных строковых литералов.

Помимо прочего, должна быть возможность закодировать символ, который обычно завершает строковую константу, плюс должен быть какой-то способ указать сам escape-символ. Escape-последовательности не всегда красивы и просты в использовании, поэтому многие компиляторы предлагают и другие способы решения распространенных проблем. Однако escape-последовательности решают любую проблему с разделителями, и большинство компиляторов интерпретируют escape-последовательности. Когда escape-символ находится внутри строкового литерала, это означает «это начало escape-последовательности». Каждая escape-последовательность определяет один символ, который должен быть помещен непосредственно в строку. Фактическое количество символов, необходимых в escape-последовательности, варьируется. Escape-символ находится в верхней/левой части клавиатуры, но редактор его переведет, поэтому его невозможно записать в строку напрямую. Обратная косая черта используется для представления escape-символа в строковом литерале.

Многие языки поддерживают использование метасимволов внутри строковых литералов. Метасимволы интерпретируются по-разному в зависимости от контекста и языка, но обычно представляют собой своего рода «команду обработки» для представления печатаемых или непечатаемых символов.

Например, в строковом литерале C , если за обратной косой чертой следует такая буква, как «b», «n» или «t», то это представляет собой непечатаемый символ возврата , новой строки или символа табуляции соответственно. Или, если за обратной косой чертой следуют 1–3 восьмеричные цифры, то эта последовательность интерпретируется как представление произвольной кодовой единицы с указанным значением в кодировке литерала (например, соответствующий код ASCII для литерала ASCII). Позже это было расширено, чтобы обеспечить более современную запись шестнадцатеричного кода символов:

«Я сказал:  \t\t\x22  Ты меня слышишь?  \x22\n  » 
Escape-последовательность Юникод Литеральные символы, помещенные в строку
\0 U+0000 нулевой символ [3] [4]
(обычно как частный случай восьмеричной записи \oooo)
U + 0007 тревога [5] [6]
U + 0008 возврат назад [5]
\ е U+000C подача формы [5]
\п U + 000A перевод строки [5] (или новая строка в POSIX)
U + 000D возврат каретки [5] (или новая строка в Mac OS 9 и более ранних версиях)
\ т U + 0009 горизонтальная вкладка [5]
\v U + 000B вертикальная вкладка [5]
\Это U + 001B escape-символ [6] ( ССЗ , [7] лязг и тсс )
\в#### U+#### 16-битный символ Юникода , где #### — четыре шестнадцатеричные цифры. [4]
\В######## У+###### 32-битный символ Юникода, где ######## — это восемь шестнадцатеричных цифр (ширина символьного пространства Юникода в настоящее время составляет всего 21 бит, поэтому первые две шестнадцатеричные цифры всегда будут равны нулю)
\в{######} У+###### 21-битный символ Юникода, где ###### — переменное количество шестнадцатеричных цифр.
\Икс## Зависит от кодировки [б] Спецификация 8-битного символа, где # — шестнадцатеричная цифра. Длина шестнадцатеричной escape-последовательности не ограничивается двумя цифрами, а имеет произвольную длину. [5]
\ооо Зависит от кодировки [б] Спецификация 8-битного символа, где o — восьмеричная цифра. [5]
\" U + 0022 двойная кавычка ("") [5]
\& несимвол, используемый для разделения числовых escape-символов в Haskell [3]
\' U + 0027 одинарная кавычка (') [5]
\\ U + 005C обратная косая черта (\) [5]
\? U + 003F вопросительный знак (?) [5]

Примечание. Не все последовательности в списке поддерживаются всеми анализаторами, и могут существовать другие escape-последовательности, которых нет в списке.

Вложенное экранирование [ править ]

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

Неправильное заключение вложенных строк в кавычки может представлять собой уязвимость безопасности. При использовании ненадежных данных, например в полях данных SQL-запроса, следует использовать подготовленные операторы , чтобы предотвратить атаку путем внедрения кода . В версиях PHP со 2 по 5.3 существовала функция, называемая магическими кавычками , которая автоматически экранировала строки (для удобства и безопасности), но из-за проблем была удалена, начиная с версии 5.4.

Необработанные строки [ править ]

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

Необработанные строки особенно полезны, когда необходимо экранировать общий символ, особенно в регулярных выражениях (вложенных в строковые литералы), где обратная косая черта \широко используется, а также в путях DOS/Windows , где в качестве разделителя пути используется обратная косая черта. Обилие обратных косых черт известно как синдром наклоненной зубочистки , и его можно уменьшить, используя необработанные строки. Сравните экранированные и необработанные пути в C#:

 "Путь Windows: C:\\Foo\\Bar\\Baz\\" 
  @"Путь Windows: C:\Foo\Bar\Baz\" 

Крайние примеры возникают, когда они объединены: пути по единому соглашению об именах начинаются с \\, и, таким образом, экранированное регулярное выражение, соответствующее UNC-имени, начинается с 8 обратных косых черт, "\\\\\\\\", из-за необходимости экранирования строки и регулярного выражения. Использование необработанных строк уменьшает это число до 4 (экранирование в регулярном выражении), как в C#. @"\\\\".

В документах XML разделы CDATA позволяют использовать такие символы, как & и <, без того, чтобы синтаксический анализатор XML пытался интерпретировать их как часть структуры самого документа. документа Это может быть полезно при включении обычного текста и кода сценариев, чтобы сохранить правильность формата .

<![CDATA[ if (path!=null && deep<2) { add(path);  } ]]> 

Многострочные строковые литералы [ править ]

Во многих языках строковые литералы могут содержать буквальные символы новой строки, занимающие несколько строк. В качестве альтернативы, символы новой строки можно экранировать, чаще всего так: \n. Например:

эхо   'фу 
 бар' 

и

echo   -e   "foo\nbar" 

оба действительны bash, производя:

фу
 бар
 

Языки, допускающие буквальный перевод строки, включают bash, Lua, Perl, PHP, R и Tcl. В некоторых других языках строковые литералы не могут включать символы новой строки.

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

Наиболее распространенным решением этих проблем являются документа строковые литералы в стиле . Формально говоря, здесь документ — это не строковый литерал, а потоковый или файловый литерал. Они возникают в сценариях оболочки и позволяют использовать литерал в качестве входных данных для внешней команды. Открывающий разделитель <<END где END может быть любым словом, а закрывающим разделителем является END на отдельной строке, служащей границей контента – <<связано с перенаправлением стандартного ввода из литерала. Поскольку разделитель является произвольным, это также позволяет избежать проблемы столкновения разделителей. Они также позволяют удалять начальные вкладки с помощью вариантного синтаксиса. <<-ENDхотя ведущие пробелы не удаляются. Тот же синтаксис с тех пор был принят для многострочных строковых литералов во многих языках, особенно в Perl, и здесь они также называются документами и сохраняют синтаксис, несмотря на то, что они являются строками и не требуют перенаправления. Как и в случае с другими строковыми литералами, для них иногда может быть указано другое поведение, например интерполяция переменных.

Python, чьи обычные строковые литералы не допускают буквальных символов новой строки, вместо этого имеет специальную форму строк, предназначенную для многострочных литералов, называемую тройными кавычками . Они используют тройной разделитель либо ''' или """. Эти литералы особенно используются для встроенной документации, известной как строки документации .

Tcl допускает буквальные символы новой строки в строках и не имеет специального синтаксиса для работы с многострочными строками, хотя разделители могут размещаться в строках сами по себе, а начальные и конечные символы новой строки удаляются с помощью string trim, пока string map можно использовать для удаления вмятин.

Конкатенация строковых букв [ править ]

Некоторые языки обеспечивают конкатенацию строковых литералов , при которой соседние строковые литералы неявно объединяются в один литерал во время компиляции. Это особенность C, [8] [9] С++, [10] Д, [11] Рубин, [12] и Питон, [13] который скопировал его из C. [14] Примечательно, что эта конкатенация происходит во время компиляции, во время лексического анализа (как этап после первоначальной токенизации) и контрастирует как с конкатенацией строк во время выполнения (обычно с + оператор) [15] и конкатенация во время свертывания констант , которая происходит во время компиляции, но на более позднем этапе (после анализа фраз или «синтаксического анализа»). Большинство языков, таких как C#, Java [16] и Perl не поддерживают неявную конкатенацию строковых литералов, а вместо этого требуют явной конкатенации, например, с помощью +оператор (это также возможно в D и Python, но запрещено в C/C++ – см. ниже); в этом случае конкатенация может происходить во время компиляции посредством свертывания констант или может быть отложена до времени выполнения.

Мотивация [ править ]

В языке C, откуда возникли это понятие и термин, конкатенация строковых литералов была введена по двум причинам: [17]

  • Чтобы длинные строки могли занимать несколько строк с правильными отступами в отличие от продолжения строки, которое разрушает схему отступов; и
  • Разрешить создание строковых литералов с помощью макросов (посредством создания строк ). [18]

На практике это позволяет осуществлять конкатенацию строк на ранних этапах компиляции («перевод», в частности, как часть лексического анализа), без необходимости анализа фраз или постоянного свертывания. Например, следующие допустимы для C/C++:

char   *  s   =   "привет,"   "мир"  ; 
  printf  (  "привет,"   "мир"  ); 

Однако следующее недействительно:

char   *  s   =   "привет,"   +   "мир"  ; 
  printf  (  "привет,"   +   "мир"  ); 

Это связано с тем, что строковые литералы имеют тип массива , char [n] (С) или const char [n](C++), который нельзя добавить; в большинстве других языков это не ограничение.

Это особенно важно при использовании в сочетании с препроцессором C , чтобы обеспечить возможность вычисления строк после предварительной обработки, особенно в макросах. [14] В качестве простого примера:

char   *  file_and_message   =   __FILE__   ": сообщение"  ; 

будет (если файл называется ac) расширится до:

char   *  file_and_message   =   "ac"   ": сообщение"  ; 

который затем объединяется, что эквивалентно:

char   *  file_and_message   =   "ac: сообщение"  ; 

Распространенным вариантом использования является создание строк формата printf или scanf , где спецификаторы формата задаются макросами. [19] [20]

В более сложном примере используется преобразование целых чисел в строку (препроцессором) для определения макроса, который расширяется до последовательности строковых литералов, которые затем объединяются в один строковый литерал с именем файла и номером строки: [21]

#define STRINGIFY(x) #x 
 #define TOSTRING(x) STRINGIFY(x) 
 #define AT __FILE__ ":" TOSTRING(__LINE__) 

Помимо синтаксических требований C/C++, неявная конкатенация представляет собой форму синтаксического сахара , упрощающую разделение строковых литералов на несколько строк, избегая необходимости продолжения строки (через обратную косую черту) и позволяя добавлять комментарии к частям строк. Например, в Python регулярное выражение можно прокомментировать следующим образом: [22]

ре  .   компилировать  (  "[A-Za-z_]"         # буква или подчеркивание 
            "[A-Za-z0-9_]*"     # буква, цифра или подчеркивание 
           ) 

Проблемы [ править ]

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

l   =   [  'foo'  , 
      'бар' 
      'зорк'  ] 

Соответственно, он не используется в большинстве языков, и его было предложено исключить из D. [23] и Питон. [14] Однако удаление этой функции нарушает обратную совместимость, а замена ее оператором конкатенации приводит к проблемам приоритета: конкатенация строковых литералов происходит во время лексического анализа, до вычисления оператора, но конкатенация с помощью явного оператора происходит одновременно с другими операторами, отсюда и приоритет. Это проблема, потенциально требующая скобок для обеспечения желаемого порядка вычислений.

Более тонкая проблема заключается в том, что в C и C++ [24] существуют разные типы строковых литералов, и их объединение имеет поведение, определяемое реализацией, что представляет потенциальную угрозу безопасности. [25]

Различные виды строк [ править ]

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

Один из самых старых примеров — сценарии оболочки, где одинарные кавычки обозначают необработанную строку или «литеральную строку», а двойные кавычки содержат escape-последовательности и интерполяцию переменных.

Например, в Python необработанным строкам предшествует символ r или R - сравнивать 'C:\\Windows' с r'C:\Windows'(однако необработанная строка Python не может заканчиваться нечетным количеством обратных косых черт). Python 2 также различает два типа строк: 8-битные строки ASCII («байты») (по умолчанию), явно обозначаемые b или B префикс и строки Юникода, обозначенные значком u или U префикс. [26] в то время как в Python 3 строки по умолчанию имеют Unicode, а байты представляют собой отдельный bytes тип, который при инициализации с кавычками должен иметь префикс b.

Нотация C# для необработанных строк называется @-кавычками.

@"C:\Foo\Bar\Baz\" 

Хотя это отключает экранирование, оно позволяет удвоить кавычки, что позволяет представлять кавычки внутри строки:

@"Я сказал: "Привет.""" 

C++11 допускает необработанные строки, строки Юникода (UTF-8, UTF-16 и UTF-32) и строки широких символов, определяемые префиксами. Он также добавляет литералы для существующего C++. string, который обычно предпочтительнее существующих строк в стиле C.

В Tcl строки, разделенные скобками, являются буквальными, а строки, разделенные кавычками, имеют экранирование и интерполяцию.

В Perl имеется большое разнообразие строк, которые более формально считаются операторами и известны как кавычки и операторы, подобные кавычкам . К ним относятся как обычный синтаксис (фиксированные разделители), так и общий синтаксис, позволяющий выбирать разделители; к ним относятся: [27]

''    ""    ``    //    m//    qr//    s///    y  //  / 
 q{}    qq{}    qx{}    qw{}    m{}    qr{}    s{}{}    tr  {}{}    да  {}{} 

REXX использует символы-суффиксы для указания символов или строк, используя их шестнадцатеричный или двоичный код. Например,

'20'  х 
  "0010 0000"  б 
  "00100000"  б 
 

все дают пробел , избегая вызова функции X2C(20).

Строковая интерполяция [ править ]

В некоторых языках строковые литералы могут содержать заполнители, ссылающиеся на переменные или выражения в текущем контексте , которые оцениваются (обычно во время выполнения). Это называется интерполяцией переменных или, в более общем смысле, интерполяцией строк . Языки, поддерживающие интерполяцию, обычно различают строковые литералы, которые интерполируются, от неинтерполируемых. Например, в sh-совместимых оболочках Unix (а также в Perl и Ruby) строки в двойных кавычках (разделенных кавычками ") интерполируются, а строки в одинарных кавычках (разделенных апострофом ") - нет. Строковые литералы иногда называют «необработанными строками», но это отличается от «необработанной строки» в смысле экранирования. Например, в Python это строка с префиксом. r или R не имеет экранирования или интерполяции, обычная строка (без префикса) имеет экранирование, но не имеет интерполяции, а строка с префиксом f или F имеет экранирование и интерполяцию.

Например, следующий код Perl :

$name       =   "Нэнси"  ; 
  $greeting   =   "Привет, мир"  ; 
  print   "$name сказал $приветствие толпе людей."   ; 

производит вывод:

Нэнси сказала «Привет, мир» толпе людей.
 

В этом случае метасимвол ($) (не путать с символом в операторе присваивания переменной) интерпретируется как указание на интерполяцию переменной и требует некоторого экранирования, если его нужно вывести буквально.

Этому следует противопоставить printf функция, которая выдает тот же результат, используя такие обозначения, как:

printf   "%s сказал %s толпе людей."   ,   $имя  ,   $приветствие  ; 

но не выполняет интерполяцию: %s является заполнителем в строке формата printf , но сами переменные находятся за пределами строки.

Это контрастирует с «необработанными» строками:

print   '$name сказал $приветствие толпе людей.'   ; 

которые производят вывод, например:

$name сказал $приветствие толпе людей.
 

Здесь символы $ не являются метасимволами и не интерпретируются как имеющие какое-либо значение, кроме обычного текста.

Встраивание исходного кода в строковые литералы [ править ]

Языки, которым не хватает гибкости в указании строковых литералов, делают особенно громоздким написание программного кода, генерирующего другой программный код. Это особенно верно, когда язык генерации такой же или похож на язык вывода.

Например:

Тем не менее, некоторые языки особенно хорошо адаптированы для создания такого рода самоподобного вывода, особенно те, которые поддерживают несколько вариантов предотвращения столкновения разделителей.

Использование строковых литералов в качестве кода, генерирующего другой код, может иметь неблагоприятные последствия для безопасности, особенно если выходные данные хотя бы частично основаны на ненадежном пользовательском вводе. Это особенно актуально в случае веб-приложений, где злонамеренные пользователи могут воспользоваться такими слабостями, чтобы подорвать работу приложения, например, путем проведения атаки с помощью SQL-инъекции .

См. также [ править ]

Примечания [ править ]

  1. ^ Приведенное здесь регулярное выражение само по себе не заключено в кавычки и не экранировано, чтобы избежать путаницы.
  2. ^ Перейти обратно: а б Поскольку эта escape-последовательность представляет собой определенную кодовую единицу , а не определенный символ, то, какую кодовую точку (если таковая имеется) она представляет, зависит от кодировки строкового литерала, в котором она находится.

Ссылки [ править ]

  1. ^ «Введение в Java — MFC 158 G» . Строковые литералы (или константы) называются «анонимными строками».
  2. ^ «Грамматика ANSI C (Lex)» . Лю.се. ​ Проверено 22 июня 2016 г.
  3. ^ Перейти обратно: а б «Приложение Б. Символы, строки и правила экранирования» . Realworldhaskell.org . Проверено 22 июня 2016 г.
  4. ^ Перейти обратно: а б "Нить" . сайт mozilla.org . Проверено 22 июня 2016 г.
  5. ^ Перейти обратно: а б с д Это ж г час я дж к л м «Escape-последовательности (C)» . microsoft.com . Проверено 22 июня 2016 г.
  6. ^ Перейти обратно: а б «Обоснование международного стандарта — языки программирования — C» (PDF) . 5.10. Апрель 2003 г., стр. 52, 153–154, 159. Архивировано (PDF) из оригинала 6 июня 2016 г. Проверено 17 октября 2010 г.
  7. ^ «6.35 Символ <ESC> в константах» , Руководство GCC 4.8.2 , получено 8 марта 2014 г.
  8. ^ C11 Проект стандарта , Проект комитета WG14 N1570 — 12 апреля 2011 г. , 5.1.1.2 Этапы перевода, стр. 11: «6. Токены соседних строковых литералов объединяются».
  9. ^ Синтаксис C: конкатенация строковых литералов
  10. ^ C++11 , Проект стандарта «Рабочий проект стандарта языка программирования C++» (PDF) . , 2.2 Фазы трансляции [lex.phases], с. 17: «6. Токены соседних строковых литералов объединяются». и 2.14.5 Строковые литералы [lex.string], примечание 13, стр. 28–29: «На этапе трансляции 6 (2.2) соседние строковые литералы объединяются».
  11. ^ D Язык программирования , Лексический анализ , «Строковые литералы»: «Соседние строки объединяются с помощью оператора ~ или путем простого сопоставления:»
  12. ^ Ruby: Язык программирования Ruby , Язык программирования Ruby, 19 октября 2017 г. , получено 19 октября 2017 г.
  13. ^ Справочник по языку Python, 2. Лексический анализ, 2.4.2. Конкатенация строковых литералов : «Допускаются несколько соседних строковых литералов (разделенных пробелами), возможно, с использованием разных соглашений о кавычках, и их значение такое же, как и их конкатенация».
  14. ^ Перейти обратно: а б с Идеи Python, « Неявная конкатенация строковых литералов считается вредной? », Гвидо ван Россум, 10 мая 2013 г.
  15. ^ Справочник по языку Python, 2. Лексический анализ, 2.4.2. Конкатенация строковых литералов : «Обратите внимание, что эта функция определена на синтаксическом уровне, но реализована во время компиляции. Оператор «+» должен использоваться для объединения строковых выражений во время выполнения».
  16. ^ «Строки (Учебные пособия по Java™ > Изучение языка Java > Числа и строки)» . Docs.oracle.com . 28 февраля 2012 г. Проверено 22 июня 2016 г.
  17. ^ Обоснование языка программирования ANSI C. Силиконовый пресс. 1990. с. 31 . ISBN  0-929306-07-4 . , 3.1.4 Строковые литералы : «Длинную строку можно продолжить на несколько строк, используя продолжение строки с обратной косой чертой и новой строкой, но эта практика требует, чтобы продолжение строки начиналось с первой позиции следующей строки. Для обеспечения большей гибкости компоновки и для решения некоторых проблем предварительной обработки (см. §3.8.3) Комитет ввел конкатенацию строковых литералов, которые соединяются подряд (без нулевого символа в середине), образуя один объединенный строковый литерал. Это дополнение. в язык C позволяет программисту расширить строковый литерал за пределы физической строки без необходимости использовать механизм обратной косой черты и новой строки и тем самым разрушать схему отступов программы. Явный оператор конкатенации не был введен, поскольку конкатенация представляет собой оператор. лексическая конструкция, а не операция времени выполнения».
  18. ^ Обоснование языка программирования ANSI C. Силиконовый пресс. 1990. с. 6566 . ISBN  0-929306-07-4 . , 3.8.3.2 Оператор # : «Оператор # был введен для создания строк. Его можно использовать только в расширении #define. Он приводит к замене следующего за ним формального имени параметра строковым литералом, образованным путем преобразования в строку фактического токена аргумента. Последовательность. В сочетании с конкатенацией строковых литералов (см. §3.1.4) использование этого оператора позволяет создавать строки так же эффективно, как и путем замены идентификатора внутри строки. Пример в Стандарте иллюстрирует эту возможность.
  19. ^ Журнал пользователей C/C++, том 19, стр. 50
  20. ^ «python — зачем разрешать объединение строковых литералов?» . Переполнение стека . Проверено 22 июня 2016 г.
  21. ^ «LINE__ в строку (stringify) с использованием директив препроцессора» . Decompile.com . 12 октября 2006 г. Проверено 22 июня 2016 г.
  22. ^ Справочник по языку Python, 2. Лексический анализ, 2.4.2. Конкатенация строковых литералов : «Эту функцию можно использовать для уменьшения количества необходимых обратных косых черт, для удобного разделения длинных строк на длинные строки или даже для добавления комментариев к частям строк, например:
  23. ^ Система отслеживания проблем DLang - Проблема 3827 - Предупредить и затем запретить неявное объединение соседних строковых литералов.
  24. ^ C++11 , Проект стандарта «Рабочий проект стандарта языка программирования C++» (PDF) . , 2.14.5 Строковые литералы [lex.string], примечание 13, с. 28–29: «Любые другие объединения условно поддерживаются поведением, определяемым реализацией».
  25. ^ «STR10-C. Не объединяйте строковые литералы разных типов — Безопасное кодирование — Стандарты безопасного кодирования CERT» . Архивировано из оригинала 14 июля 2014 года . Проверено 3 июля 2014 г.
  26. ^ «2. Лексический анализ — документация Python 2.7.12rc1» . python.org . Проверено 22 июня 2016 г.
  27. ^ «perlop — perldoc.perl.org» . perl.org . Проверено 22 июня 2016 г.

Внешние ссылки [ править ]

Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: 4A4A7443BDF65FE512AE7795AE12138A__1711952280
URL1:https://en.wikipedia.org/wiki/String_literal
Заголовок, (Title) документа по адресу, URL1:
String literal - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)