it-swarm-id.com

Apa yang dilakukan C ??! ??! operator lakukan?

Saya melihat garis C yang terlihat seperti ini:

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

Itu dikompilasi dengan benar dan tampaknya berjalan ok. Sepertinya memeriksa apakah ada kesalahan, dan jika ada, itu menanganinya. Tetapi saya tidak begitu yakin apa yang sebenarnya dilakukan atau bagaimana melakukannya. Tampaknya programmer mencoba mengungkapkan perasaan mereka tentang kesalahan.

Saya belum pernah melihat ??!??! sebelumnya dalam bahasa pemrograman apa pun, dan saya tidak dapat menemukan dokumentasi untuk itu di mana pun. (Google tidak membantu dengan istilah pencarian seperti ??!??!). Apa fungsinya dan bagaimana contoh kode bekerja?

1820
Peter Olson

??! adalah trigraph yang diterjemahkan menjadi |. Jadi katanya:

!ErrorHasOccured() || HandleError();

yang, karena hubungan arus pendek, setara dengan:

if (ErrorHasOccured())
    HandleError();

Guru Minggu Ini (berkaitan dengan C++ tetapi relevan di sini), di mana saya mengambil ini.

Kemungkinan Asal trigraphs atau seperti @DwB tunjukkan dalam komentar itu lebih mungkin karena EBCDIC menjadi sulit (lagi). Diskusi ini di papan developerworks IBM tampaknya mendukung teori itu.

Dari ISO/IEC 9899: 1999 §5.2.1.1, catatan kaki 12 (h/t @ Random832):

Urutan trigraph memungkinkan input karakter yang tidak didefinisikan dalam Set Kode Invarian seperti yang dijelaskan dalam ISO/IEC 646, yang merupakan subset dari tujuh-bit US ASCII set kode.

1475
user786653

Nah, mengapa ini ada secara umum mungkin berbeda dari mengapa itu ada dalam contoh Anda.

Itu semua dimulai setengah abad yang lalu dengan repurposing terminal komunikasi hardcopy sebagai antarmuka pengguna komputer. Di era awal Unix dan C itu adalah ASR-33 Teletype.

Perangkat ini lambat (10 cps) dan berisik dan jelek dan tampilan set karakter ASCII berakhir pada 0x5f, jadi (tidak melihat gambar) tidak ada tombol:

{ | } ~ 

Trigraphs didefinisikan untuk memperbaiki masalah tertentu. Idenya adalah bahwa program C dapat menggunakan subset ASCII yang ditemukan pada ASR-33 dan di lingkungan lain kehilangan nilai ASCII yang tinggi.

Contoh Anda sebenarnya adalah dua dari ??!, masing-masing artinya |, jadi hasilnya adalah ||.

Namun, orang yang menulis kode C hampir secara definisi memiliki peralatan modern,1 jadi tebakan saya adalah: seseorang memamerkan atau menghibur diri mereka sendiri, meninggalkan semacam Telur Paskah dalam kode untuk Anda temukan.

Itu pasti berhasil, itu mengarah ke pertanyaan SO yang sangat populer.

 ASR-33 Teletype

ASR-33 Teletype


1. Dalam hal ini, trigraph ditemukan oleh komite ANSI, yang pertama kali bertemu setelah C menjadi sukses besar, sehingga tidak ada kode C atau coders asli yang akan menggunakannya.
414
DigitalRoss

Ini adalah C trigraph . ??! adalah |, jadi ??!??! adalah operator ||

153
Joel Falcou

Seperti yang telah dinyatakan ??!??! pada dasarnya adalah duatrigraphs(??! dan ??! lagi) disatukan bersama yang diganti-diterjemahkan ke ||, yaitu logical OR , oleh preprocessor.

Tabel berikut ini berisi setiap trigraph akan membantu menyatukan kombinasi trigraph alternatif:

Trigraph   Replaces

??(        [
??)        ]
??<        {
??>        }
??/        \
??'        ^
??=        #
??!        |
??-        ~

Sumber: C: A Reference Manual Edisi ke 5

Jadi trigraph yang terlihat seperti ??(??) akhirnya akan dipetakan ke [], ??(??)??(??) akan digantikan oleh [][] dan seterusnya, Anda mendapatkan idenya.

Karena trigraph diganti selama preprocessing, Anda bisa menggunakan cpp untuk mendapatkan tampilan outputnya sendiri, menggunakan program trigr.c konyol:

void main(){ const char *s = "??!??!"; } 

dan memprosesnya dengan:

cpp -trigraphs trigr.c 

Anda akan mendapatkan output konsol sebesar

void main(){ const char *s = "||"; }

Seperti yang Anda perhatikan, opsi -trigraphs harus ditentukan atau jika tidak cpp akan mengeluarkan peringatan; ini menunjukkan bagaimana trigraph adalah sesuatu dari masa lalu dan tidak memiliki nilai modern selain membingungkan orang yang mungkin menabrak mereka.


Adapun alasan di balik pengenalan trigraph, lebih baik dipahami ketika melihat bagian sejarah ISO/IEC 646 :

ISO/IEC 646 dan pendahulunya ASCII (ANSI X3.4) sebagian besar mendukung praktik yang ada mengenai pengkodean karakter dalam industri telekomunikasi.

As ASCII tidak menyediakan sejumlah karakter yang diperlukan untuk bahasa selain bahasa Inggris, sejumlah varian nasional dibuat yang menggantikan beberapa karakter yang kurang digunakan dengan yang dibutuhkan .

(penekanan milikku)

Jadi, pada dasarnya, beberapa karakter yang diperlukan (yang ada trigraph ada) diganti dalam varian nasional tertentu. Ini mengarah pada representasi alternatif menggunakan trigraph yang terdiri dari karakter yang masih dimiliki oleh varian lain.

126