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, cppaby samemu zobaczyć wynik, używając głupiego trigr.cprogramu:
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ć, -trigraphsnależy określić opcję, w przeciwnym razie cpppojawi 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?