Escape-последовательности используются в языках программирования C и C ++ , и их дизайн был скопирован во многих других языках, таких как Java , PHP , C # и т. Д. Escape-последовательность - это последовательность символов, которая не представляет себя при использовании внутри символа или строковый литерал , но переводится в другой символ или последовательность символов, которые может быть трудно или невозможно представить напрямую.
В C все escape-последовательности состоят из двух или более символов, первый из которых - обратная косая черта, \ (называемый « escape-символом »); остальные символы определяют интерпретацию escape-последовательности. Например, \ n - это escape-последовательность, обозначающая символ новой строки .
Мотивация
Предположим, мы хотим распечатать Привет, в одной строке, за которой следует Мир! на следующей строке. Можно попытаться представить строку, которая будет напечатана, как один литерал следующим образом:
#include int main () { printf ( "Привет, мир ! "); }
Это недопустимо в C, поскольку строковый литерал не может охватывать несколько логических исходных строк. Это можно обойти, напечатав символ новой строки, используя его числовое значение ( 0x0A в ASCII ),
#include int main () { printf ( "Привет,% cworld!" , 0x0A ); }
Это дает указание программе печатать Здравствуйте, за которым следует байт, числовое значение которого 0x0A , за которым следует Мир! . Хотя это действительно будет работать, когда машина использует кодировку ASCII, она не будет работать в системах, которые используют другие кодировки, которые имеют другое числовое значение для символа новой строки. Это также не очень хорошее решение, потому что оно по-прежнему не позволяет представлять символ новой строки внутри литерала, а вместо этого использует семантику printf . Чтобы решить эти проблемы и обеспечить максимальную переносимость между системами, C интерпретирует \ n внутри литерала как символ новой строки, независимо от того, что это может быть в целевой системе:
#include int main () { printf ( "Привет, \ n мир!" ); }
В этом коде escape-последовательность\ n не означает обратную косую черту, за которой следует буква n , потому что обратная косая черта вызывает «выход» из обычного способа интерпретации символов компилятором. Увидев обратную косую черту, компилятор ожидает, что другой символ завершит escape-последовательность, а затем переводит escape-последовательность в байты, которые он предназначен для представления. Таким образом, "Привет, \ nworld!" представляет строку со встроенной новой строкой, независимо от того, используется ли она внутри printf или где-нибудь еще.
Это поднимает вопрос о том, как представить фактическую обратную косую черту внутри литерала. Это делается с помощью escape-последовательности \\ , как показано в следующем разделе.
Некоторые языки не имеют escape-последовательностей, например, Паскаль . Вместо этого будет использоваться команда, включающая новую строку (Writeln включает новую строку, write исключает ее).
Writeln ( 'Привет' ) ; написать ( 'мир!' ) ;
Таблица escape-последовательностей
Следующие escape-последовательности определены в стандарте C. В этой таблице также показаны значения, которым они сопоставляются в ASCII. Однако эти escape-последовательности могут использоваться в любой системе с компилятором C и могут отображаться на другие значения, если система не использует кодировку символов на основе ASCII.
Последовательность выхода | Шестнадцатеричное значение в ASCII | Представленный персонаж |
---|---|---|
\ а | 07 | Оповещение (Beep, Bell) (добавлено в C89) [1] |
\ b | 08 | Backspace |
\ e примечание 1 | 1B | Эскейп-персонаж |
\ f | 0C | Перенос страницы разрыв страницы |
\ п | 0A | Новая строка ( перевод строки); см. примечания ниже |
\р | 0D | Возврат каретки |
\ т | 09 | Горизонтальная вкладка |
\ v | 0B | Вертикальная табуляция |
\\ | 5C | Обратная косая черта |
\ ' | 27 | Апостроф или одинарная кавычка |
\ " | 22 | Двойные кавычки |
\? | 3F | Вопросительный знак (используется, чтобы избежать триграфов ) |
\ nnn примечание 2 | любой | Байт, числовое значение которого задается параметром nnn, интерпретируемым как восьмеричное число. |
\ x чч… | любой | Байт, числовое значение которого дается hh… интерпретируется как шестнадцатеричное число. |
\ uhhhh примечание 3 | никто | Кодовая точка Unicode ниже 10000 в шестнадцатеричном формате |
\ U хххххххх примечание 4 | никто | Кодовая точка Unicode, где h - шестнадцатеричная цифра |
- Примечание 1. ^ Общий нестандартный код; см. раздел «Примечания» ниже.
- Примечание 2. ^ Может присутствовать одна, две или три восьмеричных цифры n ; см. раздел «Примечания» ниже.
- Примечание 3. ^ \ u принимает 4 шестнадцатеричных цифры h ; см. раздел «Примечания» ниже.
- Примечание 4. ^ \ U принимает 8 шестнадцатеричных цифр h ; см. раздел «Примечания» ниже.
Заметки
\ n производит один байт, несмотря на тот факт, что платформа может использовать более одного байта для обозначения новой строки, например, последовательность CR-LF DOS / Windows , 0x0D 0x0A . Перевод из От 0x0A до 0x0D 0x0A в DOS и Windows возникает, когда байт записывается в файл или на консоль, а обратное преобразование выполняется при чтении текстовых файлов.
Шестнадцатеричная escape-последовательность должна содержать хотя бы одну шестнадцатеричную цифру после \ x , без верхней границы; он продолжается для всех имеющихся шестнадцатеричных цифр. Так, например, \ xABCDEFG обозначает байт с числовым значением ABCDEF 16 , за которым следует буква G , не являющаяся шестнадцатеричной цифрой. Однако, если результирующее целочисленное значение слишком велико, чтобы поместиться в один байт, фактическое присвоенное числовое значение определяется реализацией. Большинство платформ имеют 8-битные char , что ограничивает полезную шестнадцатеричную escape-последовательность двумя шестнадцатеричными цифрами. Однако шестнадцатеричные escape-последовательности длиной более двух шестнадцатеричных цифр могут быть полезны внутри широкого символа или широкого строкового литерала (с префиксом L):
char s1 [] = " \ x12 " ; // одиночный символ со значением 0x12 (18 в десятичном формате) char s1 [] = " \ x1234 " ; // одиночный символ со значением, определяемым реализацией, если char не достаточно длинный wchar_t s2 [] = L " \ x1234 " ; // одиночный wchar_t со значением 0x1234, при условии, что wchar_t достаточно длинный (достаточно 16 бит)
Восьмеричная escape-последовательность состоит из \, за которым следуют одна, две или три восьмеричные цифры. Восьмеричная escape-последовательность заканчивается, когда она либо уже содержит три восьмеричных цифры, либо следующий символ не является восьмеричной цифрой. Например, \ 11 - это одиночная восьмеричная escape-последовательность, обозначающая байт с числовым значением 9 (11 в восьмеричной системе), а не escape-последовательность \ 1, за которым следует цифра 1 . Тем не мение, \ 1111 - восьмеричная escape-последовательность \ 111, за которым следует цифра 1 . Для обозначения байта числовым значением 1, за которым следует цифра 1 , можно было бы использовать «\ 1» «1» , поскольку C автоматически объединяет смежные строковые литералы. Обратите внимание, что некоторые трехзначные восьмеричные escape-последовательности могут быть слишком большими, чтобы поместиться в один байт; в результате получается значение, определяемое реализацией для фактически созданного байта. Escape-последовательность \ 0 - это обычно используемая восьмеричная escape-последовательность, которая обозначает нулевой символ со значением ноль.
Нестандартные escape-последовательности
Последовательность, такая как \ z не является допустимой escape-последовательностью в соответствии со стандартом C, так как она не найдена в таблице выше. Стандарт C требует диагностики таких «недопустимых» escape-последовательностей (т. Е. Компилятор должен вывести сообщение об ошибке). Несмотря на это, некоторые компиляторы могут определять дополнительные escape-последовательности с семантикой, определяемой реализацией. Примером может служить \ e escape-последовательность, которая имеет 1B в качестве шестнадцатеричного значения в ASCII, представляет escape-символ и поддерживается в GCC , [2] clang и tcc . Однако он не был добавлен в стандартный репертуар C, поскольку не имеет значимого эквивалента в некоторых наборах символов (например, EBCDIC ). [1]
Универсальные имена персонажей
Из стандарта C99 C также поддерживает escape-последовательности, которые обозначают кодовые точки Unicode в строковых литералах. Такие escape-последовательности называются универсальными именами символов и имеют вид \ u hhhh или \ U hhhhhhhh , где h обозначает шестнадцатеричную цифру. В отличие от других рассматриваемых управляющих последовательностей, универсальное имя символа может расширяться до более чем одной кодовой единицы.
Последовательность \ u hhhh обозначает кодовую точкухххх , интерпретируется как шестнадцатеричное число. Последовательность \ U hhhhhhhh обозначает кодовую точку хххххххх , интерпретируется как шестнадцатеричное число. (Следовательно, кодовые точки, расположенные в U + 10000 или выше, должны быть обозначены \ U синтаксис, тогда как более низкие кодовые точки могут использовать \ u или \ U. ) Кодовая точка преобразуется в последовательность кодовых единиц при кодировании типа назначения в целевой системе. Например, рассмотрим
char s1 [] = " \ xC0 " ; char s2 [] = " \ u00C1 " ; wchar_t s3 [] = L " \ xC0 " ; wchar_t s4 [] = L " \ u00C0 " ;
Строка s1 будет содержать один байт (не считая завершающего нуля), числовое значение которого, фактическое значение, хранящееся в памяти, на самом деле 0xC0 . Строка s2 будет содержать символ «Á», U + 00C1 ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА A С ОСТРЫМ . В системе, использующей кодировку UTF-8 , строка s2 будет содержать два байта, 0xC3 0x81 . Строка s3 содержит один wchar_t , снова с числовым значением 0xC0 . Строка s4 содержит символ "À", закодированный в wchar_t , если используется кодировка UTF-16 , то s4 также будет содержать только один wchar_t , длина 16 бит, с числовым значением 0x00C0 . Универсальное имя персонажа, например \ U0001F603 может быть представлен одним wchar_t, если используется кодировка UTF-32 , или два, если используется UTF-16.
Важно отметить, что универсальное имя персонажа \ u00C0 всегда обозначает символ «À», независимо от того, в каком строковом литерале он используется, или от используемой кодировки. Очередной раз, \ U0001F603 всегда обозначает символ в кодовой точке 1F603 16 , независимо от контекста. С другой стороны, восьмеричные и шестнадцатеричные escape-последовательности всегда обозначают определенные последовательности числовых значений, независимо от кодировки. Следовательно, универсальные имена символов дополняют восьмеричные и шестнадцатеричные escape-последовательности; в то время как восьмеричные и шестнадцатеричные escape-последовательности представляют собой «физические» кодовые единицы, универсальные имена символов представляют собой кодовые точки , которые можно рассматривать как «логические» символы.
Смотрите также
- Последовательность выхода
- Диграф
Рекомендации
- ^ a b «Обоснование международного стандарта - языки программирования - C» (PDF) . 5.10. Апрель 2003. Архивировано (PDF) из оригинала 06.06.2016 . Проверено 17 октября 2010 .
- ^ «6.35 Символ в константах» . GCC 4.8.2 Руководство . Архивировано 12 мая 2019 года . Проверено 8 марта 2014 .
дальнейшее чтение
- ISO / IEC 9899: 1999, Языки программирования - C
- Керниган, Брайан В .; Ричи, Деннис М. (2003) [1988]. Язык программирования C (2-е изд.). Прентис Холл . ISBN 978-0-13308621-8.
- Лафор, Роберт (2001). Объектно-ориентированное программирование в Turbo C ++ (1-е изд.). Публикации Galgotia. ISBN 978-8-18562322-1.