Як вже говорилося ??!??!, по суті , два тріграфи ( ??!і ??!знову) mushed разом , які замінюються переведений на ||, тобто логічне АБО , препроцесором.
Наступна таблиця, що містить кожен триграф, повинна допомогти розмежувати альтернативні комбінації триграфа:
Trigraph Replaces
??( [
??) ]
??< {
??> }
??/ \
??' ^
??= #
??! |
??- ~
Джерело: C: Довідковий посібник 5-е видання
Отже, триграф, схожий ??(??), з часом відобразиться [], ??(??)??(??)заміниться [][]і так далі, ви отримаєте ідею.
Оскільки триграфи підміняються під час попередньої обробки, ви можете використати, cppщоб самостійно переглянути результат, використовуючи нерозумну trigr.cпрограму:
void main(){ const char *s = "??!??!"; }
і обробляти його за допомогою:
cpp -trigraphs trigr.c
Ви отримаєте консольний вихід
void main(){ const char *s = "||"; }
Як ви можете помітити, опцію -trigraphsпотрібно вказати, інакше cppвинесете попередження; це вказує на те, як триграфи - це минуле і не має жодної сучасної цінності, окрім заплутування людей, які можуть наткнутися на них .
Що стосується обґрунтування введення триграфа, то його краще зрозуміти, переглядаючи розділ історії ISO / IEC 646 :
ISO / IEC 646 та його попередник ASCII (ANSI X3.4) значною мірою схвалили існуючу практику щодо кодування символів у телекомунікаційній галузі.
Оскільки ASCII не надав кількість символів, необхідних для інших мов, крім англійської, було створено ряд національних варіантів, які замінювали деякі менш вживані символи потрібними .
(наголос мій)
Отже, по суті, деякі необхідні персонажі (ті, для яких існує триграф) були замінені в певних національних варіантах. Це призводить до поперемінного подання за допомогою триграфа, що складається з символів, які інші варіанти все ще мали навколо.
!ErrorHasOccurred() ??!???! HandleError();компілювати? Ось так??!???!. Доводить суть?