स्विच स्टेटमेंट: अंतिम केस में डिफ़ॉल्ट होना चाहिए?


178

निम्नलिखित switchकथन पर विचार करें :

switch( value )
{
  case 1:
    return 1;
  default:
    value++;
    // fall-through
  case 2:
    return value * 2;
}

यह कोड संकलित करता है, लेकिन क्या यह C90 / C99 के लिए मान्य (= परिभाषित व्यवहार) है? मैंने कभी ऐसा कोड नहीं देखा है जहां डिफ़ॉल्ट मामला अंतिम मामला नहीं है।

EDIT:
जैसा कि जॉन केज और किलियांदस लिखते हैं: यह वास्तव में बदसूरत और भ्रमित कोड है और मैं इससे अच्छी तरह वाकिफ हूं। मुझे केवल सामान्य वाक्य रचना में दिलचस्पी है (क्या यह परिभाषित है?) और अपेक्षित आउटपुट।


19
+1 कभी भी उस व्यवहार पर विचार नहीं किया
जेमी वोंग

@ Péter Török: आपका मतलब है अगर मूल्य == 2 यह 6 वापस आएगा?
अलेक्जेंड्रे सी।

4
@ Péter Török नहीं, आदेश से कोई फर्क नहीं पड़ता - यदि मान किसी भी मामले के लेबल में स्थिरांक से मेल खाता है, तो नियंत्रण लेबल के बाद उस कथन पर कूद जाएगा, अन्यथा नियंत्रण डिफ़ॉल्ट लेबल के बाद बयान में कूद जाएगा यदि मौजूद हो।
पीट किरखम

11
@ जॉन केज gotoबुराई नहीं है। कार्गो पंथ अनुयायी हैं! आप कल्पना नहीं कर सकते हैं कि लोग किस चरम सीमा से बच सकते हैं gotoक्योंकि यह सब इतनी बुरी तरह से बुराई है, जिससे उनके कोड का वास्तविक अपठनीय गड़बड़ हो जाता है।
पैट्रिक श्ल्टर

3
मैं gotoमुख्य रूप से finallyकार्यों में एक खंड की तरह कुछ का अनुकरण करने के लिए उपयोग करता हूं , जहां रोकते समय (स्रोत, फ़ाइलें, मेमोरी) को जारी करना पड़ता है, और हर त्रुटि मामले की सूची के लिए दोहराता है freeऔर closeपठनीयता के लिए मदद नहीं करता है। हालांकि इसका एक उपयोग है gotoकि मैं बचना चाहूंगा, लेकिन ऐसा नहीं हो सकता, जब मैं एक लूप से बाहर निकलना चाहता हूं और मैं switchउस लूप में हूं ।
पैट्रिक श्ल्टर

जवाबों:


83

C99 मानक इस बारे में स्पष्ट नहीं है, लेकिन सभी तथ्यों को एक साथ लेकर, यह पूरी तरह से मान्य है।

caseऔर defaultलेबल एक के बराबर हैंgoto लेबल के । 6.8.1 लेबल देखें। विशेष रूप से दिलचस्प 6.8.1.4 है, जो पहले से उल्लेख किए गए डफ डिवाइस को सक्षम करता है:

किसी भी कथन को एक उपसर्ग से पहले किया जा सकता है जो एक पहचानकर्ता को एक लेबल नाम के रूप में घोषित करता है। अपने आप में लेबल नियंत्रण के प्रवाह को परिवर्तित नहीं करते हैं, जो कि उन पर अप्रभावित जारी रहता है।

संपादित करें : एक स्विच के भीतर कोड कुछ खास नहीं है; यह एक के रूप में कोड का एक सामान्य ब्लॉक हैif अतिरिक्त कूद लेबलों के साथ, । यह गिरावट के माध्यम से व्यवहार की व्याख्या करता है और क्यों breakआवश्यक है।

6.8.4.2.7 भी एक उदाहरण देता है:

switch (expr) 
{ 
    int i = 4; 
    f(i); 
case 0: 
    i=17; 
    /*falls through into default code */ 
default: 
    printf("%d\n", i); 
} 

कृत्रिम कार्यक्रम में वह वस्तु जिसका पहचानकर्ता मैं होता है, स्वचालित भंडारण अवधि (ब्लॉक के भीतर) के साथ मौजूद होता है, लेकिन इसे कभी भी प्रारंभ नहीं किया जाता है, और इस प्रकार यदि नियंत्रण अभिव्यक्ति में एक गैर-अक्षीय मान है, तो प्रिंटफ फ़ंक्शन के लिए कॉल एक अनिश्चित मूल्य तक पहुंच जाएगा। इसी प्रकार, फ़ंक्शन f पर कॉल तक नहीं पहुंचा जा सकता है।

एक स्विच स्टेटमेंट में केस कांस्टेंट अद्वितीय होना चाहिए:

6.8.4.2.3 प्रत्येक केस लेबल की अभिव्यक्ति एक पूर्णांक स्थिर अभिव्यक्ति होगी और एक ही स्विच स्टेटमेंट में मामले के दो स्थिर अभिव्यक्ति के रूपांतरण के बाद समान मूल्य नहीं होगा। स्विच स्टेटमेंट में अधिकांश एक डिफ़ॉल्ट लेबल हो सकता है।

सभी मामलों का मूल्यांकन किया जाता है, तो यह डिफ़ॉल्ट लेबल पर जाता है, यदि दिया गया हो:

6.8.4.2.5 पूर्णांक प्रचार नियंत्रण अभिव्यक्ति पर किए जाते हैं। प्रत्येक केस लेबल में निरंतर अभिव्यक्ति नियंत्रित अभिव्यक्ति के पदोन्नत प्रकार में बदल जाती है। यदि एक परिवर्तित मूल्य मिलान नियंत्रित अभिव्यक्ति के मिलान से मेल खाता है, तो मिलान किए गए केस लेबल के बाद स्टेटमेंट को नियंत्रित करता है। अन्यथा, यदि कोई डिफ़ॉल्ट लेबल है, तो लेबल किए गए स्टेटमेंट को नियंत्रित करें। यदि कोई परिवर्तित मामला स्थिर अभिव्यक्ति से मेल नहीं खाता है और कोई डिफ़ॉल्ट लेबल नहीं है, तो स्विच बॉडी का कोई भी भाग निष्पादित नहीं होता है।


6
@HeathHunnicutt आप स्पष्ट रूप से उदाहरण के उद्देश्य को नहीं समझ पाए। कोड इस पोस्टर द्वारा नहीं बनाया गया है, लेकिन सी मानक से सीधे लिया गया है, अजीब स्विच स्टेटमेंट कैसे हैं, और कैसे खराब अभ्यास से कीड़े पैदा होंगे। यदि आपने कोड के नीचे पाठ पढ़ने की जहमत उठाई है, तो आपको उतना ही एहसास होगा।
लुंडिन

2
डाउनवोट के लिए क्षतिपूर्ति करने के लिए +1। सी मानक का हवाला देकर किसी को नीचा दिखाना काफी कठोर लगता है।
लुंडिन

2
@ लुंडिन मैं सी-वोटिंग डाउन नहीं कर रहा हूं, और जैसा कि आप सुझाव देते हैं, मैंने कुछ भी अनदेखा नहीं किया। मैंने खराब, और अनावश्यक, उदाहरण का उपयोग करने के बुरे शिक्षण को वोट दिया। विशेष रूप से, वह उदाहरण पूरी तरह से एक अलग स्थिति से संबंधित है जिसके बारे में पूछा गया था। मैं आगे बढ़ सकता था, लेकिन "आपकी प्रतिक्रिया के लिए धन्यवाद।"
हीथ हनीनकुट

12
इंटेल आपको बताता है कि ब्रांच और लूप पुनर्गठन में स्विच स्टेटमेंट में सबसे अधिक बार कोड को पहले मिसप्रिंट को रोकने के लिए रखा जाए । मैं यहां हूं क्योंकि मेरे पास defaultलगभग 100: 1 द्वारा अन्य मामलों पर हावी होने वाला मामला है, और मुझे नहीं पता कि क्या इसका defaultपहला मामला बनाने के लिए वैध या अपरिभाषित है ।
jww

@jww मुझे यकीन नहीं है कि आप इंटेल द्वारा क्या मतलब है। अगर आपको बुद्धिमत्ता से मतलब है तो मैं इसे परिकल्पना कहूंगा। मेरी भी यही सोच थी, लेकिन बाद में पढ़ने में कहा गया कि यदि बयानों के विपरीत, स्विच स्टेटमेंट यादृच्छिक अभिगम हैं। इसलिए आखिरी मामला पहले की तुलना में धीमा नहीं है। यह लगातार मामले के मूल्यों को हैशिंग द्वारा पूरा किया गया है। इसीलिए जब शाखाएँ अलॉट होती हैं तो स्टेटमेंट की तुलना में स्विच स्टेटमेंट तेज़ होते हैं।

91

स्विच स्टेटमेंट में केस स्टेटमेंट और डिफॉल्ट स्टेटमेंट किसी भी क्रम में हो सकते हैं। डिफॉल्ट क्लॉज एक वैकल्पिक क्लॉज है जिसका मिलान किया जाता है यदि केस स्टेटमेंट में कोई भी कंटेस्टेंट मैच नहीं करता है।

अच्छा उदाहरण :-

switch(5) {
  case 1:
    echo "1";
    break;
  case 2:
  default:
    echo "2, default";
    break;
  case 3;
    echo "3";
    break;
}


Outputs '2,default'

यदि आप चाहते हैं कि आपके मामले कोड में तार्किक क्रम में प्रस्तुत किए जाएं (जैसा कि केस 1, केस 3, केस 2 / डिफॉल्ट नहीं) और आपके मामले बहुत लंबे हैं तो बहुत उपयोगी हैं इसलिए आप पूरे मामले को दोहराना नहीं चाहते हैं डिफ़ॉल्ट के लिए नीचे कोड


7
यह वास्तव में ऐसा परिदृश्य है जहां मैं आमतौर पर डिफ़ॉल्ट को अंत के अलावा कहीं और रखता हूं ... स्पष्ट मामलों (1, 2, 3) के लिए एक तार्किक आदेश है और मैं चाहता हूं कि डिफ़ॉल्ट बिल्कुल स्पष्ट मामलों में से एक के समान व्यवहार करे। पिछले एक नहीं है।
ArtOfWarfare

51

यह कुछ मामलों में मान्य और बहुत उपयोगी है।

निम्नलिखित कोड पर विचार करें:

switch(poll(fds, 1, 1000000)){
   default:
    // here goes the normal case : some events occured
   break;
   case 0:
    // here goes the timeout case
   break;
   case -1:
     // some error occurred, you have to check errno
}

मुद्दा यह है कि उपरोक्त कोड कैस्केड की तुलना में अधिक पठनीय और कुशल है if। आप defaultअंत में रख सकते हैं , लेकिन यह व्यर्थ है क्योंकि यह सामान्य मामलों के बजाय त्रुटि मामलों पर आपका ध्यान केंद्रित करेगा (जो कि यहां defaultमामला है)।

वास्तव में, यह इतना अच्छा उदाहरण नहीं है, pollआप जानते हैं कि कितनी घटनाएं घटित हो सकती हैं। मेरे असली मतलब नहीं है कि कर रहे हैं इनपुट मानों जहां 'अपवाद' और सामान्य मामले होते हैं की एक परिभाषित सेट के साथ मामलों। यदि अपवादों या सामान्य मामलों को सामने रखना बेहतर होता है, तो यह पसंद का विषय है।

सॉफ्टवेयर क्षेत्र में मुझे एक और बहुत सामान्य मामला लगता है: कुछ टर्मिनल मूल्यों के साथ पुनरावृत्ति। यदि आप इसे एक स्विच का उपयोग करके व्यक्त कर सकते हैं, defaultतो सामान्य मूल्य होगा जिसमें टर्मिनल मानों को पुनरावर्ती कॉल और प्रतिष्ठित तत्व (व्यक्तिगत मामले) शामिल हैं। आमतौर पर टर्मिनल मानों पर ध्यान देने की आवश्यकता नहीं होती है।

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

टिप्पणियों को पढ़ना यह विशिष्ट कारण है कि मूल पोस्टर ने इंटेल कंपाइलर शाखा लूप पुनर्गठन को कोड अनुकूलन के बारे में पढ़ने के बाद यह सवाल क्यों पूछा ।

फिर यह कोड पठनीयता और कोड प्रदर्शन के बीच कुछ मध्यस्थता बन जाएगा। भविष्य के पाठक को समझाने के लिए टिप्पणी डालने के लिए संभवतः बेहतर है कि कोई मामला पहले क्यों दिखाई देता है।


6
+1 व्यवहारिक व्यवहार के बिना (अच्छा) उदाहरण देने के लिए।
किलियांदस

1
... हालांकि इसके बारे में सोचकर, मुझे यकीन नहीं है कि शीर्ष पर डिफ़ॉल्ट अच्छा है, क्योंकि बहुत कम लोग वहां खोज रहे होंगे। बेहतर हो सकता है कि रिटर्न को एक वैरिएबल में असाइन किया जाए और एक के एक तरफ सफलता को हैंडल किया जाए और दूसरे स्टेटमेंट में त्रुटियों को केस स्टेटमेंट के साथ जोड़ा जाए।
जॉन केज

@Jon: बस इसे लिखें। आप किसी भी पठनीयता लाभ के बिना वाक्यविन्यास शोर जोड़ते हैं। और, यदि डिफ़ॉल्ट शीर्ष पर है, तो वास्तव में इसे देखने की कोई आवश्यकता नहीं है, यह वास्तव में स्पष्ट है (यदि आप इसे बीच में डालते हैं तो यह अधिक मुश्किल हो सकता है)।
क्रि।

वैसे मुझे वास्तव में सी स्विच / केस सिंटैक्स पसंद नहीं है। मैं एक मामले के बाद कई लेबल लगाने में सक्षम होना पसंद करूंगा, बजाय इसके कि वह एक के बाद एक कई लेबल लगाए case। जो निराशाजनक है वह यह है कि यह सिंटेक्सिक शर्करा के रूप में दिखता है और यदि समर्थित है तो किसी भी मौजूदा कोड को नहीं तोड़ेगा।
क्रि।

1
@kriss: मुझे यह कहने के लिए आधा ललचाया गया कि "मैं अजगर प्रोग्रामर भी नहीं हूँ!" :)
एंड्रयू ग्रिम

16

हां, यह मान्य है, और कुछ परिस्थितियों में यह उपयोगी भी है। आम तौर पर, अगर आपको इसकी आवश्यकता नहीं है, तो इसे न करें।


-1: इससे मुझे बदबू आती है। कोड को स्विच स्टेटमेंट की एक जोड़ी में विभाजित करना बेहतर होगा।
जॉन केज

25
@ जॉन केज: मुझे यहाँ -1 रखना बुरा है। यह मेरी गलती नहीं है कि यह वैध कोड है।
जेन्स गुस्ताद

बस जिज्ञासु, मैं जानना चाहूंगा कि यह किन परिस्थितियों में उपयोगी है?
सलिल

1
-1 आपके उपयोगी होने के दावे पर लक्षित था। यदि आप अपना दावा वापस करने के लिए एक वैध उदाहरण प्रदान कर सकते हैं तो मैं इसे +1 में बदल दूंगा।
जॉन केज

4
कभी-कभी एक ग़लती के लिए स्विच करते समय जो हमें कुछ सिस्टम फ़ंक्शन से बदले में मिलता है। कहें कि हमारे पास एक ऐसा मामला है जहां हम अच्छे के लिए जानते हैं कि हमें एक साफ निकास करना है, लेकिन इस स्वच्छ निकास को कोडिंग की कुछ पंक्तियों की आवश्यकता हो सकती है जिन्हें हम दोहराना नहीं चाहते हैं। लेकिन मान लीजिए कि हमारे पास कई अन्य विदेशी त्रुटि कोड भी हैं जिन्हें हम व्यक्तिगत रूप से संभालना नहीं चाहते हैं। मैं तयशुदा मामले में सिर्फ एक जुर्माने पर विचार करूंगा और इसे दूसरे मामले में चलाऊंगा और सफाई से बाहर निकलूंगा। मैं नहीं कहता कि आपको ऐसा करना चाहिए। यह सिर्फ स्वाद की बात है।
जेन गस्टेड

8

स्विच स्टेटमेंट में कोई परिभाषित क्रम नहीं है। आप मामलों को एक gotoलेबल की तरह नामित लेबल की तरह देख सकते हैं । लोगों के यहाँ क्या लगता है के विपरीत, मूल्य 2 के मामले में डिफ़ॉल्ट लेबल के लिए कूद नहीं है। शास्त्रीय उदाहरण के साथ समझाने के लिए, यहां डफ का उपकरण है , जो switch/caseसी के चरम सीमाओं का पोस्टर बच्चा है।

send(to, from, count)
register short *to, *from;
register count;
{
  register n=(count+7)/8;
  switch(count%8){
    case 0: do{ *to = *from++;
    case 7:     *to = *from++;
    case 6:     *to = *from++;
    case 5:     *to = *from++;
    case 4:     *to = *from++;
    case 3:     *to = *from++;
    case 2:     *to = *from++;
    case 1:     *to = *from++;
            }while(--n>0);
  }
}

4
और जो कोई भी डफ के डिवाइस से परिचित नहीं है, उसके लिए यह कोड पूरी तरह से अपठनीय है ...
किलरएनडीएस

7

एक परिदृश्य जहां मैं एक मामले के बयान के अंत के अलावा कहीं और स्थित 'डिफ़ॉल्ट' के लिए उपयुक्त समझूंगा, एक राज्य मशीन में है जहां एक अमान्य राज्य को मशीन को रीसेट करना चाहिए और आगे बढ़ना चाहिए क्योंकि यह प्रारंभिक अवस्था थी। उदाहरण के लिए:

स्विच (widget_state)
{
  डिफ़ॉल्ट: / * रेल बंद - रीसेट करें और जारी रखें * /
    विजेट_स्टेट = WIDGET_START;
    /* असफल */
  मामला WIDGET_START:
    ...
    टूटना;
  मामला WIDGET_WHATEVER:
    ...
    टूटना;
}

एक वैकल्पिक व्यवस्था, यदि एक अमान्य राज्य मशीन को रीसेट नहीं करना चाहिए, लेकिन एक अमान्य राज्य के रूप में आसानी से पहचाना जाना चाहिए:

स्विच (widget_state) { मामला WIDGET_IDLE: विजेट_ पहले से ही = 0; widget_hardware_off (); टूटना; मामला WIDGET_START: ... टूटना; मामला WIDGET_WHATEVER: ... टूटना; चूक: widget_state = WIDGET_INVALID_STATE; /* असफल */ मामला WIDGET_INVALID_STATE: विजेट_ पहले से ही = 0; widget_hardware_off (); ... "सुरक्षित" स्थिति स्थापित करने के लिए जो कुछ भी आवश्यक है वह करें }

कोड कहीं और फिर (widget_state == WIDGET_INVALID_STATE) के लिए जाँच कर सकते हैं और जो भी त्रुटि-रिपोर्टिंग या राज्य-रीसेट व्यवहार उचित लगता है प्रदान करते हैं। उदाहरण के लिए, स्थिति-बार कोड एक त्रुटि आइकन दिखा सकता है, और "प्रारंभ विजेट" मेनू विकल्प जो कि अधिकांश गैर-निष्क्रिय राज्यों में अक्षम है, को WIDGET_INVALID_STATE और WIDGET_IDLE के लिए सक्षम किया जा सकता है।


6

एक अन्य उदाहरण के साथ चिंतन करना: यह उपयोगी हो सकता है यदि "डिफ़ॉल्ट" एक अप्रत्याशित मामला है, और आप त्रुटि को लॉग इन करना चाहते हैं लेकिन कुछ समझदार भी करते हैं। मेरे अपने कोड से कुछ उदाहरण:

  switch (style)
  {
  default:
    MSPUB_DEBUG_MSG(("Couldn't match dash style, using solid line.\n"));
  case SOLID:
    return Dash(0, RECT_DOT);
  case DASH_SYS:
  {
    Dash ret(shapeLineWidth, dotStyle);
    ret.m_dots.push_back(Dot(1, 3 * shapeLineWidth));
    return ret;
  }
  // more cases follow
  }

5

ऐसे मामले हैं जब आप ENUM को एक स्ट्रिंग में परिवर्तित कर रहे हैं या किसी फ़ाइल में / से / के लिए जहाँ आप लिख / पढ़ रहे हैं, वहाँ enum में स्ट्रिंग परिवर्तित कर रहे हैं।

आपको कभी-कभी फ़ाइलों को मैन्युअल रूप से संपादित करके की गई त्रुटियों को कवर करने के लिए एक मान को डिफ़ॉल्ट बनाने की आवश्यकता होती है।

switch(textureMode)
{
case ModeTiled:
default:
    // write to a file "tiled"
    break;

case ModeStretched:
    // write to a file "stretched"
    break;
}

2

defaultहालत स्विच है कि एक मामले खंड मौजूद कर सकते हैं के भीतर कहीं हो सकता है। अंतिम उपवाक्य होना आवश्यक नहीं है। मैंने कोड देखा है जो डिफ़ॉल्ट को पहले क्लॉज के रूप में रखता है। case 2:सामान्य रूप से निष्पादित हो जाता है, भले ही डिफ़ॉल्ट खंड यह ऊपर है।

परीक्षण के रूप में, मैंने एक फ़ंक्शन में नमूना कोड डाला, बुलाया test(int value){}और भाग गया:

  printf("0=%d\n", test(0));
  printf("1=%d\n", test(1));
  printf("2=%d\n", test(2));
  printf("3=%d\n", test(3));
  printf("4=%d\n", test(4));

आउटपुट है:

0=2
1=1
2=4
3=8
4=10

1

यह मान्य है, बल्कि बुरा है। मेरा सुझाव है कि आम तौर पर फॉल-थ्रू की अनुमति देना बुरा है क्योंकि इससे कुछ बहुत गन्दा स्पेगेटी कोड हो सकता है।

इन मामलों को कई स्विच स्टेटमेंट या छोटे कार्यों में तोड़ना लगभग निश्चित रूप से बेहतर है।

[संपादित करें] @ चित्र: आपका उदाहरण:

Example from UCS-2 to UTF-8 conversion 

r is the destination array, 
wc is the input wchar_t  

switch(utf8_length) 
{ 
    /* Note: code falls through cases! */ 
    case 3: r[2] = 0x80 | (wc & 0x3f); wc >>= 6; wc |= 0x800; 
    case 2: r[1] = 0x80 | (wc & 0x3f); wc >>= 6; wc |= 0x0c0; 
    case 1: r[0] = wc;
}

यदि यह इस तरह से लिखा गया था, तो यह इरादा के रूप में स्पष्ट होगा (मुझे लगता है)

if( utf8_length >= 1 )
{
    r[0] = wc;

    if( utf8_length >= 2 )
    {
        r[1] = 0x80 | (wc & 0x3f); wc >>= 6; wc |= 0x0c0; 

        if( utf8_length == 3 )
        {
            r[2] = 0x80 | (wc & 0x3f); wc >>= 6; wc |= 0x800; 
        }
    }
}   

[ edit2 ] @ ट्रिस्टोपिया: आपका दूसरा उदाहरण संभवतः फॉलो-थ्रू के लिए एक अच्छे उपयोग का सबसे साफ उदाहरण है:

for(i=0; s[i]; i++)
{
    switch(s[i])
    {
    case '"': 
    case '\'': 
    case '\\': 
        d[dlen++] = '\\'; 
        /* fall through */ 
    default: 
        d[dlen++] = s[i]; 
    } 
}

..लेकिन व्यक्तिगत रूप से मैं टिप्पणी मान्यता को अपने कार्य में विभाजित करूंगा:

bool isComment(char charInQuestion)
{   
    bool charIsComment = false;
    switch(charInQuestion)
    {
    case '"': 
    case '\'': 
    case '\\': 
        charIsComment = true; 
    default: 
        charIsComment = false; 
    } 
    return charIsComment;
}

for(i=0; s[i]; i++)
{
    if( isComment(s[i]) )
    {
        d[dlen++] = '\\'; 
    }
    d[dlen++] = s[i]; 
}

2
ऐसे मामले हैं जहां से गुजरना वास्तव में एक अच्छा विचार है।
पैट्रिक श्ल्टर

UCS-2 से UTF-8 रूपांतरण rका उदाहरण गंतव्य सरणी wcहै, इनपुट wchar_t स्विच (utf8_length) {/ * नोट: कोड मामलों के माध्यम से गिरता है! * * केस 3: आर [2] = 0x80 | (wc & 0x3f); wc >> = 6; wc | = 0x800; केस 2: r [1] = 0x80 | (wc & 0x3f); wc >> = 6; wc | = 0xc0; केस 1: r [0] = wc; }
पैट्रिक श्ल्टर

यहाँ एक और, चरित्र से बचने के साथ एक स्ट्रिंग कॉपी रूटीन: for(i=0; s[i]; i++) { switch(s[i]) { case '"': case '\'': case '\\': d[dlen++] = '\\'; /* fall through */ default: d[dlen++] = s[i]; } }
पैट्रिक श्ल्टर

हां, लेकिन यह दिनचर्या हमारे हॉटस्पॉट्स में से एक है, इसे लागू करने का सबसे तेज, पोर्टेबल (हम असेंबली नहीं करेंगे) तरीका था। यह किसी भी UTF लंबाई के लिए केवल 1 परीक्षण है, तुम्हारा 2 या 3 है। इसके अलावा, मैं इसके साथ नहीं आया, मैंने इसे बीएसडी से लिया।
पैट्रिक श्ल्टर

1
हाँ, विशेष रूप से बल्गेरियाई और ग्रीक (सोलारिस स्पार्क पर) और हमारे आंतरिक मार्कअप (जो कि 3 बाइट UTF8 है) के साथ पाठ में रूपांतरण थे। माना जाता है, टोटो में यह बहुत ज्यादा नहीं है और हमारे पिछले हार्डवेयर अपडेट के बाद अप्रासंगिक हो गया है, लेकिन जिस समय यह लिखा गया था उससे बहुत फर्क पड़ा।
पैट्रिक श्ल्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.