Jak już wspomniano, ??!??!
są to zasadniczo dwa trygrafy ( ??!
i ??!
ponownie) wymieszane razem, które są zastępowane-tłumaczone ||
, tj. Logiczne OR , przez preprocesora.
Poniższa tabela zawierająca wszystkie trygrafy powinna pomóc w jednoznacznym odróżnieniu alternatywnych kombinacji trygrafów:
Trigraph Replaces
??( [
??) ]
??< {
??> }
??/ \
??' ^
??= #
??! |
??- ~
Źródło: C: A Reference Manual wydanie 5
Tak więc trójwymiarowy wygląd, który wygląda tak ??(??)
, ostatecznie zostanie zamapowany []
, ??(??)??(??)
zostanie zastąpiony przez [][]
i tak dalej, masz pomysł.
Ponieważ podczas wstępnego przetwarzania trigry są zastępowane, możesz użyć tego, cpp
aby samemu zobaczyć wynik, używając głupiego trigr.c
programu:
void main(){ const char *s = "??!??!"; }
i przetwarzając go za pomocą:
cpp -trigraphs trigr.c
Otrzymasz wyjście konsoli
void main(){ const char *s = "||"; }
Jak można zauważyć, -trigraphs
należy określić opcję, w przeciwnym razie cpp
pojawi się ostrzeżenie; wskazuje to na to, że trygrafy należą do przeszłości i nie mają żadnej nowoczesnej wartości poza mylącymi ludźmi, którzy mogą się na nie natknąć .
Jeśli chodzi o uzasadnienie wprowadzenia kaligrafii, lepiej to zrozumieć, patrząc na sekcję historii ISO / IEC 646 :
ISO / IEC 646 i jego poprzednik ASCII (ANSI X3.4) w dużej mierze poparły istniejącą praktykę dotyczącą kodowania znaków w branży telekomunikacyjnej.
Ponieważ ASCII nie podał liczby znaków potrzebnych w językach innych niż angielski, opracowano wiele wariantów krajowych, które zastąpiły niektóre rzadziej używane znaki potrzebnymi .
(moje podkreślenie)
Zasadniczo niektóre potrzebne postacie (te, dla których istnieje trigraf) zostały zastąpione w niektórych wariantach krajowych. Prowadzi to do alternatywnej reprezentacji za pomocą trójwymiarowych znaków składających się z postaci, które inne warianty nadal miały w pobliżu.
!ErrorHasOccurred() ??!???! HandleError();
się skompilować? To??!
???
!
. Udowadnia sens?