Обычно #define
принимает только действительные идентификаторы в имени макроса, поэтому вы не можете:
#define @ at
#define @(x) [x]
Аналогично с обратной цитатой. И вы не упомянули '$', который иногда допускается в идентификаторах.
Может быть расширение для компилятора, разрешающее такие сопоставления, но я бы не стал его использовать.
Что касается исторической причины этого, то существуют части набора символов ISO 646, которые зарезервированы для национальных реализаций национальных символов. Эти зарезервированные части включают символы, вызывающие проблемы, а функции триграфов и орграфов в стандарте C (и, следовательно, в стандарте C++) были добавлены в ISO C в 1989 и 1994 годах соответственно, чтобы обеспечить обходные пути для проблем.
Триграфы
Триграфы были добавлены в процессе стандартизации C89, чтобы людям, например, не приходилось видеть алфавитные символы (в скандинавских языках), используемые в их коде C (адаптировано из примера в B Stroustrup, «Design and Evolution of C++», с использованием Датский терминал):
#include <stdio.h>
int main(int argc, char **argvÆÅ)
æ
if (argc < 1 øø *argvÆ1Å == 'Ø0') return 0;
printf("Hello, %sØn", argvÆ1Å);
å
Или в кодовом наборе ISO 8859-1 (или любом из кодовых наборов ISO 8859-x):
#include <stdio.h>
int main(int argc, char **argv[])
{
if (argc < 1 || argv[1] == '\0') return 0;
printf("Hello, %s\n", argv[1]);
}
Триграфы были введены для создания нейтрального формата кода:
??=include <stdio.h>
int main(int argc, char **argv??(??))
??<
if (argc < 1 ??!??! *argv??(1??) == '??/0') return 0;
printf("Hello, %s??/n", argv??(1??));
??>
Это тоже не очень читаемо, но одинаково для всех.
Trigraph Equivalent to
??/ \ backslash
??< { open brace
??> } close brace
??( [ open square bracket
??) ] close square bracket
??= # hash (pound in American, but a pound is £ in English)
??' ^ caret
??! | pipe
??- ~ tilde
В стандарте сказано, что «других триграфов нет». Вот почему управляющая последовательность '\?' распознается (как простой знак вопроса - хотя предположительно это '??/?'). Обратите внимание, что коллекция компиляторов GNU (GCC) не интерпретирует триграфы, если вы не держите руку на пульсе (укажите '-trigraphs
' в командной строке).
Диграфы
Орграфы были добавлены в 1994 году и не так распространены или навязчивы, как триграфы; они появляются только вне строк и строковых литералов. Орграфы:
Digraph Equivalent to
<: [
:> ]
<% {
%> }
%: #
%:%: ##
Пример с использованием орграфов (и триграфов):
%:include <stdio.h>
%:include <iso646.h>
int main(int argc, char **argv<::>)
<%
if (argc < 1 or *argv<:1:> == '??/0') return 0;
printf("Hello, %s??/n", argv<:1:>);
%>
На знаке и обратной кавычке конкретно?
Если вы посмотрите на приведенный выше URL-адрес Википедии, вы увидите, что и «@», и «`» иногда заменяются национальными символами — и, следовательно, не являются хорошими идентификаторами. Дополнительная причина не использовать «@» заключается в том, что во время введения C «#» был символом стирания по умолчанию, а «@» был символом уничтожения (стирания строки) для терминалов. Таким образом, вы должны были помнить, чтобы избежать их , Так как '#' появлялся только в начале строки, это не было большой проблемой (использование '#' и '##' появилось намного позже - снова стандартизация), но '@' стер бы весь предыдущий ввод в строку. И это за несколько дней до «vi» — «ed — стандартный редактор Unix».
person
Jonathan Leffler
schedule
06.03.2010
@
широко используется в Objective-C (надмножество C). - person kennytm   schedule 06.03.2010