Mục đích của trình tự Trecraft trong C ++?


127

Theo C ++ '03 Tiêu chuẩn 2.3 / 1:

Trước khi bất kỳ quá trình xử lý nào khác diễn ra, mỗi lần xuất hiện của một trong các chuỗi sau của ba ký tự (chuỗi trình tự ba chiều của thuật ngữ) được thay thế bằng ký tự đơn được chỉ ra trong Bảng 1.

----------------------------------------------------------------------------
| trigraph | replacement | trigraph | replacement | trigraph | replacement |
----------------------------------------------------------------------------
| ??=      | #           | ??(      | [           | ??<      | {           |
| ??/      | \           | ??)      | ]           | ??>      | }           |
| ??’      | ˆ           | ??!      | |           | ??-      | ˜           |
----------------------------------------------------------------------------

Trong cuộc sống thực, điều đó có nghĩa là mã printf( "What??!\n" );sẽ dẫn đến việc in What|??!là một chuỗi ba chữ được thay thế bằng |ký tự.

Câu hỏi của tôi là mục đích của việc sử dụng tricles? Có bất kỳ lợi thế thực tế của việc sử dụng tricles?

CẬP NHẬT : Trong các câu trả lời đã được đề cập rằng một số bàn phím châu Âu không có tất cả các ký tự dấu chấm câu, vì vậy các lập trình viên không phải là người Mỹ phải sử dụng ba chữ trong cuộc sống hàng ngày?

CẬP NHẬT : Visual Studio 2010 đã tắt hỗ trợ trecraft theo mặc định.


Một số dấu câu khó tiếp cận hơn trên bàn phím châu Âu (đến mức một số lập trình viên sử dụng bố cục của Hoa Kỳ để gõ nhanh hơn) Không thấy một dấu chấm nào bị thiếu dấu chấm - có thể cho các ngôn ngữ slavic?
peterchen

2
Có thể xảy ra việc một số thiết bị đầu cuối và / hoặc ảo hóa không cho phép bạn truy cập dễ dàng vào một số ký tự. Theo kinh nghiệm của tôi, người phạm tội chính là dấu ngã.
Francesco

1
gõ cái này trên bàn phím DE-deadkeys của tôi, # là một phím bên cạnh để trả về, \ là "AltGr" + "ß" (bên cạnh 0), ^ là "^" + "^" (vì có deadkey; bên cạnh 1) , [là "AltGr" + "8",] là "AltGr" + "9", | là "AltGr" + "<", {là "AltGr" + "7",} là "AltGr" + "0" và ~ là "~" + "~" (vì các phím tắt, chỉ trên #). Vì vậy, không có vấn đề thực sự lớn. ngón tay của tôi giống như tự gõ các kết hợp này :-D
nonchip

1
Tôi nghĩ rằng việc có hai bố trí bàn phím và chuyển đổi chúng theo công việc tôi đang làm trên máy tính là điều bình thường. Đó là cách phổ biến ở khu vực trung tâm châu Âu. Thật đáng sợ khi sử dụng những bức thư này. Tôi sẽ bỏ phiếu để loại bỏ điều này khỏi tiêu chuẩn.
VX

Câu trả lời:


97

Câu hỏi này (về các bản tóm tắt liên quan chặt chẽ) có câu trả lời.

Thực tế là bộ ký tự ISO 646 không có tất cả các ký tự của cú pháp C, do đó, có một số hệ thống với bàn phím và màn hình không thể xử lý các ký tự (mặc dù tôi tưởng tượng rằng chúng khá hiếm ngày nay).

Nói chung, bạn không cần sử dụng chúng, nhưng bạn cần biết về chúng để biết chính xác vấn đề bạn gặp phải. Các ký tự là lý do ?nhân vật '' có một chuỗi thoát:

'\?'

Vì vậy, một số cách bạn có thể tránh vấn đề ví dụ của mình là:

 printf( "What?\?!\n" ); 

 printf( "What?" "?!\n" ); 

Nhưng bạn phải nhớ khi bạn gõ hai '?' các nhân vật mà bạn có thể đang bắt đầu một bộ ba (và chắc chắn đó không bao giờ là điều tôi nghĩ đến).

Trong thực tế, các bức thư và bản vẽ sơ đồ là thứ tôi không lo lắng chút nào trên cơ sở hàng ngày. Nhưng bạn nên biết về chúng bởi vì cứ sau vài năm bạn sẽ gặp phải một lỗi liên quan đến chúng (và bạn sẽ dành phần còn lại của ngày để nguyền rủa sự tồn tại của chúng). Sẽ thật tuyệt nếu trình biên dịch có thể được cấu hình để cảnh báo (hoặc lỗi) khi nó bắt gặp một trecraft hoặc digraph, vì vậy tôi có thể biết rằng tôi đã có một cái gì đó tôi nên xử lý một cách có chủ ý.

Và chỉ để hoàn thiện, các bản tóm tắt ít nguy hiểm hơn vì chúng được xử lý dưới dạng mã thông báo, do đó, một bản tóm tắt bên trong một chuỗi ký tự sẽ không được hiểu là một bản tóm tắt.

Để có một nền giáo dục tốt về nhiều niềm vui khác nhau với dấu câu trong các chương trình C / C ++ (bao gồm cả lỗi ba chữ chắc chắn sẽ khiến tôi nhổ tóc), hãy xem bài viết GOTW # 86 của Herb Sutter .


Phụ lục:

Có vẻ như GCC sẽ không xử lý (và sẽ cảnh báo về) các bộ ba theo mặc định. Một số trình biên dịch khác có các tùy chọn để tắt hỗ trợ trecraft (ví dụ của IBM). Microsoft bắt đầu hỗ trợ cảnh báo (C4837) trong VS2008 phải được bật rõ ràng (sử dụng -Wall hoặc một cái gì đó).


Khả năng tương thích với C là lý do duy nhất? Có thể gặp họ trong các chương trình C ++ hiện đại không?
Kirill V. Lyadvinsky

Có, C ++ cũng hỗ trợ các thư mục và bản thảo.
Michael Burr

4
Như tôi nhớ lại, ít nhất một trình biên dịch mà tôi đã sử dụng (g ++?) Yêu cầu một tùy chọn dòng lệnh rõ ràng trước khi dịch thuật và bản dịch được dịch, nếu không thì cảnh báo được đưa ra nhưng không có sự thay thế.
KTC

1
@ Jla3ep - Cá nhân tôi chưa bao giờ có nhu cầu về bộ ba, nhưng không may là trình biên dịch sẽ xử lý mã với chúng, vì vậy bạn cần lưu ý về chúng (để tránh sử dụng ngẫu nhiên). Ngoài ra, nếu bạn nhận được mã từ một nơi khác, bạn có thể sử dụng chúng một cách có chủ ý, nhưng điều đó sẽ cực kỳ bất thường. Tôi nghĩ rằng tôi đã tình cờ sử dụng các bộ ba được sử dụng một lần trong hơn 20 năm qua (đó là một số mã cho máy tính lớn của IBM).
Michael Burr

1
Nó thực sự chỉ làm tôi lo lắng khi các bài viết được mở rộng trong các bình luận để làm những điều đáng ngạc nhiên.
Joshua

23

Trẻ em hôm nay! :-)

Có, thiết bị nước ngoài, chẳng hạn như thiết bị đầu cuối IBM 3270. 3270, nếu tôi nhớ, không có niềng răng xoăn! Nếu bạn muốn viết C trên mini / mainframe của IBM, bạn phải sử dụng các bộ ba khốn khổ cho mọi ranh giới khối. May mắn thay, tôi chỉ phải viết phần mềm bằng C để mô phỏng một số cơ sở máy tính mini của IBM, chứ không thực sự viết phần mềm C trên System / 36.

Nhìn bên cạnh phím "P":

bàn phím

Hừm. Khó nói. Có một nút phụ bên cạnh "trả lại xe ngựa" và tôi có thể có nó ngược lại: có thể đó là cặp "[" / "]" bị thiếu. Dù sao đi nữa, bàn phím này sẽ khiến bạn đau buồn nếu bạn phải viết C.

Ngoài ra, các thiết bị đầu cuối này hiển thị EBCDIC, bộ ký tự máy tính lớn "bản địa" của IBM, chứ không phải ASCII (cảm ơn, Pavel Minaev, để nhắc nhở).

Mặt khác, như hướng dẫn GNU C nói: "Bạn không cần tổn thương não này." Trình biên dịch gcc để mặc định "tính năng" này bị tắt.


1
Có một nút đặt lại trên bàn phím. Thật tuyệt vời! Lạ mà thu hút sự chú ý của tôi đầu tiên mặc dù.
l46kok

10
Bất cứ ai muốn sử dụng C ++ 17 trên máy EBCDIC, đều phải bị bỏ tù vì hoại tử.
SF.

Trừ khi một nền tảng không có ký tự ở tất cả ngoại trừ những người ở ISO646, không thể tất cả những gì có thể được thực hiện với trigraphs, được thực hiện bằng cách yêu cầu rằng tất cả thực hiện xác định hoặc một dấu gạch chéo hoặc bất kỳ ký tự khác mà không có trong bộ ký tự C như một Ký tự "meta", thay thế tất cả các tham chiếu đến dấu gạch chéo ngược trong Tiêu chuẩn bằng "meta" và thêm dấu gạch chéo / thoát meta cho bất kỳ thành viên nào của bộ ký tự C không có trong ISO-646?
supercat

22

Từ The C++ Programming Languagephiên bản đặc biệt, trang 829

Các ký tự đặc biệt ASCII [, ], {, }, |, và \chiếm vị trí bộ ký tự chỉ định là chữ cái theo tiêu chuẩn ISO. Trong hầu hết các bộ ký tự ISO-646 quốc gia châu Âu, các vị trí này bị chiếm bởi các chữ cái không có trong bảng chữ cái tiếng Anh.

Một tập hợp các bộ ba được cung cấp để cho phép các ký tự quốc gia được thể hiện theo cách di động bằng cách sử dụng một bộ ký tự tối thiểu thực sự tiêu chuẩn. Điều này có thể hữu ích cho việc trao đổi các chương trình, nhưng nó không giúp mọi người đọc chương trình dễ dàng hơn. Đương nhiên, giải pháp lâu dài cho vấn đề này là dành cho các lập trình viên C ++ để có được thiết bị hỗ trợ tốt cả ngôn ngữ mẹ đẻ và C ++ của họ. Thật không may, điều này dường như không khả thi đối với một số người và việc giới thiệu thiết bị mới có thể là một quá trình chậm chạp khó chịu.


7
"Việc giới thiệu thiết bị mới có thể là một quá trình chậm chạp khó chịu". Đặc biệt so với quá trình nhanh chóng và không đau đớn của việc chuẩn hóa các tính năng ngôn ngữ lập trình.
jforberg

4
Nếu đây là một loại bùn cho bố trí bàn phím, thì thật buồn cười là không có chữ viết tắt nào, ví dụ như gõ `từ tiếng Ý và một số bố cục bàn phím khác
badp

15

Chúng được sử dụng trên các hệ thống thiếu một số ký tự trong bộ ký tự cơ bản của C ++. Không cần phải nói, các hệ thống như vậy là cực kỳ hiếm.


2
Điều đó có nghĩa là tôi sẽ không bao giờ sử dụng chúng trong cuộc sống thực?
Kirill V. Lyadvinsky

1
bạn sống ở nước nào? Không phải tất cả các bàn phím cho tất cả các ngôn ngữ có các phím cần thiết.
David Thornley

2
Có, nhưng bạn có thể cần phải biết về sự tồn tại trong trường hợp một nguyên nhân gây ra kết quả không mong muốn khi được trang bị, giả sử, một chuỗi bằng chữ.
CB Bailey

4
@David Thornley: Hầu hết các hệ thống hiện đại đều hỗ trợ tất cả các ký tự cơ bản của C ++ ngay cả khi chúng không ở vị trí thông thường hoặc yêu cầu trình tự sửa đổi để nhập. Các ký tự chỉ cần được duy trì trong mã nguồn trên các hệ thống mà ký tự thực sự không thể được biểu diễn trong bộ ký tự hệ thống. Tôi vẫn duy trì rằng các hệ thống như vậy là cực kỳ hiếm.
CB Bailey

9

Các thư mục đã được đề xuất để loại bỏ trong C ++ 0x. Điều đó nói rằng, dường như vẫn còn có lập luận mạnh mẽ ủng hộ họ - xem bài viết của ủy ban C ++ N2910 thảo luận về điều này. Rõ ràng, EBCDIC là một thành trì lớn nơi họ cần.


Vâng, "ngoại ngữ" đó! :-)
Roboprog

Họ không thực sự nói nhiều ngoại trừ "kết quả từ một cuộc khảo sát nội bộ về phản hồi của khách hàng", nhưng cũng tốt. Tôi ngạc nhiên rằng EBCDIC vẫn được sử dụng rộng rãi mặc dù (và các hệ thống này dự kiến ​​sẽ sử dụng trình biên dịch C ++ 0x)
peterchen

5

Tôi đã thấy các bộ ba được sử dụng vào đầu những năm 90 để giúp chuyển đổi các chương trình PL / 1 từ máy tính lớn để được chạy / biên dịch / gỡ lỗi trên PC.

Họ đã chỉnh sửa PL / I trên PC bằng trình biên dịch PL / I sang C và họ muốn mã hoạt động khi được chuyển trở lại máy tính lớn không hỗ trợ dấu ngoặc nhọn. Tôi đề nghị họ có thể sử dụng macro như

#def BEGIN {    
#def END }  

hoặc như một sự thay thế PL / I thân thiện hơn

#def BEGIN ??<
#def END ??>

và nếu họ thực sự muốn được ưa thích, họ có thể thử

#ifdef MAINFRAME
    #def BEGIN ??<
    #def END ??>
#else
    #def BEGIN {    
    #def END }  
#endif

và sau đó chương trình sẽ trông giống như được viết bằng Pascal. Họ chỉ nhìn tôi buồn cười và sẽ không nói chuyện với tôi trong phần còn lại của ngày. Tôi không nghĩ rằng tôi đổ lỗi cho họ. :)

Điều đã giết chết những nỗ lực không phải là ba biểu đồ, đó là sự khác biệt của hệ thống IO giữa các nền tảng. Mở các tệp trên PC khác rất nhiều so với máy tính lớn, nó sẽ giới thiệu quá nhiều cách để giữ cùng một mã chạy trên cả hai.


PL / 1 = Phiên bản C của IBM (nhiều hơn hoặc ít hơn). Xem nhận xét của tôi: Các thiết bị đầu cuối của IBM không có khóa '{' / '}' :-( Loại khó viết C [++] trên một trong số này, nếu không.
Roboprog

3

Chủ yếu bởi vì tiêu chuẩn C đã giới thiệu chúng trở lại vào năm 1989, khi có vấn đề với sự hiện diện của các ký tự mà ánh xạ bản đồ trên một số máy. Vào thời điểm tiêu chuẩn C ++ được công bố vào năm 1998, nhu cầu về các bộ ba là không lớn. Họ là một mụn cóc trên C; họ chỉ là một mụn cóc trên C ++. Cần có họ - đặc biệt là bên ngoài thế giới nói tiếng Anh - đó là lý do tại sao họ được thêm vào C.


1
Tôi đã luôn nghi ngờ rằng IBM đã không nói tiếng Anh :-)
Roboprog

3

Một số bàn phím châu Âu không (không?) Có tất cả các ký tự dấu chấm câu mà bàn phím Hoa Kỳ có, bởi vì chúng cần các phím cho các ký tự chữ cái khác thường của chúng. Vì vậy, ví dụ (làm điều này), bàn phím Thụy Điển sẽ có vòng chữ A trong đó nẹp xoăn.

Để phù hợp với những người dùng đó, các bộ ba là một cách để nhập dấu chấm câu chỉ sử dụng các ký tự ASCII phổ biến nhất.


4
Các thư mục không thực sự về nhập dữ liệu (họ tạo mã khá khó đọc), họ nói nhiều hơn về các hệ thống không thực sự có các ký tự được yêu cầu. Nếu một hệ thống có thể ghi và hiển thị ký tự - ngay cả khi một chuỗi khóa giống như khóa cần phải gõ - thì việc giữ lại chuỗi ký tự trong nguồn sẽ dễ dàng hơn nhiều.
CB Bailey

2

Họ ở đó chủ yếu là vì lý do lịch sử. Ngày nay, hầu hết các bàn phím hiện đại cho hầu hết các ngôn ngữ đều cho phép truy cập vào tất cả các ký tự đó, nhưng điều này từng là vấn đề một lần với một số bàn phím châu Âu. Đây là lý do tại sao các bức tượng được phát minh.

Nếu bạn không biết họ dùng để làm gì, bạn không nên sử dụng chúng.

Mặc dù vậy, vẫn tốt để biết về chúng, vì bạn có thể vô tình và vô tình sử dụng một mã trong mã của mình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.