Zgodnie z C ++ '03 Standard 2.3 / 1:
Przed jakimkolwiek innym przetwarzaniem każde wystąpienie jednej z następujących sekwencji trzech znaków („sekwencje trygrafów”) zastępuje się pojedynczym znakiem wskazanym w tabeli 1.
---------------------------------------------------------------------------- | trigraph | replacement | trigraph | replacement | trigraph | replacement | ---------------------------------------------------------------------------- | ??= | # | ??( | [ | ??< | { | | ??/ | \ | ??) | ] | ??> | } | | ??’ | ˆ | ??! | | | ??- | ˜ | ----------------------------------------------------------------------------
W prawdziwym życiu oznacza to, że kod printf( "What??!\n" );
będzie drukowany, What|
ponieważ ??!
jest to sekwencja trygrafu, która jest zastępowana |
znakiem.
Moje pytanie brzmi: jaki jest cel używania trójgrafów? Czy jest jakaś praktyczna zaleta używania trójgrafów?
UPD : W odpowiedziach wspomniano, że niektóre europejskie klawiatury nie mają wszystkich znaków interpunkcyjnych, więc programiści spoza Stanów Zjednoczonych muszą używać trójgrafów w życiu codziennym?
UPD2 : Visual Studio 2010 ma domyślnie wyłączoną obsługę trygrafów .
Odpowiedzi:
Na to pytanie (dotyczące blisko spokrewnionych dwuznaków) można odpowiedzieć.
Sprowadza się to do tego, że zestaw znaków ISO 646 nie zawiera wszystkich znaków składni C, więc są systemy z klawiaturami i wyświetlaczami, które nie radzą sobie ze znakami (chociaż wyobrażam sobie, że są one dość rzadkie dzisiaj).
Ogólnie rzecz biorąc, nie musisz ich używać, ale musisz wiedzieć o nich dokładnie w przypadku napotkanego problemu. Trygrafy są powodem, dla którego
?
znak „ ” ma sekwencję ucieczki:'\?'
Oto kilka sposobów uniknięcia przykładowego problemu:
printf( "What?\?!\n" ); printf( "What?" "?!\n" );
Ale musisz pamiętać, kiedy wpisujesz dwa „?” postaci, o których być może zaczynasz trygraf (iz pewnością nigdy o tym nie myślę).
W praktyce trójgrafy i dwuznaki to coś, o co na co dzień nie martwię się wcale. Ale powinieneś być ich świadomy, ponieważ raz na kilka lat napotkasz związany z nimi błąd (i spędzisz resztę dnia przeklinając ich istnienie). Byłoby miło, gdyby kompilatory mogły być skonfigurowane tak, aby ostrzegały (lub błąd), gdy natrafią na trójgraf lub dwuznak, więc mógłbym wiedzieć, że mam coś, z czym powinienem świadomie się uporać.
Dla kompletności dwuznaki są znacznie mniej niebezpieczne, ponieważ są przetwarzane jako tokeny, więc dwuznak wewnątrz literału ciągu nie zostanie zinterpretowany jako dwuznak.
Aby uzyskać dobrą edukację na temat różnych zabaw z interpunkcją w programach C / C ++ (w tym błędu trygrafu, który z pewnością sprawiłby, że wyrywam sobie włosy), zapoznaj się z artykułem Herba Suttera GOTW # 86 .
Uzupełnienie:
Wygląda na to, że GCC domyślnie nie przetwarza (i będzie ostrzegać) trygrafów. Niektóre inne kompilatory mają opcje wyłączania obsługi trigraph (na przykład IBM). Microsoft zaczął obsługiwać ostrzeżenie (C4837) w VS2008, które musi być jawnie włączone (za pomocą -Wall lub czegoś podobnego).
źródło
Dzieci dzisiaj! :-)
Tak, sprzęt zagraniczny, taki jak terminal IBM 3270. 3270 nie ma, jeśli dobrze pamiętam, aparatu ortodontycznego! Jeśli chciałeś napisać C na IBM mini / mainframe, to musiał użyć nędzne trójznaków dla każdej granicy bloku. Na szczęście musiałem tylko pisać oprogramowanie w C, aby emulować niektóre funkcje minikomputerów IBM, a nie pisać oprogramowania w C na Systemie / 36.
Spójrz obok klawisza „P”:
Hmmm. Ciężko powiedzieć. Obok „powrotu karetki” znajduje się dodatkowy przycisk, który może być odwrócony: może to była para „[” / „]”, której brakowało. W każdym razie ta klawiatura spowodowałaby żal, gdybyś musiał napisać C.
Ponadto terminale te wyświetlają EBCDIC, „natywny” zestaw znaków mainframe IBM, a nie ASCII (dzięki, Pavel Minaev, za przypomnienie).
Z drugiej strony, jak mówi przewodnik GNU C: „Nie potrzebujesz tego uszkodzenia mózgu”. Kompilator gcc domyślnie wyłącza tę „funkcję”.
źródło
Z
The C++ Programming Language
wydania specjalnego, strona 829źródło
`
, czego brakuje we włoskim i kilku innych układach klawiaturySą przeznaczone do użytku w systemach, w których brakuje niektórych znaków z podstawowego zestawu znaków C ++. Nie trzeba dodawać, że takie systemy są niezwykle rzadkie.
źródło
W C ++ 0x zaproponowano usunięcie trygrafów. To powiedziawszy, nadal wydaje się, że istnieją mocne argumenty na ich poparcie - patrz dokument komisji C ++ N2910, który to omawia. Najwyraźniej EBCDIC jest jedną z głównych bastionów, w których są potrzebne.
źródło
Widziałem trygrafy używane we wczesnych latach 90. do konwersji programów PL / 1 z komputera mainframe w celu uruchomienia / kompilacji / debugowania na komputerze PC.
Bawili się edycją PL / I na komputerze PC za pomocą kompilatora PL / I na C i chcieli, aby kod działał po przeniesieniu z powrotem do komputera mainframe, który nie obsługuje nawiasów klamrowych. Zasugerowałem, że mogą używać makr, takich jak
#def BEGIN { #def END }
lub jako bardziej przyjazną alternatywę PL / I
#def BEGIN ??< #def END ??>
a jeśli naprawdę chcieli się spodobać, mogli spróbować
#ifdef MAINFRAME #def BEGIN ??< #def END ??> #else #def BEGIN { #def END } #endif
a wtedy program wyglądałby tak, jakby był napisany w języku Pascal. Po prostu dziwnie na mnie patrzyli i nie rozmawiali ze mną przez resztę dnia. Chyba ich nie winię. :)
Tym, co zabiło wysiłek, a nie trójgrafami, były różnice w systemie IO między platformami. Otwieranie plików na komputerze PC różniło się tak bardzo od komputera typu mainframe, że wprowadziłoby zbyt wiele kludge, aby utrzymać ten sam kod działający na obu.
źródło
Przede wszystkim dlatego, że standard C wprowadził je w 1989 roku, kiedy pojawiły się problemy z obecnością znaków, które są mapowane na trójgrafach na niektórych komputerach. Do czasu opublikowania standardu C ++ w 1998 r. Zapotrzebowanie na trygrafy nie było duże. Są brodawką na C; są tak samo jak brodawka w C ++. Była taka potrzeba - szczególnie poza anglojęzycznym światem - dlatego dodano je do C.
źródło
Niektóre klawiatury europejskie nie mają (nie miały?) Wszystkich znaków interpunkcyjnych, które miały klawiatury amerykańskie, ponieważ potrzebowały klawiszy do ich niezwykłych znaków alfabetycznych. Na przykład (zmyślając) szwedzka klawiatura miałaby pierścień A w miejscu nawiasu klamrowego.
Aby dostosować się do tych użytkowników, trygrafy są sposobem wprowadzania znaków interpunkcyjnych przy użyciu tylko najpopularniejszych znaków ASCII.
źródło
Są tam głównie z powodów historycznych. Obecnie większość nowoczesnych klawiatur dla większości języków umożliwia dostęp do wszystkich tych znaków, ale kiedyś był to problem z niektórymi klawiaturami europejskimi. Dlatego wymyślono trójgrafy.
Jeśli nie wiesz, do czego służą, nie powinieneś ich używać.
Jednak nadal dobrze jest być ich świadomym, ponieważ możesz przypadkowo i nieumyślnie użyć go w swoim kodzie.
źródło