इससे क्या होता है ??!??! ऑपरेटर सी में करते हैं?


1989

मैंने सी की एक लाइन देखी जो इस तरह दिखाई देती है:

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

यह सही ढंग से संकलित है और ठीक लगता है। ऐसा लगता है कि यह जाँच रहा है कि क्या कोई त्रुटि हुई है, और यदि यह है, तो इसे संभालता है। लेकिन मुझे वास्तव में यकीन नहीं है कि यह वास्तव में क्या कर रहा है या यह कैसे कर रहा है। ऐसा लगता है कि प्रोग्रामर त्रुटियों के बारे में अपनी भावनाओं को व्यक्त करने की कोशिश कर रहा है।

मैंने पहले कभी ??!??!किसी प्रोग्रामिंग भाषा में नहीं देखा है , और मैं इसके लिए कहीं भी प्रलेखन नहीं पा सकता हूं। (Google जैसे खोज शब्दों के साथ मदद नहीं करता है ??!??!)। यह क्या करता है और कोड नमूना कैसे काम करता है?


44
@PeterOlson, आप !ErrorHasOccurred() ??!???! HandleError();संकलन की उम्मीद कैसे करते हैं ? वह है ??! ??? !। बात साबित होती है?
बजे एक CVn

31
मेरा सुझाव है कि आप क्लीन कोड पर पढ़ें। ErrorHasOccured () ErrorHasNotOccured () के लिए रिफ्लेक्ट किया जाना चाहिए और इस प्रकार विस्मयादिबोधक चिह्न को साफ करना चाहिए ... जिनके पास इन सभी ऑपरेटरों को समझने का समय है ??!
केडेकम

17
मैं बल्कि ErrorHasOccured() && HandleError()खुद को पसंद करता हूं। यह भी है कि लू कैसे करता है।
ह्यूगो जिंक

76
@KadekM, फ़ंक्शन नाम में नकार को स्थानांतरित करने से स्वच्छ कोड नहीं बनता है, बल्कि विपरीत होता है।
12

14
किसी के लिए एक नोट जो अपने खोज इंजन के साथ मौत की लड़ाई के बाद यहां समाप्त हो गया: प्रतीकात्मक हाउंड प्रतीकात्मक खोजों के साथ मदद कर सकता है।
जकॉब

जवाबों:


1578

??!एक ट्रिग्राफ है जो अनुवाद करता है |। तो यह कहता है:

!ErrorHasOccured() || HandleError();

जिसके कारण, छोटी चक्कर लगाना, के बराबर है:

if (ErrorHasOccured())
    HandleError();

द वीक के गुरु (सी ++ के साथ लेकिन यहां प्रासंगिक है), जहां मैंने इसे उठाया।

ट्रिब्यूट्स की संभावित उत्पत्ति या जैसा कि @DwB टिप्पणियों में बताते हैं, यह EBCDIC के मुश्किल (फिर से) होने के कारण अधिक संभावना है। आईबीएम डेवलपरवर्क्स बोर्ड की यह चर्चा उस सिद्धांत का समर्थन करती है।

ISO / IEC 9899 से: 1999 /5.2.1.1, फुटनोट 12 (h / t @ random832):

ट्रिग्राफ अनुक्रम उन वर्णों के इनपुट को सक्षम करते हैं जो कि इनवेरिएंट कोड सेट में परिभाषित नहीं होते हैं जैसा कि आईएसओ / आईईसी 646 में वर्णित है, जो सात-बिट यूएस एएससीआईआई सेट सेट का सबसेट है।


376
मूल रूप से आपके द्वारा कीबोर्ड के मामले में ट्रिग्राफ की आवश्यकता थी उदाहरण के लिए a '|' प्रतीक। यहाँ यह या तो प्रोग्रामर जानबूझकर परेशान कर रहा है या कुछ विचित्र संपादक 'फीचर'
मार्टिन बेकेट

35
हाँ, यह बराबर है if (ErrorHasOccured()) HandleError()। शुक्र है कि आप आमतौर पर इस मुहावरे का सामना पर्ल कोड में करते हैं।
user786653

22
यह जरूरी नहीं है कि EBCDIC - वर्णों के सेट की आवश्यकता होती है, जो लगभग उन वर्णों के सेट से मेल खाते हैं, जो ISO-646 (यानी पुराने 'राष्ट्रीय एससीआई' मानकों) में अपरिवर्तित नहीं हैं।
रैंडम 832

52
एक पूरी तरह से पठनीय विकल्प ErrorHasOccurred() && HandleError();यही होगा , यदि आप शेल स्क्रिप्टिंग के लिए उपयोग किए जाते हैं। :)
यम मार्कोविच

18
इसे "या तो कोई ErrorHasOcoubed के रूप में पढ़ें या आपको हैंडल होना चाहिए", @SparkyRobinson।
उमर एंटोलिन-केमरेना

453

खैर, यह सामान्य रूप से क्यों मौजूद है, शायद इससे अलग है कि यह आपके उदाहरण में क्यों मौजूद है।

यह सब आधी सदी पहले शुरू हुआ था जब कंप्यूटर उपयोगकर्ता इंटरफेस के रूप में हार्डकॉपी संचार टर्मिनलों को फिर से तैयार कर रहा था। प्रारंभिक यूनिक्स और सी युग में जो ASR-33 टेलेटाइप था।

यह उपकरण धीमा (10 सीपीएस) और शोर और बदसूरत था और इसके ASCII वर्ण सेट का दृश्य 0x5f पर समाप्त हो गया था, इसलिए इसमें कोई भी नहीं था (तस्वीर को बारीकी से देखें)

{ | } ~ 

ट्रिग्राफ को एक विशिष्ट समस्या को ठीक करने के लिए परिभाषित किया गया था। यह विचार था कि C प्रोग्राम ASR-33 पर पाए गए ASCII सबसेट का उपयोग कर सकते हैं और अन्य वातावरण में उच्च ASCII मान गायब हैं।

आपका उदाहरण वास्तव में दो है ??!, प्रत्येक अर्थ |, इसलिए परिणाम है ||

हालांकि, परिभाषा के अनुसार लगभग सी कोड लिखने वाले लोगों के पास आधुनिक उपकरण थे, 1 तो मेरा अनुमान है: कोई व्यक्ति खुद को दिखा रहा है या उन्हें खुश कर रहा है, आप खोजने के लिए कोड में एक प्रकार का ईस्टर अंडा छोड़ रहे हैं।

यह निश्चित रूप से काम करता है, यह एक बहुत ही लोकप्रिय एसओ प्रश्न है।

एएसआर -33 टेलेटाइप

                                            एएसआर -33 टेलेटाइप


1. उस मामले के लिए, एएनएसआई समिति द्वारा ट्रिग्राफ का आविष्कार किया गया था, जो पहली बार सी के बाद एक भगोड़ा सफलता बन गया था, इसलिए मूल सी कोड या कोडर्स में से किसी ने भी उनका उपयोग नहीं किया होगा।


18
यह कीबोर्ड और कैरेक्टर सेट में गायब पात्रों का एकमात्र मामला नहीं है। कमोडोर 64 के अपने देर से तीसवें और ऊपर के बहुत से लोगों के अधिक परिचित होने की संभावना है - प्रदर्शित चरित्र दोनों अभाव ब्रेसिज़ सेट करता है (और शायद बार और टिल्ड भी) - इस मामले में क्योंकि "ASCII" ASCII नहीं था । ECMA-6 में (लगभग हमेशा ASCII कहा जाता है, लेकिन US-ASCII नहीं) 18 क्षेत्र-विशिष्ट कोड थे, लेकिन मुझे नहीं पता कि वे कौन से कोड थे। एक बात जो मैं निश्चित रूप से कह सकता हूं - ब्रिटिश "ASCII" में, के #साथ बदल दी गई थी £। अन्य क्षेत्रों में, शायद "ASCII" में कोई ब्रेसिज़ आदि नहीं थे
स्टीव 314

7
अटारी 8-बिट कंप्यूटरों के लिए समान ATASCII वर्ण सेट में {} के साथ-साथ ~ और `का भी अभाव था।
dan04

42
ये दो विकिपीडिया लेख देखें । मैं अभी भी लगभग 7-बिट राष्ट्रीय वर्णमाला के युग को याद करने के लिए पर्याप्त पुराना हूं (हालांकि मुझे यकीन है कि वे अभी भी कुछ अंधेरे न सुलझे हुए कोनों पर हैं), और मैंने पहली बार सी से जो किताब सीखी थी, उसके बारे में चेतावनी देना आवश्यक था गलत चारसेट में if (x || y) { a[i] = '\0'; }दिखने की संभावना if (x öö y) ä aÄiÅ = 'Ö0'; å
इल्मरी करोनें

9
एक और दिलचस्प ऐतिहासिक बात यह है कि यूनिक्स (जो कि बड़े प्लेटफॉर्म सी रोड पर था) किसी भी महत्व का पहला सिस्टम हो सकता है (और शायद कुल मिलाकर) ऊपरी अक्षर के बजाय निचले मामले में अल्फ़ाबेटिक मानों को डिफ़ॉल्ट करने के लिए। हालांकि मैंने अपनी खुद की आँखों से कई समकालीन प्रणालियों को नहीं देखा है, मुझे लगता है कि यह परिष्कार का एक वास्तविक संकेत था। वास्तव में एकमात्र सभ्य ओएस होने के अलावा, यूनिक्स ने भी आपके ऊपरी मामले को कमतर में बदल दिया, बल्कि इसके विपरीत। वो लोग वाकई मस्त थे।
DigitalRoss

16
मजेदार कहानी मैं आपको बताना चाहता हूँ ... IBM RS / 6000 वर्कस्टेशन के XL फोरट्रान कंपाइलर को XL C कंपाइलर से विकसित किया गया था। पहले कुछ रिलीज में, वे गलती से ट्रिग्राफ प्रोसेसिंग में निकल गए थे, इसलिए कुछ कानूनी फोरट्रान कैरेक्टर सीक्वेंस (शाब्दिक स्ट्रिंग, IIRC में) थे जो सी ट्रिग्राफ के रूप में गलत व्याख्या किए गए थे, जिससे कुछ दिलचस्प कीड़े पैदा हुए!
फिल पेरी

166

यह C ट्रिगर है??!है |, तो ??!??!ऑपरेटर है||


5
ट्रिग्राफ एक ऐसे दौर से आता है जहाँ कुछ कीबोर्ड में वे सभी कुंजियाँ नहीं होती हैं जो अब उनके पास हैं। यह तब भी आता है जब कुछ पाठ संपादक ने विशेष चीजों के लिए विशेष वर्ण आरक्षित किए। यह ज्यादातर अतीत का एक अवशेष और एक क्विज़ एनबलर है;)
जोएल फाल्को

5
क्योंकि कुछ कीबोर्ड स्पष्ट रूप से नहीं है "|" इसलिए कुछ लोगों के पास कीबोर्ड को बार-बार हेडबट करने के अलावा कोई विकल्प नहीं होता है जब तक कि एक ट्रिग्राफ नहीं होता है जो उन्हें उन प्रतीकों को देता है जिनकी उन्हें आवश्यकता होती है।
उल्लू

और फिर <iso646.h>हैडर फाइल होती है।
डेविड आर ट्रिब्बल

149

जैसा कि पहले ही कहा गया है ??!??!कि अनिवार्य रूप से दो ट्रिग्राफ ( ??!और ??!फिर से) एक साथ फंसे हुए होते हैं , जिन्हें प्रीप्रोसेसर द्वारा प्रतिस्थापित किया जाता है- ||अर्थात तार्किक या , तार्किक या

निम्न प्रत्येक ट्रिग्राफ वाली तालिका को वैकल्पिक ट्रिग्राफ संयोजनों को खंडित करने में मदद करनी चाहिए:

Trigraph   Replaces

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

स्रोत: सी: एक संदर्भ मैनुअल 5 वें संस्करण

तो ऐसा ट्रिग्राफ जो दिखता है, ??(??)आखिरकार मैप कर लेगा [], ??(??)??(??)इसकी जगह ले लेगा , [][]और आपको इसका आइडिया मिल जाएगा।

चूंकि ट्रिग्राफ को प्रीप्रोसेसिंग के दौरान प्रतिस्थापित किया जाता है इसलिए आप cppएक मूर्खतापूर्ण trigr.cप्रोग्राम का उपयोग करके, आउटपुट का एक दृश्य प्राप्त करने के लिए उपयोग कर सकते हैं :

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

और इसके साथ प्रसंस्करण:

cpp -trigraphs trigr.c 

आपको एक कंसोल आउटपुट मिलेगा

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

जैसा कि आप देख सकते हैं, विकल्प -trigraphsनिर्दिष्ट होना चाहिए या फिर cppएक चेतावनी जारी करेगा; यह इंगित करता है कि ट्रिग्राफ अतीत की बात है और उन लोगों को भ्रमित करने के अलावा कोई आधुनिक मूल्य नहीं है जो उन्हें टक्कर दे सकते हैं


Trigraphs की शुरूआत के पीछे तर्क का सवाल है, यह बेहतर समझा जाता है जब पर देख रहे हैं आईएसओ / आईईसी 646 के इतिहास अनुभाग :

आईएसओ / IEC 646 और इसके पूर्ववर्ती ASCII (ANSI X3.4) ने दूरसंचार उद्योग में चरित्र एनकोडिंग के बारे में मौजूदा अभ्यास का समर्थन किया है।

जैसा कि एएससीआईआई ने अंग्रेजी के अलावा अन्य भाषाओं के लिए आवश्यक कई वर्ण प्रदान नहीं किए हैं, कई राष्ट्रीय वेरिएंट बनाए गए थे जिन्होंने कुछ कम-उपयोग किए गए पात्रों को आवश्यक लोगों के साथ प्रतिस्थापित किया

(जोर मेरा)

तो, संक्षेप में, कुछ आवश्यक पात्रों (जिनके लिए एक ट्रिग्राफ मौजूद है) को कुछ राष्ट्रीय वेरिएंट में बदल दिया गया था। यह वैकल्पिक वर्णों का उपयोग करता है, जिसमें अन्य वर्ण अभी भी आसपास मौजूद वर्णों का उपयोग करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.