सारांश
यह पाठ पाठ्यक्रम की आठवीं और अंतिम इकाई खोलता है, जो बड़े प्रोग्रामों को समर्पित है। यह इकाई का प्रयोजन बताता है: ऐसे प्रोग्रामों को संगठित करना, सत्यापित करना और डिबग करना जो अब न एक फ़ाइल में समाते हैं, न दिमाग़ में; इसके तीन पाठों और उन्हें जोड़ने वाले सूत्र को प्रस्तुत करता है, जो पाठ्यक्रम के पहले पाठ में खुले चक्र (विनिर्देश, निर्माण, सत्यापन) को पूरा करता है; उसे याद दिलाता है जिसे इकाई ज्ञात मानती है, यानी पूरे पाठ्यक्रम को; वह समस्या सामने रखता है जिसे इकाई हल करती है, यानी एक ही फ़ाइल वाले ऐसे प्रोग्राम की समस्या जो उन आँकड़ों के साथ ठीक चलता है जिनसे उसका परीक्षण किया गया और अपने विनिर्देश की सीमा पर छिपी एक त्रुटि के बारे में चुप रहता है; परीक्षण करने और सिद्ध करने के अंतर का पूर्वाभास देता है; और दिखाता है कि इकाई कहाँ ले जाती है, अंतिम परियोजना तक और C++ में प्रोग्रामिंग II पाठ्यक्रम तक।
अधिगम उद्देश्य
- इकाई की विषय-वस्तु के क्रम का वर्णन करना और समझाना कि हर पाठ अपने बाद वाले पाठ को क्या देता है।
- एक उदाहरण के साथ याद करना कि किसी फ़ंक्शन को घोषित करने और परिभाषित करने में क्या अंतर है, उसे निर्दिष्ट करने वाला अनुबंध क्या है, और कौन-से चरण (कंपाइलेशन और लिंकिंग) कई फ़ाइलों को एक प्रोग्राम में बदलते हैं।
- एक उदाहरण के साथ पूर्वाभास पाना कि किसी प्रोग्राम का कुछ मामलों से परीक्षण करने और यह सिद्ध करने में कि वह सभी स्वीकार्य मामलों के लिए सही है, क्या अंतर है।
- पहचानना कि इकाई और पाठ्यक्रम पूरा करने पर क्या कर पाना अपेक्षित है, और उसे उससे अलग करना जो C++ में प्रोग्रामिंग II में सीखा जाएगा।
प्रवेश मूल्यांकन
इकाई शुरू करने से पहले आरंभ-बिंदु को माप लेना उपयोगी है। इस मूल्यांकन में अंक नहीं दिए जाते: यह अध्ययन को दिशा देता है। पहले सात प्रश्न उसे जाँचते हैं जिसे इकाई ज्ञात मानती है (घोषणा और परिभाषा, पूर्व-शर्त, इकाई 6 के किसी फ़ंक्शन का अनुबंध, लिंकर के संदेश, द्विआधारी खोज के मामले, ट्रेस तालिका और वेक्टर के बाहर पढ़ना); उसके बाद के तीन प्रश्न, पाठों के क्रम से, इकाई के केंद्रीय विचारों को छूते हैं, और उनमें “मुझे अभी नहीं पता” एक ईमानदार उत्तर है। हर उत्तर बात को समझाता है और उस पाठ का नाम बताता है जो उसे पढ़ाता है; यही कौशल सारांश वाले पाठ में फिर से मापे जाते हैं।
इकाई शुरू करने से पहले अपना आरंभ बिंदु मापें। यह एक छोटा स्व-मूल्यांकन है: इस पर अंक नहीं दिए जाते और इसका परिणाम केवल आपके ब्राउज़र में रहता है।
प्रश्न 1पिछली इकाइयों से
mainसे पहले लिखी गई पंक्तिint gcd(int a, int b);क्या करती है?घोषणा और परिभाषा को मिला देता है: बॉडी के बिना निष्पादित करने को कुछ नहीं है, और कोई भी फ़ंक्शन लिखे होने से नहीं, बल्कि कॉल किए जाने पर निष्पादित होता है।घोषित करने को कॉल करने से मिला देता है: कॉल में पैरामीटरों के प्रकार नहीं लिखे जाते।यह अनदेखा करता है कि कंपाइलर को किसी कॉल की जाँच के लिए सिग्नेचर काफ़ी है; बॉडी का न होना, अगर कोई उसे न लिखे, कंपाइलर नहीं बल्कि लिंकर पकड़ता है।घोषणा इतनी होती है कि कंपाइलर हर कॉल की जाँच कर सके; परिभाषा, बॉडी के साथ, नीचे कहीं या किसी दूसरी फ़ाइल में हो सकती है। पूरा पाठ कई फ़ाइलें और अपनी लाइब्रेरी इसी अलगाव पर टिका है: हेडर घोषित करता है, कार्यान्वयन फ़ाइल परिभाषित करती है।दोहराएँ: फ़ंक्शन
प्रश्न 2पिछली इकाइयों सेफ़ंक्शन
toBase(n, base)की पूर्व-शर्त है “n >= 0और2 <= base <= 10”। इसकी गारंटी किसे देनी चाहिए?पूर्व-शर्त को इनपुट के सत्यापन से मिला देता है: इनपुट का सत्यापन प्रोग्राम की सीमा का काम है, हर फ़ंक्शन का नहीं।मानता है कि टिप्पणियों की जाँच होती है; कंपाइलर उन्हें छोड़ देता है।यह नहीं देखता कि अनुबंध दायित्व बाँटता है; उसके बिना, जब कुछ बिगड़ता है तो कोई नहीं जानता कि ग़लती किसकी है।पूर्व-शर्त अनुबंध का वह हिस्सा है जो कॉल करने वाले को बाँधता है; बदले में फ़ंक्शन अपनी पश्च-शर्त की गारंटी देता है। अगर पूर्व-शर्त का उल्लंघन हो, तो फ़ंक्शन कुछ भी वादा नहीं करता। पाठ प्रोग्रामों का परीक्षण सिखाएगा कि प्रोग्राम विकसित होते समय इसेassertसे कैसे जाँचा जाए।दोहराएँ: फ़ंक्शन
प्रश्न 3पिछली इकाइयों सेपाठ 6.4 का फ़ंक्शन
binarySearch(values, target)targetकी कोई एक स्थिति लौटाता है, या वह न हो तोvalues.size()। इसकी पूर्व-शर्त क्या है?रिक्त वेक्टर के साथ लूप एक भी चक्कर नहीं लगाता और फ़ंक्शन 0 लौटाता है, जोvalues.size()है: यह स्थिति पश्च-शर्त में शामिल है।फ़ंक्शन अनुपस्थिति की सूचना देता है; उपस्थिति की माँग उसे बेकार कर देगी।दोहराव होने पर फ़ंक्शन उस मान की स्थितियों में से एक लौटाता है, और पश्च-शर्त इसकी अनुमति देती है।हर चक्कर बीच वाले अवयव से तुलना करके अंतराल का आधा हिस्सा छोड़ देता है, और यह तभी वैध है जब वेक्टर क्रमबद्ध हो। बिना क्रम वाले आँकड़ों पर फ़ंक्शन, बिना किसी चेतावनी के, कुछ ग़लत उत्तर देता है। पूर्व-शर्त अनुबंध में लिखी जाती है, जहाँ कॉल करने वाला उसे देखता है।दोहराएँ: खोजना और क्रमबद्ध करना
प्रश्न 4पिछली इकाइयों सेएक प्रोग्राम बिना त्रुटियों के कंपाइल होता है, और एक्ज़ीक्यूटेबल बिल्ड करते समय
undefined reference to `tetrahedral(int)'दिखता है। कौन-सा चरण विफल हुआ?कंपाइलर के संदेशों को, जो एक फ़ाइल और एक पंक्ति बताते हैं, लिंकर के संदेशों से, जो ऑब्जेक्ट फ़ाइलें और नाम बताते हैं, अलग नहीं करता।प्रोग्राम अस्तित्व में आया ही नहीं: एक्ज़ीक्यूटेबल के बिना निष्पादन नहीं होता।#includeके न होने से कंपाइल करते समयwas not declared in this scopeआता है, यह संदेश नहीं।कंपाइलर ने हर कॉल स्वीकार कर ली क्योंकि उसने एक घोषणा देखी थी; लिंकर ने सभी ऑब्जेक्ट फ़ाइलों और लाइब्रेरियों में परिभाषा खोजी, और वह नहीं मिली। पाठ कई फ़ाइलें और अपनी लाइब्रेरी इसके सामान्य कारण समझाता है: कोई फ़ाइल जो कंपाइल नहीं हुई, या किसी दूसरे प्रकार के साथ नक़ल की गई घोषणा।दोहराएँ: प्रोग्राम, कंपाइलर और C++
प्रश्न 5पिछली इकाइयों सेमामलों के इन समूहों में से कौन-सा द्विआधारी खोज को सबसे अच्छी तरह परखता है?
मात्रा को व्याप्ति से मिला देता है: अनुपस्थिति और सीमाओं को कभी नहीं परखता, जहाँ आम तौर पर त्रुटियाँ होती हैं।जो मामला पहले ही पास हो चुका है, उससे कुछ नया पता चलने की संभावना सबसे कम है।वे अनंत हैं, या प्रकार की सीमाओं के भीतर भी खगोलीय संख्या में हैं: परीक्षण के लिए चुनना ज़रूरी है।हर मामला अंतराल की एक अलग सीमा को परखता है: शुरू से ही रिक्त अंतराल, एक अवयव तक सिमटने वाला अंतराल, दोनों सिरे, और मान के न होने के तीन तरीक़े। मामलों को विनिर्देश से, प्रदेशों और सीमाओं के अनुसार चुनना, पाठ प्रोग्रामों का परीक्षण का विषय है।दोहराएँ: खोजना और क्रमबद्ध करना
प्रश्न 6पिछली इकाइयों से
int a{0}; int b{1}; for (int i{0}; i < 4; ++i) { const int t{a + b}; a = b; b = t; }के बादaऔरbके मान क्या हैं?एक चक्कर ज़्यादा गिनता है:i < 4के साथ बॉडी चार बार निष्पादित होती है, पाँच बार नहीं।एक चक्कर कम गिनता है, जो उलटी दिशा की एक के अंतर की त्रुटि है।भूल जाता है किtवह योग रखता है जोaके बदलने से पहले निकाला गया था: अंतिम चक्कर मेंaकोbका 3 मिलता है, परbको वही योग, 5, मिलता है, न किaका नया मान।ट्रेस तालिका, चक्कर-दर-चक्कर, देती है: चार चक्कर,iके 0 से 3 तक रहते हुए। यही वह तालिका है जिसे डिबगर प्रोग्राम लिखने वाले व्यक्ति की जगह भरता है, और पाठ प्रोग्रामों की डिबगिंग हर ब्रेकपॉइंट पर अवस्था को परखने के लिए इसका उपयोग करता है।दोहराएँ: लूप
प्रश्न 7पिछली इकाइयों से
std::vector<int> v{1, 2}; std::println("{}", v[2]);पाठ्यक्रम के विकल्पों के साथ क्यों रुक जाता है, और केवल-O2के साथ, डिटेक्टरों के बिना, कंपाइल करने पर कोई भी संख्या क्यों लिख सकता है?मानता है कि ऑप्टिमाइज़ेशन त्रुटियाँ ठीक करता है; वह केवल जाँचें हटाता है और मान लेता है कि प्रोग्राम मानक का उल्लंघन नहीं करता।प्रभाव को उलट देता है: प्रोग्राम को रोकने वाली जाँच ऑप्टिमाइज़ेशन के बिना लाइब्रेरी की जाँच है।यह इंडेक्सों की एक के अंतर की त्रुटि है: दो अवयवों वाले वेक्टर के इंडेक्स 0 और 1 हैं।दो अवयवों वाले वेक्टर में इंडेक्स 2 नहीं होता। क्या दिखेगा, यह कंपाइलर और विकल्पों पर निर्भर है, और इसीलिए परीक्षण सभी जाँचें सक्रिय रखकर चलाए जाते हैं, जैसा पाठ प्रोग्रामों का परीक्षण सिखाता है।दोहराएँ: वेक्टर
प्रश्न 8इन्क्लूड गार्ड वाला एक हेडर
double scale(double x)को,inlineके बिना, परिभाषित करता है (केवल घोषित नहीं), औरmain.cppतथाreport.cppदोनों उसे इन्क्लूड करते हैं। प्रोग्राम बिल्ड करने पर क्या होता है?मानता है कि गार्ड फ़ाइलों के बीच काम करते हैं; वे हर ट्रांसलेशन यूनिट के भीतर काम करते हैं।कंपाइल हो रही फ़ाइल को पूरे प्रोग्राम से मिला देता है: हर फ़ाइल के भीतर एक ही परिभाषा है।यह एक ईमानदार उत्तर है: पाठ 8.1 इसे लिंकर के वास्तविक संदेश के साथ दिखाता है।गार्ड किसी हेडर को एक ही फ़ाइल में दो बार आने से रोकते हैं, पर हर.cppअलग से कंपाइल होती है और परिभाषा की अपनी प्रति पाती है: लिंकर को दो मिलती हैं। यह एक परिभाषा नियम है, पाठ कई फ़ाइलें और अपनी लाइब्रेरी से।दोहराएँ: कई फ़ाइलें और अपनी लाइब्रेरी
प्रश्न 9एक फ़ंक्शन सावधानी से चुने गए पाँच सौ स्वचालित परीक्षण पास करता है। क्या कहा जा सकता है?
प्रचुरता को प्रमाण से मिला देता है; किसी ऐसी सीमा पर त्रुटि जिसे किसी मामले ने नहीं छुआ, भीतर के कितने भी मामलों के बाद भी बची रहती है।मामले संभावित त्रुटियों का यादृच्छिक प्रतिदर्श नहीं हैं, और सफलताओं की आवृत्ति यह नहीं मापती कि प्रोग्राम के सही होने की प्रायिकता कितनी है।यह एक ईमानदार उत्तर है: पाठ 8.2 इसी प्रश्न से शुरू होता है।परीक्षण किसी त्रुटि की उपस्थिति दिखा सकता है, उसकी अनुपस्थिति कभी नहीं: सभी मामलों में सही होने का दावा करने के लिए एक युक्ति चाहिए, जैसे पाठ 4.3 का निश्चर, मामलों की सूची नहीं। अच्छी तरह चुने गए परीक्षण किसी आम त्रुटि के बच निकलने को असंभाव्य बना देते हैं, और इसीलिए वे इतने मूल्यवान हैं। पाठ प्रोग्रामों का परीक्षण इस भेद को विस्तार से समझाता है।दोहराएँ: प्रोग्रामों का परीक्षण
प्रश्न 10एक लूप के भीतर पंक्ति
total += k;पर एक ब्रेकपॉइंट है, और प्रोग्राम वहाँ तीसरी बार रुकता है। हाइलाइट की गई पंक्ति क्या बताती है?रुकने को पहले ही उठाए जा चुके कदम से मिला देता है।प्रोग्राम जहाँ रुकता है उस स्थान को, जिसे डिबग करने वाला व्यक्ति चुनता है, विफलता के कारण से मिला देता है।यह एक ईमानदार उत्तर है: पाठ 8.3 ब्रेकपॉइंट और चरण-दर-चरण निष्पादन को पढ़ाता है।डिबगर चिह्नित पंक्ति से पहले रुकता है; वहtotalका जो मान दिखाता है, वह पहले के दो चक्करों के बाद का है। इसे गड़बड़ाने से ट्रेस तालिकाएँ एक पंक्ति खिसक जाती हैं। पाठ प्रोग्रामों की डिबगिंग इसे विस्तार से समझाता है।दोहराएँ: प्रोग्रामों की डिबगिंग
सामग्री लोड हो रही है…