Как уже говорилось, ??!??!
- это, по сути, два триграфа (* ??!
и ??!
снова), собранные вместе и замененные на ||
, то есть логическое ИЛИ , препроцессором.
Следующая таблица, содержащая каждый триграф, должна помочь устранить неоднозначность альтернативных комбинаций триграфов:
Trigraph Replaces
??( [
??) ]
??< {
??> }
??/ \
??' ^
??= #
??! |
??- ~
Источник: C: Справочное руководство, 5-е издание
Таким образом, триграф, который выглядит как ??(??)
, в конечном итоге отобразится на []
, ??(??)??(??)
будет заменен на [][]
и так далее, вы получите идею.
Поскольку триграфы заменяются во время предварительной обработки, вы можете использовать cpp
, чтобы самостоятельно просмотреть вывод, используя глупую программу trigr.c
:
void main(){ const char *s = "??!??!"; }
и обрабатывая еес:
cpp -trigraphs trigr.c
Вы получите консольный вывод
void main(){ const char *s = "||"; }
Как вы можете заметить, должна быть указана опция -trigraphs
, иначе cpp
выдаст предупреждение;это указывает на то, что триграфы остались в прошлом и не представляют никакой современной ценности, кроме как сбивать с толку людей, которые могут натолкнуться на них .
Что касается обоснования введения триграфов,это лучше понять при рассмотрении исторического раздела ИСО / МЭК 646 :
ИСО / МЭК 646 и его предшественника ASCII (ANSI X3.4) в значительной степени одобрили существующую практику в отношениикодировки символов в телекоммуникационной отрасли.
Поскольку в ASCII не предусмотрено количество символов, необходимых для языков, отличных от английского, был создан ряд национальных вариантов, в которых некоторые менее используемые символы заменены нанеобходимые .
(выделено мной)
Итак, по сути, некоторые необходимые символы (те, для которых существует триграф)были заменены в определенных национальных вариантах.Это приводит к альтернативному представлению с использованием триграфов, состоящих из символов, которые все еще были в других вариантах.