Что делает C! оператор делает?



я увидел строку C, которая выглядела так:



!ErrorHasOccured() ??!??! HandleError();


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



Я никогда не видел ??!??! раньше на любом языке программирования, и я не могу найти документацию для него нигде. (Погуглить не помогает с поисковыми терминами, как ??!??!). Что он делает и как работает Пример кода?

748   4  

4 ответов:

??! это trigraph что означает |. Поэтому он говорит:

!ErrorHasOccured() || HandleError();

что, из-за короткого замыкания, составляет:

if (ErrorHasOccured())
    HandleError();

гуру недели (имеет дело с C++ , но здесь уместно), где я взял это.

возможное происхождение триграфов или, как указывает @DwB в комментариях, это более вероятно из-за того, что EBCDIC сложно (снова). этой обсуждение на IBM совет developerworks, похоже, поддерживает эту теорию.

из ISO / IEC 9899: 1999 §5.2.1.1, сноска 12 (h / t @Random832):

последовательности триграфов позволяют вводить символы, которые не определены в наборе инвариантных кодов как описано в ИСО/МЭК 646, который представляет собой подмножество из семи-бит, установленный в коде ASCII.

Ну, почему это существует в целом, вероятно, отличается от того, почему он существует в вашем примере.

все это началось полвека назад с перепрофилирования печатных терминалов связи в качестве компьютерных пользовательских интерфейсов. В начальную эпоху Unix и C это был телетайп ASR-33.

Это устройство было медленным (10 cps) и шумным и уродливым, а его вид набора символов ASCII заканчивался на 0x5f, поэтому у него не было (посмотрите внимательно на рис) ни одного из ключи:

{ | } ~ 

в триграфов были определены для устранения конкретной проблемы. Идея заключалась в том, что программы C могли использовать подмножество ASCII, найденное на ASR-33, и в других средах, в которых отсутствуют высокие значения ASCII.

ваш пример на самом деле два ??!, что |, Так что в результате ||.

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

это точно сработало, это привело к дико популярному вопросу SO.

ASR-33 Teletype

телетайп ASR-33


1. Если уж на то пошло, триграфы были изобретены комитетом ANSI, который впервые встретился после C стать a безудержный успех, поэтому ни один из исходных кодов C или кодеров не использовал бы их.

Это C trigraph. ??! и |, Так что ??!??! оператор ||

как уже сказано ??!??! - это, по существу, два триграфов (??! и ??! снова) смешали, что вам заменили-переведен ||, то есть логическое или, препроцессором.

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

enter image description here (Изображение взято из 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 не предоставил ряд символов, необходимых для языков, отличных от английского,был сделан ряд национальных вариантов, которые заменили некоторые менее используемые символы необходимыми одни.

(выделено мной)

Comments

    Ничего не найдено.