int [] = {1,2,}; अजीब अल्पविराम की अनुमति दी। कोई खास वजह?


335

शायद मैं इस ग्रह से नहीं हूं, लेकिन यह मुझे प्रतीत होगा कि निम्नलिखित एक वाक्यविन्यास त्रुटि होनी चाहिए:

int a[] = {1,2,}; //extra comma in the end

लेकिन ऐसा नहीं है। जब विजुअल स्टूडियो पर इस कोड को संकलित किया गया तो मुझे आश्चर्य हुआ, लेकिन मैंने सीख लिया है कि जहां तक ​​C ++ नियमों का सवाल है, वे MSVC कंपाइलर पर भरोसा नहीं करते हैं, इसलिए मैंने मानक की जाँच की और यह मानक द्वारा भी अनुमति है। यदि आप मुझ पर विश्वास नहीं करते हैं, तो आप व्याकरण के नियमों के लिए 8.5.1 देख सकते हैं।

यहां छवि विवरण दर्ज करें

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

तो, क्या फिर से, कोई विशेष कारण यह अनावश्यक अल्पविराम स्पष्ट रूप से अनुमति है?


10
हर कोई 'नई लाइन जोड़ने में आसानी' के लिए सहमत होता दिख रहा है - लेकिन क्या भाषा के विनिर्देशों को परिभाषित करने वाले लोग वास्तव में ऐसी चीजों से परेशान हैं? यदि वे वास्तव में उस समझ को समझ रहे हैं तो वे एक लापता को अनदेखा क्यों नहीं करते हैं ;जब यह स्पष्ट है कि टोकन वास्तव में एक अगला बयान है।
येटनोथेरयूजर

35
@YetAnotherUser: हां, भाषा डिजाइनर ऐसी चीजों पर विचार करते हैं। अर्धविराम छोड़ने की अनुमति देने से बहुत बड़ा प्रभाव पड़ेगा और भाषा के कई हिस्सों में अत्यधिक अस्पष्ट होगा (याद रखें, व्हॉट्सएप सी में शब्दार्थ नहीं है)। एक अतिरिक्त अल्पविराम है यह मामला अस्पष्ट नहीं है। एक अतिरिक्त अर्धविराम लगभग कभी अस्पष्ट नहीं है, और इसलिए भी अनुमति है। इस मामले में जहां यह अस्पष्ट है ( for()उदाहरण के लिए), इसे जोड़ने पर एक संकलक चेतावनी फेंकता है।
रोब नेपियर

5
@ टोमलाक: यह एक मानवीय पाठक के लिए अस्पष्ट है, और अक्सर एक गलती है। यही कारण है कि यह एक चेतावनी फेंकता है। इसी तरह if (x = 1)व्याकरण में अस्पष्ट नहीं है, लेकिन यह मनुष्यों के लिए बहुत अस्पष्ट है, और इस तरह एक चेतावनी फेंकता है।
रोब नेपियर

12
@ रब: आपका ifउदाहरण अस्पष्ट नहीं है। मुझे नहीं लगता कि "अस्पष्ट" का अर्थ है कि आप क्या सोचते हैं इसका मतलब है!
ऑर्बिट

5
जब तक हम इस बात से सहमत होते हैं कि यह संकलक के लिए हमारी रक्षा के लिए कुछ उपयोगी है, जबकि एक सरणी घोषणा में एक अनुगामी अल्पविराम संकलक के लिए हमारी रक्षा के लिए कुछ उपयोगी नहीं है।
रोब नेपियर

जवाबों:


436

यह स्रोत कोड उत्पन्न करना आसान बनाता है, और कोड लिखने के लिए भी जिसे बाद की तारीख में आसानी से बढ़ाया जा सकता है। इस बात पर विचार करें कि अतिरिक्त प्रविष्टि जोड़ने के लिए क्या आवश्यक है:

int a[] = {
   1,
   2,
   3
};

... आपको कॉमा को मौजूदा लाइन में जोड़ना होगा और एक नई लाइन जोड़ना होगा। उस मामले से तुलना करें जहां तीनों के पास पहले से ही एक अल्पविराम है, जहां आपको बस एक पंक्ति जोड़ना है। इसी तरह यदि आप एक लाइन को हटाना चाहते हैं तो आप इस बारे में चिंता किए बिना कर सकते हैं कि यह अंतिम पंक्ति है या नहीं और आप अल्पविराम के बारे में जानकारी दिए बिना लाइनों को फिर से चालू कर सकते हैं। मूल रूप से इसका मतलब है कि आप लाइनों का इलाज कैसे करते हैं, इसमें एकरूपता है।

अब कोड बनाने के बारे में सोचें। कुछ इस तरह (छद्म कोड):

output("int a[] = {");
for (int i = 0; i < items.length; i++) {
    output("%s, ", items[i]);
}
output("};");

इस बात की चिंता करने की ज़रूरत नहीं है कि आप जो वर्तमान आइटम लिख रहे हैं, वह पहला है या अंतिम। बहुत सरल।


89
इसके अलावा, VCS का उपयोग करते समय, दो संस्करणों के बीच "अंतर" क्लीनर होता है क्योंकि किसी आइटम को जोड़ने या हटाने पर केवल एक पंक्ति बदल जाती है।
केविन पेंको

47
@ नेस्टर: "दुर्भाग्यपूर्ण" क्यों? यहाँ क्या नकारात्मक है? सिर्फ इसलिए कि भाषा के एक छोटे हिस्से के लिए कोड जनरेशन (और आसान हेरफेर) के लिए कुछ विचार दिया गया है, इसका मतलब यह नहीं है कि भाषा के सभी निर्णयों के पीछे प्राथमिक प्रेरणा होनी चाहिए। टाइप इंफ़ेक्शन, अर्ध-कॉलनों को हटाने आदि का भाषा के लिए बहुत बड़ा प्रभाव है। आप एक गलत द्वंद्ववाद यहाँ स्थापित कर रहे हैं, IMO।
जॉन स्कीट

18
@ नेस्टर: यह वह जगह है जहाँ व्यावहारिकता ने डैमेटिज़्म पर जीत हासिल की है: यह पूरी तरह से एक चीज या पूरी तरह से दूसरे से क्यों होना है , जब दोनों का मिश्रण होना अधिक उपयोगी है? यह वास्तव में कैसे प्राप्त करता है, अंत में अल्पविराम जोड़ने में सक्षम है? क्या यह एक असंगति है जिसने आपको कभी भी किसी भी अर्थ में बाधित किया है? यदि नहीं, तो कृपया अंत में अल्पविराम की अनुमति के व्यावहारिक लाभों के खिलाफ उस अप्रासंगिक असमानता को तौलना चाहिए ।
जॉन स्कीट

8
@ शरारत: यह टाइपिंग रेट की बात नहीं है - वस्तुओं को कॉपी करते, निकालते या रीरोड करते समय यह सरलता की बात है। इसने कल ही मेरे जीवन को सरल बना दिया। कोई नकारात्मक पक्ष के साथ, जीवन को आसान क्यों नहीं बनाते हैं? जैसा कि एमएस पर उंगली उठाने की कोशिश करने के लिए, मुझे संदेह है कि यह सी में माइक्रोसॉफ्ट के अस्तित्व में आने से पहले से ही है ... आप कहते हैं कि यह औचित्य अजीब लगता है, लेकिन मुझे यकीन है कि यह हर एक दिन सैकड़ों कंपनियों के हजारों डेवलपर्स को फायदा पहुंचाता है। संकलक लेखकों को लाभ पहुंचाने वाली किसी चीज़ की तलाश से बेहतर स्पष्टीकरण नहीं है?
जॉन स्कीट

6
यह K & R C. में था
फेर्रुकियो

126

यदि आप ऐसा कुछ करते हैं तो यह उपयोगी है:

int a[] = {
  1,
  2,
  3, //You can delete this line and it's still valid
};

6
जावास्क्रिप्ट इस सिंटैक्स का समर्थन करता है: var a = [1, 2,];इसलिए मुझे पता है कि ज्यादातर अन्य भाषाएँ ... ActionScript, Python, PHP।
सीन फुजिवारा

14
@ सीन आईई जावास्क्रिप्ट में एक पार्स त्रुटि का कारण होगा, इसलिए सावधान रहें!
10

10
यह IE9 में मेरे लिए नहीं है। लेकिन यह कुछ अजीब करता है ... यह एक अशक्त तत्व बनाता है। मैं खबरदार रहूँगा।
सीन फुजिवारा

5
@Sean क्षमा करें, आप सही कर रहे हैं - यह IE में एक पार्स त्रुटि नहीं है, लेकिन यह होगा के लिए एक अतिरिक्त तत्व सेट सम्मिलित undefined
स्किलड्रिक

3
अधिकांश निराशा की बात है कि JSON इस वाक्य-विन्यास का समर्थन नहीं करता है।
टिम्मम्म

38

डेवलपर के लिए उपयोग में आसानी, मुझे लगता है।

int a[] = {
            1,
            2,
            2,
            2,
            2,
            2, /*line I could comment out easily without having to remove the previous comma*/
          }

इसके अतिरिक्त, यदि किसी कारण से आपके पास एक उपकरण है जो आपके लिए कोड उत्पन्न करता है; टूल को इस बात की परवाह नहीं है कि यह इनिशियलाइज़ का आखिरी आइटम है या नहीं।


32

मैंने हमेशा यह मान लिया है कि अतिरिक्त तत्वों को जोड़ना आसान बनाता है:

int a[] = {
            5,
            6,
          };

बस बन जाता है:

int a[] = { 
            5,
            6,
            7,
          };

बाद की तारीख पर।


3
मुझे नहीं लगता कि थोड़ी तेजी से संपादन करना वाक्यविन्यास को गड़बड़ाने का एक अच्छा कारण है। IMHO यह सिर्फ एक और अजीब सी ++ सुविधा है।
जियोर्जियो

3
@ जियोर्जियो: खैर, यह सी से विरासत में मिला है। यह पूरी तरह से संभव है कि यह मूल भाषा विनिर्देश में एक ओवरसाइट है, जो एक उपयोगी साइड-इफेक्ट होता है।
ओलिवर चार्ल्सवर्थ

ठीक है, मुझे नहीं पता था कि यह सी से आता है। मैंने अभी चेक किया है कि यह जावा में भी अनुमति है। हालांकि यह अजीब लगता है: मेरे अंतर्ज्ञान में अल्पविराम एक विभाजक है न कि एक टर्मिनेटर। इसके अलावा, अंतिम अल्पविराम को छोड़ना संभव है। तो, क्या यह एक टर्मिनेटर, एक विभाजक या दोनों है? लेकिन ठीक है, यह सुविधा उपलब्ध है और यह जानना अच्छा है।
जियोर्जियो

11
@ जिओर्जियो - सोर्स कोड इंसानों के लिए है, मशीनों के लिए नहीं। इस तरह की छोटी चीजें हमें सरल ट्रांसपोजिशन त्रुटियां करने से बचाए रखने के लिए एक आशीर्वाद हैं, एक निरीक्षण नहीं। संदर्भ के लिए, यह PHP और ECMAScript (और इसलिए जावास्क्रिप्ट और एक्शनस्क्रिप्ट) में भी काम करता है, हालांकि यह जावास्क्रिप्ट ऑब्जेक्ट नोटेशन (JSON) में अमान्य है (जैसे [1,2,3,]ठीक है, लेकिन {a:1, b:2, c:3,}नहीं है)।
डेरेलिज्ड

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

21

सब कुछ लाइनों को जोड़ने / हटाने / बनाने में आसानी के बारे में कह रहा है, सही है, लेकिन वास्तविक वाक्य विन्यास इस चमकता है जब एक साथ फ़ाइलों को विलय कर रहा है। कल्पना कीजिए कि आपको यह सरणी मिली है:

int ints[] = {
    3,
    9
};

और मान लें कि आपने इस कोड को एक रिपॉजिटरी में जाँच लिया है।

फिर आपका दोस्त इसे संपादित करता है, अंत में जोड़ रहा है:

int ints[] = {
    3,
    9,
    12
};

और आप एक साथ इसे संपादित करते हैं, शुरुआत में जोड़ते हैं:

int ints[] = {
    1,
    3,
    9
};

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

इसलिए, मेरे अंगूठे का नियम है: यदि दूसरी पंक्ति में सूची एक ही पंक्ति में है, तो अनुगामी अल्पविराम का उपयोग करें यदि सूची एकल पंक्ति में है, तो इसका उपयोग न करें।


15

ट्रेलिंग कॉमा मुझे विश्वास है कि पिछड़े संगतता कारणों के लिए अनुमति दी गई है। मौजूदा कोड का एक बहुत कुछ है, मुख्य रूप से ऑटो-जनरेट किया गया है, जो एक अनुगामी अल्पविराम लगाता है। अंत में विशेष स्थिति के बिना लूप लिखना आसान बनाता है। जैसे

for_each(my_inits.begin(), my_inits.end(),
[](const std::string& value) { std::cout << value << ",\n"; });

प्रोग्रामर के लिए वास्तव में कोई फायदा नहीं है।

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


5
मैं पूरी तरह से असहमत हूं; [यह मेरी राय है कि] इसने सी के ठीक बाद लंबे समय तक बनाई गई कई भाषाओं में अपना रास्ता खोज लिया है क्योंकि यह प्रोग्रामर के लिए फायदेमंद है कि वह एरे के कंटेंट के आसपास शिफ्ट होने में सक्षम हो, लाइन्स विली-नीली को कमेंट करे, और इसी तरह, मूर्खतापूर्ण प्रेरित प्रेरित वाक्यविन्यास त्रुटियों के बारे में चिंता किए बिना। क्या हम पहले से ही पर्याप्त तनाव में नहीं हैं?
डेरेलिज्ड

12
@Dereleased - एक ही तर्क से, अनुगामी (कुछ भी) की अनुमति क्यों नहीं दी जानी चाहिए, कैसे के बारे में int a = b + c +;या if(a && b &&);अंत में कुछ भी कॉपी-पेस्ट करना आसान होगा और कोड जनरेटर लिखना आसान होगा। यह मुद्दा दोनों तुच्छ और व्यक्तिपरक है, ऐसे मामलों में यह हमेशा अच्छा होता है कि कोड रीडर के लिए सबसे अच्छा क्या है।
जीन बुशुइव

1
@ गेन बुशुयेव: बिल्कुल! मेरे पास अक्सर लाइन के अंत में ऑपरेटर के साथ + या && के साथ लंबे अभिव्यक्ति होते हैं, और निश्चित रूप से, मुझे कुछ अतिरिक्त समय बिताना होगा, जब मैं अभिव्यक्ति के अंतिम संचालन को निकालना चाहता हूं। मुझे लगता है कि यह अल्पविराम वाक्य रचना वास्तव में विषम है!
जियोर्जियो

2
@GeneBushuyev - मैं उन पर असहमत हूं। सरणियों में अनुगामी अल्पविराम की तरह अनुमति देना और एक बग हटाने वाली विशेषता है और प्रोग्रामर के रूप में आपके जीवन को आसान बनाता है, मैं विशुद्धता के लिए अनुगामी और (&&) कथनों को हटाने के लिए उपाय करूंगा, और अन्य सशर्त परिचालकों को सशर्त बयान। यह सीधे सादे बदसूरत, IMO है।
सून रासमुसेन

2
&&ऑपरेटर के बारे में , कभी-कभी मैं सशर्त काम if (true \n && b1 \n && b2)करता हूं ताकि मैं लाइनों को जोड़ सकूं और हटा सकूं क्योंकि मुझे जरूरत है।
क्रिश्चियन मान

12

जहां तक ​​मुझे पता है कि इसकी एक वजह यह है कि यह स्वचालित रूप से कोड उत्पन्न करने के लिए सरल होना चाहिए; आपको अंतिम तत्व के लिए किसी विशेष हैंडलिंग की आवश्यकता नहीं है।


11

यह कोड जनरेटर बनाता है जो सरणियों या गणना को आसान बनाता है।

कल्पना कीजिए:

std::cout << "enum Items {\n";
for(Items::iterator i(items.begin()), j(items.end); i != j; ++i)
    std::cout << *i << ",\n";
std::cout << "};\n";

यानी, अनुगामी अल्पविराम के थूकने से बचने के लिए पहले या अंतिम आइटम की विशेष हैंडलिंग करने की कोई आवश्यकता नहीं है।

यदि कोड जनरेटर पायथन में लिखा गया है, उदाहरण के लिए, str.join()फ़ंक्शन का उपयोग करके अनुगामी अल्पविराम थूकने से बचना आसान है :

print("enum Items {")
print(",\n".join(items))
print("}")

10

मैं इस सब के बाद आश्चर्यचकित हूं कि किसी ने एनोटेट C ++ रेफरेंस मैनुअल ( ARM ) को उद्धृत नहीं किया है , यह निम्नलिखित के बारे में कहता है [dcl.init] जोर देने के साथ:

प्रारंभ के लिए स्पष्ट रूप से बहुत सारी सूचनाएं हैं, लेकिन प्रत्येक अच्छी तरह से उपयोग की एक विशेष शैली की सेवा करता है। The = {initializer_list, opt} संकेतन C से विरासत में मिला था और डेटा संरचनाओं और सरणियों के आरंभ के लिए अच्छी तरह से कार्य करता है। [...]

हालांकि व्याकरण विकसित हुआ है क्योंकि एआरएम को लिखा गया था कि मूल अवशेष है।

और हम C99 के औचित्य पर जा सकते हैं यह देखने के लिए कि C में इसकी अनुमति क्यों थी और यह कहता है:

K & R एक इनिशियलाइज़र-सूची के अंत में एक इनिलाइज़र में एक अनुगामी अल्पविराम की अनुमति देता है। स्टैंडर्ड ने इस सिंटैक्स को बनाए रखा है, क्योंकि यह एक इनिशियलाइज़र सूची से सदस्यों को जोड़ने या हटाने में लचीलापन प्रदान करता है, और इस तरह की सूचियों के मशीन निर्माण को सरल करता है।


1
साहित्य द्वारा सबसे अधिक समर्थित उत्तर और इस सुविधा के सही स्रोत के लिए अपवोट करें।
मार्को

10

मैं एक उपयोग का मामला देखता हूं जिसका अन्य उत्तरों में उल्लेख नहीं किया गया था, हमारा पसंदीदा मैक्रोज़:

int a [] = {
#ifdef A
    1, //this can be last if B and C is undefined
#endif
#ifdef B
    2,
#endif
#ifdef C
    3,
#endif
};

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


7

एकमात्र भाषा जहां यह है - व्यवहार में * - अनुमति नहीं है जावास्क्रिप्ट है, और यह समस्याओं की एक असंख्य राशि का कारण बनता है। उदाहरण के लिए यदि आप सरणी के मध्य से एक पंक्ति को कॉपी और पेस्ट करते हैं, तो इसे अंत में पेस्ट करें, और अल्पविराम को हटाने के लिए भूल गए तो आपकी साइट आपके IE आगंतुकों के लिए पूरी तरह से टूट जाएगी।

* सिद्धांत रूप में इसकी अनुमति है लेकिन इंटरनेट एक्सप्लोरर मानक का पालन नहीं करता है और इसे त्रुटि के रूप में मानता है


जावास्क्रिप्ट की "सरणियाँ" (जो एक जादुई लंबाई की संपत्ति वाली वस्तुएं हैं) वैसे भी असामान्य हैं: var x = [,,,]कानूनी है (IE <9 को छोड़कर, लेकिन कल्पना यह कानूनी है)
पीटर सी

ECMAScript विनिर्देश के अनुसार, यह पूरी तरह से मान्य है; सिद्धांत रूप में, यह किसी भी ब्राउज़र में काम करना चाहिए जो उक्त विनिर्देश के अनुसार जावास्क्रिप्ट को लागू करता है, विशेष रूप से यहाँ पाए गए विनिर्देश का हिस्सा
डेरेलिज्ड

1
दुर्भाग्य से जावास्क्रिप्ट जनता के लिए ऐप बनाने के बारे में है। तो नहीं, यह पूरी तरह से मान्य नहीं है जब ~ 50% उपयोगकर्ताओं को आपके ऐप का उपयोग करने में समस्या होगी। और हां, अगर मैं IE <9 पर प्रतिबंध लगा सकता हूं - तो वहां काम करने वाले अच्छे कोड बनाने में बस बहुत अधिक घंटे खर्च होते हैं ...
kgadek

@ डेरे: हाँ, मैंने अपने उत्तर में उतना ही कहा =)
थॉमस

@Dereleased microsoft अपने स्वयं के विनिर्देशों को लागू करता है और आदेश देता है कि अन्य कम से कम उस मानसिकता को बदल रहे हैं (भगवान का शुक्र है)
Chris McGrath

7

यह मशीनों के लिए आसान है, यानी पार्सिंग और कोड की पीढ़ी। यह मनुष्यों के लिए भी आसान है, यानी संशोधन के माध्यम से, टिप्पणी-आउट और दृश्य-लालित्य।

सी मानकर, आप निम्नलिखित लिखेंगे?

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    puts("Line 1");
    puts("Line 2");
    puts("Line 3");

    return EXIT_SUCCESS
}

न केवल क्योंकि अंतिम कथन एक त्रुटि है, बल्कि इसलिए भी क्योंकि यह असंगत है। तो क्यों संग्रह करने के लिए एक ही है? यहां तक ​​कि भाषाओं में जो आपको अंतिम अर्धविराम और अल्पविराम को छोड़ने की अनुमति देते हैं, समुदाय आमतौर पर इसे पसंद नहीं करता है। पर्ल समुदाय, उदाहरण के लिए, अर्धविराम, बार वन-लाइनर्स को छोड़ना पसंद नहीं करता है। वे लागू होते हैं कि अल्पविराम के लिए भी।

बहु-संग्रह में अल्पविरामों को एक ही कारण से न छोड़ें क्योंकि आप कोड के मल्टीलाइन ब्लॉकों के लिए अर्धविराम नहीं लगाते हैं। मेरा मतलब है, अगर भाषा ने अनुमति दी तो भी आप ऐसा नहीं करेंगे, है ना? सही?


ऐसी भाषाएँ हैं (जैसे पास्कल) जो इसकी अनुमति देती हैं। यानी आपको बीच में से चुनना होगा; एक टर्मिनेटर (C) या एक विभाजक (पास्कल) के रूप में। ',' के लिए भी। यह मेरे लिए ठीक होगा यदि ',' एक टर्मिनेटर है, लेकिन फिर {1, 2, 3} एक वाक्यविन्यास त्रुटि होनी चाहिए।
जियोर्जियो

6

कारण तुच्छ है: लाइनों को जोड़ने / हटाने में आसानी।

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

int a[] = {
   1,
   2,
   //3, // - not needed any more
};

अब, आप आसानी से सूची में वस्तुओं को जोड़ / हटा सकते हैं, कभी-कभी अनुगामी अल्पविराम जोड़ / हटा सकते हैं।

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


6

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


5

यह एक लंबी सूची में तत्वों को घूमने से होने वाली गलतियों से बचाने के लिए है।

उदाहरण के लिए, मान लें कि हमारे पास इस तरह दिखने वाला एक कोड है।

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Super User",
        "Server Fault"
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

और यह बहुत अच्छा है, क्योंकि यह स्टैक एक्सचेंज साइटों की मूल त्रयी दिखाता है।

Stack Overflow
Super User
Server Fault

लेकिन इसके साथ एक समस्या है। आप देखते हैं, इस वेबसाइट पर पाद सुपर सर्वर से पहले सर्वर फॉल्ट दिखाता है। बेहतर है कि किसी को नोटिस करने से पहले।

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Server Fault"
        "Super User",
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

आखिरकार, चारों ओर चलती रेखाएं इतनी कठिन नहीं हो सकती हैं, क्या यह हो सकती है?

Stack Overflow
Server FaultSuper User

मुझे पता है, "सर्वर फॉल्टसुपर उपयोगकर्ता" नामक कोई वेबसाइट नहीं है, लेकिन हमारे संकलक का दावा है कि यह मौजूद है। अब, मुद्दा यह है कि सी में एक स्ट्रिंग समवर्ती सुविधा है, जो आपको दो दोहरे उद्धृत तार लिखने की अनुमति देता है और कुछ भी नहीं का उपयोग करके उन्हें समाहित करता है (समान मुद्दा पूर्णांक के साथ भी हो सकता है, क्योंकि -संकेत के कई अर्थ हैं)।

अब क्या होगा अगर मूल सरणी के अंत में एक बेकार अल्पविराम था? ठीक है, लाइनों को चारों ओर ले जाया जाएगा, लेकिन ऐसा बग नहीं हुआ होगा। अल्पविराम के रूप में कुछ याद करना आसान है। यदि आपको हर एरे तत्व के बाद अल्पविराम लगाना याद है, तो ऐसा बग नहीं हो सकता। आप कुछ डिबगिंग में चार घंटे बर्बाद नहीं करना चाहेंगे, जब तक आप पाएंगे कि अल्पविराम आपकी समस्याओं का कारण है


4

कई चीजों की तरह, एक सरणी इनिशलाइज़र में अनुगामी अल्पविराम उन चीज़ों में से एक है जो C ++ को C से विरासत में मिला है (और हमेशा के लिए समर्थन करना होगा)। यहाँ रखे गए लोगों से बिल्कुल अलग नज़र आने वाली किताब "डीप सी सीक्रेट्स" का उल्लेख है ।

एक से अधिक "अल्पविराम विरोधाभास" के साथ एक उदाहरण के बाद:

char *available_resources[] = {
"color monitor"           ,
"big disk"                ,
"Cray"                      /* whoa! no comma! */
"on-line drawing routines",
"mouse"                   ,
"keyboard"                ,
"power cables"            , /* and what's this extra comma? */
};

हमने पढ़ा :

... कि अंतिम इनिशियलाइज़र के बाद अल्पविराम अनुगामी टाइपो नहीं है, लेकिन अभिरुचि सी से लिया गया सिंटैक्स में एक धब्बा है । इसकी उपस्थिति या अनुपस्थिति की अनुमति है लेकिन इसका कोई महत्व नहीं है । ANSI C तर्क में दावा किया गया औचित्य यह है कि यह C की स्वचालित पीढ़ी को आसान बनाता है। यह दावा अधिक विश्वसनीय होगा यदि अनुगामी अल्पविरामों को प्रत्येक अल्पविराम-सीपा-रेटेड सूची में अनुमति दी जाती है , जैसे कि एनम घोषणा में, या एक ही घोषणा में कई चर घोषणाकर्ता। वो नहीं हैं।

... मेरे लिए यह अधिक समझ में आता है


2
इस enumमामले में अल्पविराम के खिलाफ निषेध कुछ दिलचस्प है, क्योंकि यही वह मामला है जहाँ लापता अल्पविराम कम से कम अस्पष्टता प्रकट करेगा। दिया हुआ struct foo arr[] = {{1,2,3,4,5}, {3,4,5,6,7}, }; दो समझदार अर्थ हैं जो भाषा असाइन कर सकती है: एक दो-तत्व सरणी बनाएं, या एक तीन-तत्व सरणी बनाएं जहां अंतिम आइटम डिफ़ॉल्ट मान है। यदि सी ने बाद की व्याख्या को अपनाया था, तो मैं enum foo {moe, larry, curly, };इस सिद्धांत पर मना कर सकता था कि कथन लिखने के लिए केवल एक ही तरीका हो (अल्पविराम के बिना), लेकिन ...
सुपरकैट

1
... यह देखते हुए कि सी एक ऐसे मामले में अल्पविराम की अनदेखी करने के लिए तैयार है जहां यह यथोचित हो सकता है (लेकिन नहीं था) को एक महत्वपूर्ण अर्थ सौंपा गया है (जो इसे मना करने के पक्ष में एक मजबूत तर्क होगा) यह उत्सुक है कि यह isn है एक ऐसे मामले में तैयार नहीं है, जहां अल्पविराम का एक अर्थ नहीं हो सकता है [भले ही किसी के enum foo {moe,,larry,curly,};बीच संख्या को स्किप करने के रूप में व्याख्या की गई हो , moeऔर larryआमतौर पर यह कोई फर्क नहीं पड़ता कि क्या अनुगामी अल्पविराम संसाधित या अनदेखा किया गया था। एकमात्र मामला जहां यह मामला हो सकता है यदि अंतिम आइटम अपने घोषित प्रकार के लिए अधिकतम मूल्य था, और वह ...
सुपरकैट

1
... बस यह कहकर नियंत्रित किया जा सकता है कि अंतिम निर्दिष्ट गणना मूल्य के बाद होने वाले अतिप्रवाह को अनदेखा किया जाना चाहिए।
सुपरकैट

@supercat C # की तरह भाषाएं भी हैं, जहां IDE सुविधाओं और एकीकरण पर विचार करते समय एक प्राथमिक डिजाइन अनुसंधान चला जाता है, जब भाषा को समर्पित किया जाता है। C इन भाषाओं में से एक नहीं थी (और हो भी नहीं सकती थी)।
निकोस अथानासीउ

यहां तक ​​कि C # जैसी भाषाओं के साथ, डिजाइन के उद्देश्यों को बदलने से कुछ बहुत ही गंभीर डिजाइन असंगतियां हुई हैं। उदाहरण के लिए, सामान्य तरीकों और ऑपरेटरों (भले ही अंतर्निहित ढांचा इसका समर्थन कर सकता है) के लिए किसी भी प्रकार के रिटर्न-टाइप ओवरलोडिंग का समर्थन करने से भाषा बच गई, क्योंकि इसे एक सरल-संकलन भाषा के लक्ष्य के विपरीत देखा गया था, लेकिन लैम्ब्डा मूल्यांकन में प्रकार के निष्कर्ष नियम शामिल हैं जिनका संकल्प एनपी-पूर्ण है। नए तरीके / ऑपरेटर को ओवरलोड करने के नियमों को जोड़ने से मौजूदा कोड टूट सकता है (हालांकि मुझे लगता है कि अच्छे नियम इस तरह के खतरे को कम कर सकते हैं) ...
supercat

2

कोड जनरेशन और एडिटिंग आसानी के अलावा, यदि आप पार्सर को लागू करना चाहते हैं, तो इस प्रकार का व्याकरण सरल और लागू करने में आसान है। C # इस नियम का कई स्थानों पर अनुसरण करता है कि एक enumपरिभाषा में आइटम की तरह अल्पविराम से अलग वस्तुओं की सूची है ।


1

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

#define LIST_BEGIN int a[] = {
#define LIST_ENTRY(x) x,
#define LIST_END };

उपयोग:

LIST_BEGIN
   LIST_ENTRY(1)
   LIST_ENTRY(2)
LIST_END

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

#define LIST_LAST_ENTRY(x) x

और यह उपयोग करने के लिए बहुत अजीब होगा।


0

ताकि जब दो लोग अलग-अलग शाखाओं की सूची में एक नया आइटम जोड़ते हैं, तो Git परिवर्तनों को ठीक से मर्ज कर सकता है, क्योंकि Git एक लाइन के आधार पर काम करता है।


-4

यदि आप निर्दिष्ट लंबाई के बिना किसी सरणी का उपयोग करते हैं, तो VC ++ 6.0 स्वचालित रूप से इसकी लंबाई की पहचान कर सकता है, इसलिए यदि आप "int [a] = {1,2,};" का उपयोग करते हैं, तो a की लंबाई 3 है, लेकिन अंतिम एक hasn ' टी को इनिशियलाइज़ किया गया है, आप "cout <" का उपयोग कर सकते हैं


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