programmers
डेविड जे मलान का लेक्चर, अध्याय दो, हिंदी प्रस्तुति

भाग 1
एक मछली, दो मछली, लाल मछली, नीली मछली।
बधाई हो! आज तुम्हारा दिन है। तुम महान जगहों की ओर जा रहे हो, तुम निकल पड़े हो और दूर जा रहे हो।
अप्रैल का एक उज्ज्वल, ठंडा दिन था, और घड़ियाँ तेरह बजा रही थीं।
विंस्टन स्मिथ, अपने सीने में ठुड्डी दबाए हुए बदसूरत हवा से बचने की कोशिश में,
विक्टरी मैन्शन्स के कांच के दरवाज़ों से तेज़ी से फिसल गया,
हालाँकि इतनी तेज़ी से नहीं कि उसके साथ घुसने वाली रेतीली धूल के घुमाव को रोक सके।
ठीक है, यह CS50 है, और यह सप्ताह दो है।
और अगर हम कर सकें, इस नाटकीय पाठ के बाद, हमारे स्वयंसेवकों के लिए तालियों की गड़गड़ाहट।
तो अब हम सप्ताह एक से यह मान सकते हैं कि हमारे पास विचारों को व्यक्त करने का एक नया तरीका है
जो हमने पहले सप्ताह शून्य में खोजा था, जैसे फ़ंक्शन और कंडीशनल और वेरिएबल और इसी तरह की चीज़ें।
और अब हम C में वही कर रहे हैं जो हम Scratch में करते थे।
आज हम कुछ वास्तविक दुनिया की समस्याओं पर ध्यान केंद्रित करने वाले हैं
ताकि हम यह मान सकें कि हमारे पास वह अभिव्यक्ति क्षमता है।
हमारे टूलकिट में कुछ उपकरण हैं और वास्तव में कुछ वास्तविक दुनिया की समस्याओं को हल करना शुरू करें यदि वे प्रतिनिधि हैं।
विशेष रूप से, वास्तविक दुनिया की समस्या जिससे हम आज और इस सप्ताह शुरू करने वाले हैं वह है पढ़ने के स्तर।
संभावना है कि जब तुम बड़े हो रहे थे, तुम एक निश्चित स्तर पर पढ़ते थे जो उस उम्र पर आधारित था जिस पर तुम थे।
शायद यह पहली कक्षा का स्तर था या पाँचवीं कक्षा का स्तर या दसवीं कक्षा का स्तर या इसी तरह का।
और वह इस बात का फ़ंक्शन था कि तुम किताब के शब्दों या स्क्रीन पर शब्दों के साथ कितने सहज थे जिन्हें तुम पढ़ रहे थे।
जो तुमने अभी सुना, हमारे स्वयंसेवकों के लिए धन्यवाद, तीन अलग-अलग पढ़ने के स्तर हैं जिन पर ये तीन स्वयंसेवक पढ़ते हैं।
और वास्तव में, क्यों न हम उन्हें फिर से सुनें और इस बार थोड़ा और विचारशील हों
ताकि आकलन कर सकें कि तुम्हारा सहपाठी किस पढ़ने के स्तर पर पढ़ रहा है।
तो आइए लीया से शुरू करें यदि तुम पहले अपना परिचय देना चाहो।
नमस्ते, मैं लीया हूँ। मैं हॉर्डी में प्रथम वर्ष की हूँ और यहाँ मेरी छोटी सी चीज़ है।
एक मछली, दो मछली, लाल मछली, नीली मछली।
तो लीया किस पढ़ने के स्तर पर पढ़ती है उसके पाठ के आधार पर तुम क्या कहोगे?
हाँ, आगे।
किंडरगार्टन।
किंडरगार्टन? ठीक है, तो काफी कम उम्र।
और तुम किंडरगार्टन क्यों कहते हो?
वह बहुत छोटे वाक्यांशों में बोल रही है बिना ज्यादा जटिलता के।
ठीक है, बहुत छोटे वाक्यांश बिना ज्यादा जटिलता के।
और वास्तव में, एक वैज्ञानिक माप के अनुसार जिसे हम इस सप्ताह के प्रॉब्लम सेट में खोजेंगे,
वास्तव में, हम कहेंगे कि लीया ग्रेड एक से पहले पढ़ती है।
तो किंडरगार्टन वास्तव में उपयुक्त होगा।
लेकिन यहाँ मंच पर स्वागत है।
अब आइए मारिया की ओर बढ़ें यदि तुम अपना परिचय देना चाहो।
हाँ, नमस्ते, मैं मारिया हूँ। मैं स्टाउटन में हूँ और एप्लाइड मैथ के बारे में सोच रही हूँ।
बधाई हो। आज तुम्हारा दिन है।
तुम महान जगहों की ओर जा रहे हो। तुम निकल पड़े हो और दूर जा रहे हो।
एक और परिचित वाक्यांश शायद मारिया किस पढ़ने के स्तर पर है?
हाँ, यहाँ।
और तुम दूसरी या तीसरी कक्षा क्यों कहते हो?
ठीक है।
तो अब हम जटिलताएँ पेश कर रहे हैं जैसे तुकबंदी और उद्धरण में थोड़ा और सार।
और वास्तव में, उसी माप के आधार पर जिसका मैंने पहले वर्णन किया,
जिसमें एक गणितीय फ़ंक्शन शामिल होगा जो किसी तरह विश्लेषण करता है कि मारिया ने अभी क्या कहा,
वास्तव में, हम निष्कर्ष निकालेंगे कि उसने तीसरी कक्षा के स्तर या ग्रेड तीन पर पढ़ा।
अंत में, ओमर, यदि तुम अपना परिचय देना चाहो और अपना फिर से पढ़ो।
ठीक है।
तो नमस्ते सबको। मैं ओमर हूँ।
मैं हर्लबट में फ्रेशमैन हूँ और कॉम्प्स हाई करने के बारे में सोच रहा हूँ।
और यह मेरा पाठ है।
अप्रैल का एक उज्ज्वल ठंडा दिन था और घड़ियाँ 13 बजा रही थीं।
विंस्टन स्मिथ, अपने सीने में ठुड्डी दबाए हुए और बदसूरत हवा से बचने के प्रयास में,
विक्टरी मैन्शन्स के कांच के दरवाज़ों से तेज़ी से फिसल गया,
हालाँकि इतनी तेज़ी से नहीं कि रेतीली धूल के घुमाव को रोक सके जो उसके साथ घुस गई।
ठीक है।
तो हम तेज़ी से आगे बढ़ गए।
ओमर किस पढ़ने के स्तर पर है, तुम क्या कहोगे?
कोई और।
तुम क्या कह सकते हो या अनुमान लगा सकते हो?
हाँ।
यहाँ आगे।
ठीक है।
आठवीं कक्षा।
और तुमने वह क्यों कहा?
अधिक जटिल वाक्य, अधिक जटिल शब्द।
और वास्तव में, उसी माप के अनुसार, पाठ का यह पूरा पैराग्राफ अब,
जिसमें वास्तव में और भी व्याकरण है जब तुम इसे स्क्रीन पर देखते हो,
ग्रेड 10 कहा जाएगा उस अतिरिक्त जटिलता के कारण।
तो इसके साथ, हमें किसी तरह इन संख्याओं को क्रंच करने में सक्षम होना होगा
ताकि दिए गए पाठ के शरीर से यह निर्धारित कर सकें कि कोई किस पढ़ने के स्तर पर है।
लेकिन ऐसा करने के लिए और पाठ के शरीर पर कोई मीट्रिक लागू करने के लिए,
हमें उस पाठ को मेमोरी में स्ट्रिंग्स जैसी किसी चीज़ का उपयोग करके प्रस्तुत करना होगा जो पिछले सप्ताह से है।
लेकिन पिछले सप्ताह स्ट्रिंग्स के साथ, हम वास्तव में उन्हें सिर्फ प्रिंट कर सकते थे
या स्क्रीन पर थोक में प्रदर्शित कर सकते थे।
लेकिन मुझे लगता है कि हमें इन विभिन्न पाठों और उनके जैसे अन्य को
अधिक बारीक स्तर पर तोड़ना होगा।
और वास्तव में, आज के लक्ष्यों में ठीक यही खोजना शामिल है
और कार के कहावत वाले हुड को उतारना भी शामिल है ताकि नीचे देख सकें
और कंप्यूटर वास्तव में कैसे काम कर रहा है, स्ट्रिंग्स जैसी ये चीज़ें वास्तव में कैसे काम कर रही हैं।
तो अगर तुम मेरे साथ एक आखिरी बार हमारे स्वयंसेवकों के लिए तालियों की गड़गड़ाहट में शामिल हो सको।
मदद करने के लिए बहुत-बहुत धन्यवाद।
धन्यवाद दोस्तों।
धन्यवाद।
मारिया को भी धन्यवाद।
तो आज के लक्ष्यों में, पढ़ने के स्तर जैसी प्रतिनिधि समस्या का पता लगाने के अलावा,
एक और भी होगा, जो पढ़ने के स्तर से भी अधिक महत्वपूर्ण और सर्वव्यापी है, अर्थात् क्रिप्टोग्राफी,
जानकारी को स्क्रैम्बल करने की कला या विशेष रूप से इसे एन्क्रिप्ट करना
ताकि तुम सुरक्षित संचार भेज सको।
अब, तुम इसे आजकल तेजी से हल्के में लेते हो कि जब तुम टेक्स्ट मैसेज भेजते हो
या शायद एक ईमेल या क्रेडिट कार्ड के साथ ऑनलाइन चेकआउट करते हो
कि किसी तरह तुम्हारी जानकारी सुरक्षित है।
और आने वाले हफ्तों में, हम पता लगाएंगे कि यह वास्तव में किस हद तक सच है
और क्यों या क्यों नहीं।
अब क्रिप्टोग्राफी के साथ, इसी तरह से यदि हम संदेशों को सुरक्षित रूप से भेजने में सक्षम होना चाहते हैं
जैसे कि यदि मैं तुम्हें एक संदेश भेजना चाहता हूँ,
मैं नहीं चाहता कि कमरे में कोई और यह पता लगा सके कि मैंने क्या कहा है
भले ही वे उस संदेश को भौतिक रूप से इंटरसेप्ट कर लें, जो डिजिटल दुनिया में बहुत संभव है,
हमें जानकारी को वास्तव में स्क्रैम्बल करने के लिए मीट्रिक और तंत्र के साथ आने की आवश्यकता होगी
एक प्रतिवर्ती तरीके से ताकि मैं अपना संदेश लिख सकूँ, किसी तरह स्क्रैम्बल कर सकूँ।
तुम वह संदेश प्राप्त कर सकते हो भले ही वह कई अन्य हाथों से गुज़रा हो,
और तुम उसी संदेश को डी-स्क्रैम्बल या डिक्रिप्ट कर सकते हो।
तो उदाहरण के लिए, यहाँ स्क्रीन पर एक संदेश है, एक काफी सरल सा,
जो किसी तरह एन्क्रिप्ट किया गया है।
और हम आज के अंत तक और इस सप्ताह के अंत तक देखेंगे
कि यह एन्क्रिप्टेड संदेश, और वहाँ अंत में थोड़ा संकेत है,
वास्तव में यह कहा जाएगा कि यह “this is CS50” में डिक्रिप्ट होता है।
लेकिन क्यों होगा अंतर्निहित प्रश्न?
और हमारे टूलकिट पर कौन से अतिरिक्त उपकरण चाहिए ऐसा करने के लिए?
उपकरणों पर एक और शब्द।
तो अब तक, तुमने शायद कुछ बग्स का अनुभव किया है,
चाहे Scratch में हो या C में और भी अधिक।
वास्तव में, बहुत बुरा महसूस मत करो यदि C में तुम्हारा पहला प्रोग्राम भी काम नहीं किया।
तुम इसे बना भी नहीं सके या कंपाइल भी नहीं कर सके जब तक कि तुम वापस नहीं गए और कुछ कोड ठीक नहीं किया जो तुमने लिखा था।
खैर, यह पता चलता है कि बग्स, प्रोग्राम में गलतियाँ, बहुत आम हैं।
और भले ही हमने तुम्हें CS50.ai पर वर्चुअल रबर डक जैसे उपकरण पहले ही प्रदान कर दिए हैं,
जो VS Code में भी एम्बेडेड है CS50.dev पर, जिससे तुम रास्ते में सवाल पूछ सकते हो
आज के लक्ष्यों में तुम्हें कुछ आजीवन उपकरण देना शामिल है कि तुम वास्तव में खुद सॉफ्टवेयर को कैसे डिबग कर सकते हो
जब तुम्हारे पास पास में डक नहीं है, जब तुम्हारे पास TA नहीं है,
अकेले किसी भी इंसान की बात छोड़ो।
तो डिबगिंग के साथ, कई तकनीकें होंगी जिनका हम उपयोग कर सकते हैं
सभी बग्स या हमारे सॉफ्टवेयर से गलतियों को खोजने और हटाने के अंत की ओर।
और शायद वह व्यक्ति जो इस बग्स के शब्द को लोकप्रिय बनाने के लिए सबसे अच्छी तरह जाना जाता है
वह डॉ. ग्रेस हॉपर हैं, जो यहाँ चित्रित हैं, जो नेवी में रियर एडमिरल थीं
और तथाकथित हार्वर्ड मार्क I की मूल प्रोग्रामरों में से एक थीं,
एक बहुत प्रारंभिक मेनफ्रेम कंप्यूटर जिसे यदि तुम चार्ल्स नदी के पार घूमते हो
हार्वर्ड के साइंस एंड इंजीनियरिंग कॉम्प्लेक्स में,
तुम वास्तव में इसका एक हिस्सा अभी भी लॉबी में प्रदर्शित देख सकते हो।
इसके बाद हार्वर्ड मार्क II आया।
और हार्वर्ड मार्क II पर, डॉ. हॉपर और उनकी टीम
अपनी लॉग बुक में यह नोट डालने के लिए जानी जाती थीं
सिस्टम पर कुछ संख्या क्रंचिंग करने के बाद।
और यदि हम ज़ूम इन करें, उन्होंने उस दिन कंप्यूटर में एक समस्या पाई
जहाँ सर्किट्री के अंदर शाब्दिक रूप से एक बग, एक पतंगा था।
और जैसा यहाँ लिखा गया, बग पाए जाने का पहला वास्तविक मामला।
और तब से, क्या हम और भी अधिक कहते हैं, वाक्यांश बग
और डिबगिंग जब हमारे कोड में समस्याओं को खोजने और खत्म करने की बात आती है?
तो आइए बस उसी से शुरू करें।
वास्तव में, मुझे VS Code की ओर जाने दो और आइए जानबूझकर कुछ गलतियाँ एक साथ करें
जो बहुत अच्छी तरह से उन गलतियों की याद दिला सकती हैं जो तुमने अब तक गलती से की हैं।
लेकिन रास्ते में, उन समस्याओं को हल करने के लिए तुम्हें और अधिक उपकरण दें
इसके बजाय कि किसी और से पूछना पड़े, चाहे वर्चुअल हो या भौतिक,
मदद के लिए और वास्तव में अपने खुद के कोड में इन गलतियों को खोजो।
मुझे VS Code में सचेत रूप से एक प्रोग्राम बनाने दो जो बगी के रूप में जाना जाता है
जिसे buggy.c कहा जाता है।
और इस प्रोग्राम में, आइए शुरू में कुछ काफी परिचित कोड करें।
मैं पिछले सप्ताह की तरह ही int main void से शुरू करने जा रहा हूँ,
आज उस पर और अधिक जल्द ही।
मेरे कर्ली ब्रेसेस के अंदर, मैं कहूँगा printf, hello, comma, world।
बस इतना ही।
अब मैं अपनी टर्मिनल विंडो पर वापस जाऊँगा।
मैं make buggy करने जा रहा हूँ उस सोर्स कोड से एक प्रोग्राम बनाने के लिए।
लेकिन इससे पहले कि मैं करूँ, संभावना है, इस सामान के सिर्फ एक सप्ताह के बाद भी,
तुम शायद कुछ गलतियाँ देख सकते हो जो मैंने की हैं, कुछ बग्स।
तुम पहले से क्या गलत देखते हो?
हाँ?
मैंने standard.io.h शामिल नहीं किया, वह तथाकथित हेडर फाइल,
जो महत्वपूर्ण है क्योंकि यह कंपाइलर को बताती है
कि मैं इसमें फ़ंक्शन का उपयोग करने की योजना बना रहा हूँ, जैसे printf, जो स्पष्ट रूप से मैं कर रहा हूँ।
तो मुझे अंदर जाकर standard.io.h शामिल करने दो।
यहाँ और क्या गलत लगता है?
हाँ?
मैं लाइन पाँच के अंत में सेमीकोलन भूल गया हूँ।
तो मैं उसे जोड़ने जा रहा हूँ।
और यह सूक्ष्म है और तर्कपूर्वक बग नहीं है, लेकिन शायद एक सौंदर्य विवरण।
मैंने और क्या तर्कपूर्वक गलत किया है?
हाँ?
और पीछे?
हाँ, मैंने अपना बैकस्लैश और न्यू लाइन कैरेक्टर भूल गया
बस कर्सर को अगली लाइन पर ले जाने के लिए ताकि जब मुझे नया प्रॉम्प्ट मिले,
यह अपनी खुद की ताज़ी लाइन पर हो।
फिर से, अधिक सौंदर्य, लेकिन निश्चित रूप से करने के लिए काफी उचित बात।
तो अब मुझे आगे बढ़ने दो।
और वास्तव में, अपनी टर्मिनल विंडो में, make buggy रन करो, और यह वास्तव में कंपाइल हो गया।
लेकिन तब तक, यदि मैंने उन गलतियों को ठीक नहीं किया होता,
तो मैंने बग्स का एक पूरा गुच्छा ट्रिगर किया होता, त्रुटि संदेशों का एक पूरा गुच्छा
परिणामस्वरूप।
वास्तव में, आइए समय में पीछे जाएँ और मैंने जो फिक्स किए थे उन्हें अनडू करें
और मूल रूप में वापस जाएँ और फिर से make buggy रन करने की कोशिश करें,
एंटर।
और हम यहाँ कुछ डरावने दिखने वाले संदेश देखेंगे।
मुझे आउटपुट के शीर्ष पर स्क्रॉल करने दो
यहाँ जहाँ हम buggy.c कोलन तीन देखते हैं, जिसका मतलब लाइन तीन है।
यही वह जगह है जहाँ अभी समस्या है।
त्रुटि।
अघोषित लाइब्रेरी फ़ंक्शन printf को कॉल टाइप के साथ,और फिर यह थोड़ा और जटिल होने लगता है।लेकिन मैं स्पष्ट रूप से देखता हूँ कि यह मेरा ध्यान printf की ओर आकर्षित कर रहा है।तो उम्मीद है, किसी बिंदु पर, यदि पिछले सप्ताह नहीं, तो उम्मीद है इस सप्ताह से आगे,तुम्हारी सहज ज्ञान होगी, ओह, ठीक है।मेरा मतलब है, मैं हेडर फाइल भूल गया जिसमें printf वास्तव में घोषित है।यह कोई बड़ी बात नहीं है।यह अभ्यास के साथ आएगा।तो यही तरीका है जिससे मैं अधिक सहज रूप से जान सकता हूँ कि वास्तव में यहाँ समाधान क्या हो सकता है।अब, यहाँ एक और आम गलती है जिसे मैंने अभी जाकर ठीक किया है।लेकिन मैंने कुछ गलत किया।और उम्मीद है, तुममें से किसी ने वास्तव में यह नहीं किया क्योंकि यह एक वार्षिक FAQ है।मैंने अभी गलती से क्या गलत किया?तो यह studio.h नहीं है।यह standard.io.h है।तो कृपया standard input output के लिए उसे याद रखो।अगला, हालाँकि, बग जिसे मैंने अभी तक ठीक नहीं किया है वह सेमीकोलन है।तो मुझे अपनी स्क्रीन साफ करने दो और make buggy फिर से रन करो।मुझे अब वह पहला त्रुटि संदेश नहीं दिखना चाहिए।लेकिन मुझे अब लाइन 5 पर एक और त्रुटि संदेश दिखता है, expression के बाद सेमीकोलन अपेक्षित।ठीक है, वह काफी स्पष्ट है।तो मैं इसे ठीक करने जा रहा हूँ।लेकिन ध्यान दो कि अब तक, मेरा कोड उन दो त्रुटि संदेशों के कारण कंपाइल नहीं हो पाता।इसने मुझे ये त्रुटियाँ दिखाकर रोक दिया।लेकिन इस बिंदु पर, यदि मैं make buggy एंटर रन करूँ, यह वास्तव में कंपाइल हो गया।और फिर भी, यह तर्कपूर्वक अभी भी बगी है।क्योंकि जब मैं डॉट स्लैश buggy रन करता हूँ, मुझे अपना प्रॉम्प्ट गलत लाइन पर मिलता है।तो यह अब एक सिंटैक्स त्रुटि के बीच अंतर है, कुछ ऐसा या एक प्रोग्रामिंग त्रुटिजो मेरे प्रोग्राम को कंपाइल होने से पूरी तरह रोक देती है।यह एक डील ब्रेकर है बनाम कुछ ऐसा जो शायद अधिक तार्किक त्रुटि है।मैं वास्तव में कर्सर को अगली लाइन पर ले जाना चाहता था।और इसलिए दुनिया में विभिन्न प्रकार की त्रुटियाँ हैं जैसा हम यहाँ देख रहे हैं।बेशक, यदि मैं make buggy फिर से रन करूँ, डॉट स्लैश buggy, अब हम वापस बिजनेस में हैं,उम्मीद है कि इसे ठीक वैसा प्रदर्शित करने के इरादे से।
ठीक है, खैर, आइए इसे थोड़ा और पिछले सप्ताह की किसी और चीज़ की तरह संशोधित करें।
याद करो कि पिछले सप्ताह, मैंने किसी का नाम अधिक गतिशील रूप से लेना शुरू किया।
तो मैंने कुछ कहा जैसे name equals get string।
और वह एक फ़ंक्शन था जिसे हमने पेश किया।
और मैंने कुछ ऐसा कहा हो सकता है।
What’s your name?
प्रश्न चिह्न स्पेस के साथ बस कर्सर को आगे ले जाने के लिए।
मुझे अब पता है कि मुझे निश्चित रूप से अपने विचार को सेमीकोलन के साथ समाप्त करना होगा।
मैं इसे कंपाइल करने की कोशिश कर सकता हूँ।
Make buggy अब।
और मैं एक पूरी तरह से अलग त्रुटि संदेश देख रहा हूँ जो तुमने अभी तक नहीं देखा हो सकता है।
तो buggy.c लाइन 5 पर, त्रुटि, undeclared identifier name का उपयोग।
अब मैंने क्या गलती की है?
यह क्यों नहीं जानता?
हाँ, मैं इस वेरिएबल का टाइप घोषित करना भूल गया, जो तुममें से उन लोगों के लिए जिन्हें पूर्व प्रोग्रामिंग अनुभव है,
कुछ भाषाओं में करना नहीं पड़ता, जैसे Python, उदाहरण के लिए।
लेकिन C, C++, Java, और अन्य जैसी भाषाओं में,
तुम्हें वास्तव में स्पष्ट रूप से कंपाइलर को बताना होगा कि तुम एक वेरिएबल इंस्टैंशिएट करना चाहते हो,
कंप्यूटर की मेमोरी में एक वेरिएबल बनाकर इसे उसका टाइप बताकर।
और यह int नहीं होगा, क्योंकि मैं इस मामले में बेशक एक integer नहीं चाहता।
मैं टेक्स्ट चाहता हूँ, जिसे हम अब string कहते हैं।
ठीक है, मुझे लगता है कि यह उस बग को ठीक करता है।
तो मुझे make buggy फिर से करने दो।
और उम्मीद है, हह, इस बार एक fatal error।
फिर से, यह दर्शाता है कि मेरा कोड फिर से कंपाइल नहीं हुआ।
अभी भी लाइन पाँच पर, मेरे पास एक त्रुटि है।
लेकिन इस बार, यह कहता है, undeclared identifier string का उपयोग, क्या मेरा मतलब standard in था?
तो यह थोड़ा लाल हेरिंग है।
कंपाइलर मददगार होने की कोशिश कर रहा है यह कहते हुए, क्या मेरा मतलब standard in था?
लेकिन मुझे नहीं लगता कि मैं वास्तव में करता हूँ।
वह बस कंपाइलर की अपनी मेमोरी में सबसे समान दिखने वाला शब्द है।
यहाँ मैंने वास्तव में क्या गलती की है?
हाँ?
हाँ, मैंने CS50 हेडर फाइल शामिल नहीं की, क्योंकि string, याद करो,
CS50 लाइब्रेरी की एक विशेषता है, जैसा कि get string और get int और अन्य हैं।
तो यहाँ समाधान वास्तव में यहाँ ऊपर जाना है।
और बस नुक्ताचीनी करने के लिए, मैं अपनी हेडर फाइलों को वर्णानुक्रम में रखने की प्रवृत्ति रखता हूँ।
यह तकनीकी रूप से सख्ती से आवश्यक नहीं है, लेकिन शैलीगत रूप से।
मुझे हेडर फाइलों को वर्णानुक्रम में स्किम करना अच्छा लगता है यह देखने के लिए कि कुछ है या नहीं।
मैं standard io.h के अलावा CS50.h शामिल कर सकता हूँ।
और उस फाइल में, CS50.h में, न केवल get string घोषित है,
ताकि कंपाइलर जानता हो कि यह मौजूद है, यह पता चलता है कि शब्द string भी है।
तो यह थोड़ा सफेद झूठ है।
और यह कुछ ऐसा है जो हम क्लास के शुरुआती हफ्तों में करते हैं।हमने साइकिल से ये पुराने ट्रेनिंग व्हील्स खोदे,पूरा विचार यह है कि तुम्हें ऊपर रखें और तुम्हें शुरुआती दौर में बहुत अधिक जटिलता से बचने दें।CS50 लाइब्रेरी के रूप में इन ट्रेनिंग व्हील्स का बिंदुहमें यह अनदेखा करने देना है कि string वास्तव में क्या है सिर्फ एक या दो और हफ्तों के लिए,जिसके बाद हम फिर उस परत को छीलेंगे, उन ट्रेनिंग व्हील्स को उतारेंगे,और तुम्हें प्रकट करेंगे कि वास्तव में क्या चल रहा है।तो अभी के लिए, स्ट्रिंग्स मौजूद हैं, लेकिन वे CS50 लाइब्रेरी के कारण मौजूद हैं।कुछ हफ्तों में, वे अभी भी मौजूद रहेंगे,लेकिन हम उन्हें एक अलग नाम से पुकारेंगे, जैसा हम अंततः देखेंगे।लेकिन वास्तविक दुनिया में हर कोई, हर सॉफ्टवेयर डेवलपर, स्ट्रिंग वाक्यांश का उपयोग करता है।तो यह एक अवधारणा है जो मौजूद है।यह बिल्कुल भी CS50 विशिष्ट नहीं है।बस इतना है कि C में, शब्द string आमतौर पर मौजूद नहीं होता जब तक कि तुम इसे ऐसा न बनाओ जैसा हमने किया है।
ठीक है, तो मुझे लगता है कि अब, यदि मैं अपनी टर्मिनल विंडो साफ करूँ और फिर से make buggy रन करूँ,
अब यह वास्तव में कंपाइल होना चाहिए।
और यदि मैं डॉट स्लैश buggy रन करूँ, एंटर, मुझे अपना नाम टाइप करने में सक्षम होना चाहिए।
और अब, वोइला, hello।
तो यह अब सिंटैक्स त्रुटि नहीं है, क्योंकि मैंने अपने कोड को प्रति से गड़बड़ नहीं किया,
जैसे यह कंपाइल हो गया।
सब कुछ व्याकरणिक रूप से सही है, बोलने के लिए।
लेकिन तार्किक रूप से, बौद्धिक रूप से, यह वह नहीं है जो मैं चाहता था, है ना?
मैं चाहता था कि यह संभवतः hello comma David कहे।
आइए यहाँ एक अंतिम बग ठीक करें।
मैं इसे कैसे ठीक करूँ?
किस लाइन पर?
मैं इसे कैसे कहूँ, हाँ, hello, David?
हाँ, लाइन 7 पर, मुझे स्ट्रिंग प्लेसहोल्डर, फॉर्मेट कोड, बोलने के लिए,
percent s करना होगा, और फिर एक और चीज़, कोई और।
इसके बाद मैं क्या करूँ?
हाँ, पीछे?
हाँ, एक कॉमा, और फिर वेरिएबल नाम जोड़ो जिसमें वह वैल्यू है जिसे मैं वहाँ सब्स्टिट्यूट करना चाहता हूँ,
जो वास्तव में name है, हालाँकि मैंने इसे कुछ भी कह सकते थे।
ठीक है, तो अब make buggy एंटर लगता है फिर से कंपाइल हो गया, डॉट स्लैश buggy।
अब मैं एक बार और अपना नाम टाइप करता हूँ, और अब हम वापस बिजनेस में हैं।
तो इन कुछ अभ्यासों के दौरान, स्पष्ट रूप से मेरा मतलब
इनमें से अधिकांश या सभी बग्स, इन गलतियों को करना था।
लेकिन वे न केवल सिंटैक्स त्रुटियों को प्रदर्शित करते हैं, जो
बस कंपाइलर को उसके ट्रैक्स में रोक देंगी।
जैसे तुम अपना कोड तब तक कंपाइल भी नहीं कर पाओगे जब तक कि तुम उन चीज़ों को ठीक न कर लो।
लेकिन उसके बाद भी, ये अव्यक्त बग्स हो सकते हैं जो तब तक नहीं लगते जब तक कि तुम वास्तव में इनपुट प्रदान न करो
और देखो कि रन टाइम पर वास्तव में क्या हो रहा है जब तुम वास्तविक कोड रन कर रहे हो।
और तो यहाँ।
अब त्रुटि संदेश पढ़ना और यह पता लगाना उतना आसान नहीं है कि इसका क्या मतलब है,
क्योंकि जब इसने hello, comma, world कहा तो स्क्रीन पर कोई त्रुटि संदेश नहीं आया।
हमारे पास उपयोगकर्ता पर मानव बुद्धि थी और एहसास हुआ, ठीक है, यह स्पष्ट रूप से वह नहीं है जो मैं चाहता था।
यदि तुमने CS50 के अपने Check50 प्रोग्राम को उस जैसी किसी चीज़ पर रन किया होता,
हम तुम्हें बता सकते थे कि यह सही नहीं है इसकी शुद्धता का स्वचालित रूप से आकलन करके।
लेकिन कंपाइलर को कोई अंदाज़ा नहीं है कि तुम तार्किक रूप से क्या हासिल करने की कोशिश कर रहे हो।
यह केवल भाषा C के बारे में और कोड लिखने और कंपाइल करने के लिए आवश्यक सिंटैक्स के बारे में जानता है।
तो हम कोड में तार्किक समस्याओं को कैसे हल कर सकते हैं?
तो मैं प्रस्ताव करूँगा कि हम इस सूची पर विचार करना शुरू करें।
जहाँ, जब तुम अपने कोड में एक तार्किक समस्या खोजना चाहते हो
और बेहतर समझना चाहते हो कि क्या चल रहा है या वास्तव में क्या गलत हो रहा है, printf तुम्हारा दोस्त होगा।
अब तक, हमने printf का उपयोग स्क्रीन पर शाब्दिक रूप से प्रिंट करने के लिए किया है।
Hello, David।
Hello, Kelly या स्क्रीन पर कुछ और।
लेकिन तुम निश्चित रूप से printf का अस्थायी रूप से उपयोग कर सकते हो ताकि अपने प्रोग्राम के अंदर सिर्फ सामान प्रिंट कर सको
जिसे तुम बेहतर समझना चाह सकते हो।
और फिर एक बार जब तुम इसे समझ लो और एक बार जब तुमने कुछ समस्या हल कर ली, ठीक।
फिर तुम उन अस्थायी कोड लाइनों को हटा सकते हो, फिर से कंपाइल कर सकते हो, और आगे बढ़ सकते हो।
तो आइए printf को उस अर्थ में डिबगिंग टूल के रूप में उपयोग करें।
मुझे यहाँ VS Code पर वापस जाने दो और इस उसी प्रोग्राम buggy.c में,
सब कुछ हटा दो और एक अलग तरह के बग के साथ फिर से शुरू करो।
मैं शीर्ष पर standard.io.h शामिल करने जा रहा हूँ।
मैं उसके बाद int main void करने जा रहा हूँ।
और main के अंदर, मैं एक साधारण for लूप करने जा रहा हूँ जो सिर्फ तीन ईंटों के स्टैक की तरह प्रिंट करता है।
जैसे हमने Mario की दुनिया में देखा, जब Mario को, हमने दावा किया कि ईंटों के स्टैक पर कूदना है।
हम फिलहाल बस तीन प्रिंट करना चाहते हैं।
तो मैं कहने जा रहा हूँ for int i equals zero।
i is less than or equal to three क्योंकि मैं इनमें से तीन चाहता हूँ, i plus plus।
फिर इस for लूप के अंदर, मैं काफी सरलता से printf hash सिंबल करने जा रहा हूँ ईंट को दर्शाने के लिए,
उसके बाद एक न्यू लाइन कर्सर को अगली लाइन पर ले जाने के लिए, सेमीकोलन विचार पूरा करने के लिए।
अब, मैंने जानबूझकर यहाँ एक मूर्खतापूर्ण गलती की है।
लेकिन एक पर्याप्त रूप से सरल प्रोग्राम के संदर्भ में कि हम डिबगिंग तकनीक पर ध्यान केंद्रित कर सकें,
मैं प्रश्न में बग की अस्पष्टता पर नहीं हूँ।
उम्मीद है कि तुम अभी या पहले से बग को देख लोगे।
जब मैं अब make buggy करता हूँ और डॉट स्लैश buggy करता हूँ, मुझे तीन ईंटें नहीं मिलतीं।
मुझे बेशक एक, दो, तीन, चार कुल मिलती हैं।
तो इस प्रोग्राम में एक तार्किक बग है।
और संभावना है कि तुम पहले से देख सकते हो कि यह क्या है।
लेकिन मुझे प्रस्ताव करने दो कि यह प्रोग्राम एक प्रकार की समस्या का प्रतिनिधि है
जिसे तुम थोड़ा अधिक नैदानिक रूप से हल कर सकते हो printf के माध्यम से कंप्यूटर से पूछकर कि वास्तव में क्या चल रहा है।
और मैं प्रस्ताव करूँगा कि ऐसी स्थिति में सबसे मददगार तकनीकों में से एक,
यदि तुम यह समझने की कोशिश कर रहे हो कि तीन के बजाय चार ईंटें क्यों हैं,
खैर, स्पष्ट रूप से यह लूप से संबंधित है।
तो आइए थोड़ा और विचारपूर्वक देखें कि प्रत्येक ईंट प्रिंट करने से पहले i का मान क्या है।
और मैं अस्थायी रूप से शाब्दिक रूप से कुछ ऐसा कर सकता हूँ।Printf, quote unquote, i is percent i backslash n, close quote।और फिर मैं बस यहाँ और अभी i का मान प्रिंट कर सकता हूँ ताकि मैं वास्तव में इसे देख सकूँ।मुझे अब अपनी टर्मिनल विंडो में जाने दो, make buggy फिर से, डॉट स्लैश buggy।और अब, और मैं अपनी टर्मिनल को फुल स्क्रीन करूँगा, मुझे एक ही समय में कुछ डायग्नोस्टिक जानकारी मिलेगी।तो जब i एक है, मुझे एक ईंट मिलती है।जब i शून्य है, मुझे एक ईंट मिलती है।जब i एक है, मुझे एक और ईंट मिलती है।जब i दो है, मुझे एक और ईंट मिलती है।जब i तीन है, मुझे चौथी ईंट मिलती है।तो अब मैं तरह से देख सकता हूँ कि, ठीक है, मेरा लूप काम कर रहा है, लेकिन मैं बहुत दूर जा रहा हूँ।मैं बहुत लंबा जा रहा हूँ।अब मैं इसे और भी संक्षेप में कर सकता हूँ जो इसके लायक है।मुझे पूरे नए printf स्टेटमेंट की जरूरत नहीं है।मैं बस अपने मौजूदा printf में जा सकता हूँ, अपना percent i वहाँ रख सकता हूँ, और फिर शायद सिर्फ स्पेस,बस चीज़ों को आगे बढ़ाने के लिए, और फिर उसी लाइन में i प्रिंट कर सकता हूँ।यदि मैं अब make buggy डॉट स्लैश buggy करता हूँ, ठीक।अब मैं देख रहा हूँ कि मैं एक हैश, एक ईंट प्रिंट कर रहा हूँ,i के प्रत्येक मान के लिए i equals zero, one, two, और भी three से।तो समाधान, बेशक, यह है कि मुझे शून्य से शुरू नहीं करना चाहिएऔर three से कम या बराबर तक इटेरेट नहीं करना चाहिए।समाधान है जैसे, ओह, मैं बेवकूफ हूँ।मुझे three से कम कहना चाहिए था।या यदि मैं एक सामान्य व्यक्ति की तरह एक से गिनना पसंद करता हूँ,मैं i equal to one कह सकता था, और फिर दो और तीन तक जा सकता था।लेकिन जैसा मैंने पिछले सप्ताह दावा किया, कैनोनिकल तरीका, ऐसा करने का सबसे आम तरीका,शून्य से गिनती शुरू करना है और दो तक जाना है, लेकिन उस कुल मान के माध्यम से नहीं जो तुम्हारे मन में है।
लेकिन यहाँ जानने लायक एक और तकनीक होगी।
मुझे आगे बढ़ने दो और इसे थोड़ा अमूर्त करने दो
इसके थोड़े बेहतर संस्करण को इस प्रकार बनाकर।
मुझे इस for लूप को हटाने दो।
मुझे फिलहाल मान लेना दो कि main के अंदर,
मैं अब उपयोगकर्ता से पिरामिड की ऊँचाई पूछने जा रहा हूँ।
और मैं कुछ ऐसा करने जा रहा हूँ, int h equals get int।
और आइए उपयोगकर्ता को इस पिरामिड या इस दीवार के ऊँचाई मान के लिए प्रॉम्प्ट करें।
और फिर आइए मान लें कि एक फ़ंक्शन मौजूद है जिसे print column कहा जाता है
जो इनपुट के रूप में एक संख्या h लेता है, जो तुम कितनी ईंटें प्रिंट करना चाहते हो।
अब, यह फ़ंक्शन अभी मौजूद नहीं है।
Print column।
Get int मौजूद है, लेकिन मुझे इसकी पहुँच नहीं है।
तो मुझे दो बार वही गलती नहीं करने दो।
मुझे इस फाइल के शीर्ष पर क्या जोड़ने की जरूरत है?
हाँ।
मुझे cs50 हेडर फाइल की जरूरत है क्योंकि मैं अब get int फ़ंक्शन का उपयोग कर रहा हूँ, जो
फिर से हमारी लाइब्रेरी से आता है, C से नहीं।
तो मुझे cs50.h शामिल करने दो।
लेकिन अब print column, मैं इस फ़ंक्शन को खुद बना सकता हूँ।
तो मुझे कहने दो void print column int height parentheses में,
उस पर और अधिक बस एक पल में।
और फिर मैं पहले वाले लूप को फिर से बनाऊँगा।
For int i equals 0, i is less than or equal to the height।
तो मैं जानबूझकर अभी के लिए वही गलती करने जा रहा हूँ जो पहले थी।
i plus plus।
और फिर इस for लूप के अंदर, मैं एक सिंगल हैश और एक न्यू लाइन प्रिंट करने जा रहा हूँ
उस ईंट को दर्शाने के लिए।
तो अब, main एक फ़ंक्शन का उपयोग कर सकता है जिसे print column कहा जाता है।
यह h का मान पास करने जा रहा है।
और फिर print column फ़ंक्शन में यह for लूप
मेरे लिए इस चीज़ को प्रिंट करने का ख्याल रखने जा रहा है।
तो मुझे यह फिर से करने दो।
Make buggy एंटर अब तक तो अच्छा डॉट स्लैश buggy।
ऊँचाई डालो।
मैं मैन्युअली तीन की ऊँचाई कहने जा रहा हूँ।
और मुझे तीन ईंटें दिखनी चाहिए।
लेकिन बेशक, मुझे अभी भी चार दिख रही हैं।
अब, आगे बढ़ने से पहले, मुझे अपना टर्मिनल छिपाने दो
और प्रस्ताव करने दो कि यह सिर्फ शैलीगत रूप से खराब है अपने main फ़ंक्शन के अलावा कुछ और शीर्ष पर रखना।
लेकिन याद करो कि यदि मैं अपना हेल्पर फ़ंक्शन, print column ले जाऊँ,
और यह एक हेल्पर फ़ंक्शन है जहाँ तक मैंने इसे एक और समस्या हल करने में मदद करने के लिए बनाया,
मैं अब अपना कोड फिर से कंपाइल और रन नहीं कर सकता।
क्यों?
कंपाइलर मुझे नहीं देगा।
हाँ।
बिल्कुल।
जब कंपाइलर मेरे कोड की लाइन सात पर पहुँचता है,
यह कंपाइलेशन को रोक देगा क्योंकि यह नहीं जानता कि print column क्या है।
क्यों?
क्योंकि मैं इसे लाइन 10 तक नहीं बताता कि यह क्या है।
और यह एकमात्र समय था जब मैंने प्रस्ताव किया कि कॉपी पेस्ट उचित हैउस फ़ंक्शन की बहुत पहली लाइन को हाइलाइट और कॉपी करना है,इसे main के ऊपर सेमीकोलन के साथ पेस्ट करना, और वह तथाकथित फ़ंक्शन प्रोटोटाइप है।यह निर्दिष्ट करता है कि इसका नाम क्या है, इसके इनपुट क्या हैं, यदि कोई हो,और इसका आउटपुट क्या है, यदि कोई हो।और इन इनपुट और आउटपुट पर बाद में और अधिक।लेकिन अब, यह उसी प्रोग्राम का अधिक जटिल लेकिन अधिक मॉड्यूलराइज्ड संस्करण है।मुझे make buggy करने दो, अभी भी कंपाइल होता है, डॉट स्लैश buggy, तीन टाइप करो।और मेरे पास अभी भी वही बग है।लेकिन अब पकड़ यह है कि मेरा कोड अधिक जटिल हो गया है।और कॉलम प्रिंट करने के इस विचार को एक नए फ़ंक्शन में अमूर्त करने का मेरा बिंदु यह है किअब डिबग करने के लिए बस अधिक कोड है।मैं निश्चित रूप से वहाँ जा सकता हूँ और printf जोड़ना शुरू कर सकता हूँ।लेकिन किसी बिंदु पर, printf एक बहुत आदिम उपकरण होगा।और तुम printf जोड़ने, अपना कोड फिर से कंपाइल करने, अपना कोड रन करने, printf बदलने,अपना कोड फिर से कंपाइल करने, अपना कोड रन करने में अधिक समय बर्बाद करोगे।यह बहुत थकाऊ हो जाएगा जल्दी जब तुम्हारे स्क्रीन पर बहुत सारी कोड लाइनें हों।तो क्या मैं वास्तव में अपने कोड को लाइन बाय लाइन स्टेप थ्रू कर सकता हूँ,शायद जैसे तुम्हारा TA सेक्शन में या छोटी क्लास में करेगा,लाइन बाय लाइन कोड के माध्यम से चलते हुए?तुम कर सकते हो।क्योंकि एक और उपकरण जो तुम्हारे पास पहुँच है वह debug50 कहलाता है।तो यह एक CS50 कमांड है जो एक उद्योग मानक डिबगर शुरू करेगा।और एक डिबगर सॉफ्टवेयर का एक टुकड़ा है जिसका उपयोग वास्तविक दुनिया में किया जाता हैजो शाब्दिक रूप से तुम्हें वह करने देता है।अपने कोड को डिबग करो निष्पादन को धीमा करके या यहाँ तक कि पॉज़ करकेऔर अपने कोड के निष्पादन को लाइन बाय लाइन चलाकर।एकमात्र कारण हम इसे debug50 कहते हैं क्योंकि VS Code में,डिबगर शुरू करना थोड़ा परेशान करने वाला है।और इसलिए हमने डिबगर शुरू करने की प्रक्रिया को स्वचालित कर दिया।लेकिन उसके बाद सब कुछ CS50 से कोई लेना-देना नहीं हैऔर वास्तविक दुनिया के सॉफ्टवेयर इंजीनियरिंग तकनीकों से सब कुछ लेना-देना है।
तो हम इसका उपयोग कैसे करें?
मुझे यहाँ VS Code पर वापस जाने दो और प्रस्ताव करने दो कि मैं इस कोड को लाइन बाय लाइन स्टेप थ्रू करना चाहता हूँ,
बस जैसे हम छोटी क्लास में व्हाइटबोर्ड पर कर सकते हैं,
यह पता लगाने के लिए कि मुझे तीन के बजाय चार हैश क्यों मिल रहे हैं।
खैर, अपनी टर्मिनल विंडो में, मैं यह करने जा रहा हूँ।
Debug50 स्पेस डॉट स्लैश buggy।
तो debug50 कमांड है।
इसे जानने की जरूरत है कि मैं कौन सा प्रोग्राम डिबग करना चाहता हूँ।
तो मैं डॉट स्लैश buggy निर्दिष्ट कर रहा हूँ, जो वह प्रोग्राम का नाम है जिसे मैंने अभी कंपाइल किया।
मुझे पहली बार इसे रन करने पर एक त्रुटि मिलेगी।
जैसा कि तुम्हें मिलेगा यदि तुम वही गलती करो।
मैं इस संदेश को देखने वाला हूँ।
लगता है कि तुमने कोई ब्रेकपॉइंट सेट नहीं किया है,
लाइन नंबर के बाईं ओर क्लिक करके कम से कम एक ब्रेकपॉइंट सेट करो,
और फिर debug50 फिर से रन करो।
तो यह वास्तव में मुझे क्या बता रहा है?
खैर, डिबगर को कोई अंदाज़ा नहीं है कि कब और कहाँ मैं निष्पादन को पॉज़ करना चाहता हूँ ताकि
अपने कोड को लाइन बाय लाइन चलाना शुरू कर सकूँ।
यह चाहता है कि मैं इसे बताऊँ कहाँ तोड़ना है।
अर्थात् कहाँ पॉज़ करना है लाइन नंबर पर क्लिक करके।
तो मुझे बस एक पल के लिए अपना टर्मिनल छिपाने दो।
और तुमने शायद यह जानबूझकर कभी नहीं किया।
लेकिन यदि तुम अपने प्रोग्राम के लाइन नंबरों के बाईं ओर की स्पेस पर होवर करो,
तुम एक छोटा लाल डॉट देखोगे, एक छोटा स्टॉप साइन तरह का।
यदि तुम वास्तव में लाइन नंबर पर क्लिक करते हो, वह लाल डॉट वहाँ रह जाएगा।
और तुम यहाँ होवर देख सकते हो कहते हुए क्लिक टू ऐड ब्रेकपॉइंट।
मैं जो करने जा रहा हूँ वह है main पर ब्रेकपॉइंट जोड़ने के लिए क्लिक करना।
Main मेरे प्रोग्राम का एंट्री पॉइंट है।
यह डिफ़ॉल्ट फ़ंक्शन है जो कॉल होता है।
आइए तुरंत तोड़ें ताकि मैं इस कोड को लाइन बाय लाइन स्टेप थ्रू कर सकूँ।
ठीक है, मुझे अपनी टर्मिनल विंडो फिर से खोलने दो और इसे साफ करने दो।
और फिर debug 50 फिर से रन करो डॉट स्लैश buggy एंटर के साथ।
और अब स्क्रीन पर जल्दी से बहुत सारी चीज़ें होंगी।
और फिर यह खुद को साफ कर लेगा क्योंकि एक बार डिबगर रन हो रहा हो
और तैयार हो, यह मुझे अपना कोड लाइन बाय लाइन स्टेप थ्रू करना शुरू करने देगा।
तो क्या चल रहा है?
खैर, ध्यान दो कि टर्मिनल में अभी तक कुछ नहीं हुआ है।
क्यों?
क्योंकि मेरा कोड main के अंदर पॉज़ हो गया है।
विशेष रूप से, यह पहली वास्तविक कोड लाइन पर पॉज़ हो गया है।
तो कर्ली ब्रेस अरुचिकर है।
पहली लाइन बस फ़ंक्शन का नाम है, अनिवार्य रूप से।
तो लाइन 8 पहली रसीली कोड लाइन है जो संभवतः कुछ उपयोगी कर सकती है।
इसे यहाँ पीले में हाइलाइट किया गया है।
और तथ्य यह है कि यह कर्सर यहाँ है मतलब है कि हमने इस लाइन पर निष्पादन तोड़ा है,
लेकिन हमने अभी तक इस लाइन को निष्पादित नहीं किया है, यही वजह है कि टर्मिनल में, मुझे अभी तककुछ नहीं दिखता।मुझे निश्चित रूप से height के बाद कोलन नहीं दिखता।ध्यान दो और क्या हुआ है यहाँ।अचानक स्क्रीन के बाईं ओर जहाँ तुम्हारा फाइल एक्सप्लोरर आमतौर पर होता हैया जहाँ CS50 डक आमतौर पर होता है, हम वेरिएबल्स का उल्लेख देखते हैं।तुम वास्तव में डिबगर के अंदर देख सकते हो कि कंप्यूटर की मेमोरी में किसी भी वेरिएबल का मानक्या होता है।अब, मैं अभी इसे पूरी तरह नहीं समझता।हम समय के साथ इस पर वापस आएंगे।लेकिन अजीब तरह से, लाइन 8 के निष्पादित होने से पहले भी, ऐसा लगता हैकि h का डिफ़ॉल्ट मान 32,764 है, जो कहीं से आया लगता है।एक साइड नोट के रूप में, इसे गार्बेज वैल्यू कहा जाएगा।और यही वजह है कि हमारे पास ऑस्कर इतना सर्वव्यापी है यहाँ।एक गार्बेज वैल्यू एक वेरिएबल के अंदर एक डिफ़ॉल्ट मान होती है जोउस मेमोरी के पहले किसी और चीज़ के लिए उपयोग किए जाने का परिणाम होती है।तुम्हारे कंप्यूटर के अंदर, तुम्हारे पास यह सारी मेमोरी है, रैंडम एक्सेस मेमोरी,या RAM, आज उस पर और अधिक।और यह मानना उचित है कि मेरा कंप्यूटर, या जो भी क्लाउड सर्वर हम उपयोग कर रहे हैं,कुछ समय से रन हो रहा है।तो बिट्स जो h उपयोग करने जा रहा है उनमें पहले से कुछ रैंडम स्विच ऑन और ऑफ हो सकते हैं,बिट्स का कुछ रैंडम पैटर्न जो मुझे 32,764 देता है।लेकिन जिस क्षण यह कोड लाइन निष्पादित होती है,वह मान वास्तव में उसमें बदल जाएगा जो मैं चाहता था,जो मानव टाइप करने जा रहा है।इस बीच, यहाँ नीचे, तुम एक तथाकथित कॉल स्टैक देखोगे,इस पर भी आने वाले हफ्तों में और अधिक।लेकिन तुम देखोगे कि हम buggy.c नामक फाइल में main नामक फ़ंक्शन पर पॉज़ हुए हैं।
तो मैं कुछ उपयोगी कैसे करूँ?
खैर, डिबगर के बहुत ऊपर, तुम
रंग-कोडित आइकन का एक पूरा गुच्छा देखोगे।
एक प्ले बटन जैसा दिखता है।
और यदि मैं उस पर क्लिक करता हूँ, यह बस मेरे कोड के निष्पादन को जारी रखेगा
जैसे कि मैं अब इसे स्टेप थ्रू नहीं करना चाहता।
तो मैं अभी उस पर क्लिक नहीं करने जा रहा।
दूसरा एरो, जो एक डॉट के ऊपर थोड़ा मुड़ा हुआ एरो है,
तथाकथित स्टेप ओवर लाइन है, जिसका मतलब होगा इस लाइन पर स्टेप ओवर करो
और इसे निष्पादित करो, लेकिन सिर्फ एक लाइन एक समय में।
आइए ठीक वैसा ही करें।
तो मैं स्टेप ओवर आइकन पर क्लिक करने जा रहा हूँ, दूसरा वाला, जो
डॉट के नीचे मुड़ा हुआ एरो है।
क्लिक।
अब मैं अपनी टर्मिनल विंडो में height प्रॉम्प्ट होते देखता हूँ।
आइए आगे बढ़ें और 3 टाइप करें, जैसे मैंने पहले किया, और एंटर दबाएँ।
अब ध्यान दो क्या होता है।
निष्पादन लाइन 8 के बजाय लाइन 9 पर पॉज़ हो गया है।
और तुम देखोगे कि मेरा वेरिएबल, एक तथाकथित लोकल वेरिएबल,
इरादे के अनुसार 3 का मान रखता है।
ठीक है, अब तक, यह उतना ज्ञानवर्धक नहीं है सिवाय इस तथ्य के प्रदर्शन के
कि मैं अपने प्रोग्राम के निष्पादन को कभी भी पॉज़ कर सकता हूँ जब चाहूँ।
तो आइए अब उस स्टेप ओवर बटन पर फिर से क्लिक करें।
और फिर से, ताकि हम वास्तव में इस कॉलम को प्रिंट करें।
क्लिक।
और वहाँ हमारे पास है, स्क्रीन के नीचे चार हैश।
अब निष्पादन फ़ंक्शन के अंत में पॉज़ हो गया है।
यह मेरा अवसर है या तो रोकने का या रीस्टार्ट करने का या जारी रखने का।
मैं बस प्ले बटन पर क्लिक करने जा रहा हूँ और इसे समाप्त निष्पादित होने दूँगा।
दुर्भाग्य से, वह वास्तव में बिल्कुल भी ज्ञानवर्धक नहीं था, सिवाय मेरे लिए पुष्टि करने के
कि मैंने 3 टाइप किया, और 3 ही कंप्यूटर की मेमोरी में है।
अभी तक उतना दिलचस्प नहीं, हालाँकि।
तो आइए यह करें।
लाइन 6 पर ब्रेकपॉइंट को पहले की तरह छोड़ दो।
डिबगर को फिर से रन करो debug50, स्पेस, डॉट स्लैश buggy रन करके।
इसे अपना स्टार्टअप काम करने दो, जो पहले थोड़ा गड़बड़ लगता है,
लेकिन अब हमने लाइन 8 को फिर से हाइलाइट किया है।
मैं इस लाइन पर स्टेप ओवर करने जा रहा हूँ, क्योंकि मैं get int चाहता हूँ।
मैं फिर से 3 टाइप करने जा रहा हूँ, एंटर।
लेकिन इस बार, लाइन 9 पर स्टेप ओवर करने और बस print column
होने देने के बजाय, यह वह जगह है जहाँ डिबगर शक्तिशाली हो जाता है।
मुझे लाइन 9 में स्टेप इन करने दो और print column फ़ंक्शन
खुद को लाइन बाय लाइन चलाने दो।
तो मुझे इस बटन पर क्लिक नहीं करने दो, जो डॉट के ऊपर मुड़ा हुआ एरो है,
बल्कि अगले वाले पर, जो स्टेप इनटू बटन है।
क्लिक।
और अब तुम देखोगे कि निष्पादन print column के अंदर कूद गया है
और लाइन 14 पर पॉज़ हो गया है, जिस पर मैं ऊपर बाईं ओर देख सकता हूँ कि
i का डिफ़ॉल्ट मान क्या है।और यह कुछ पागल गार्बेज वैल्यू है, क्योंकि जो भी बिट्स i के मान को स्टोर करने के लिए उपयोग हो रहे हैंउनमें उस मेमोरी के पिछले उपयोग से कुछ रैंडम गार्बेज है।लेकिन जैसे ही लाइन 14 एक बार निष्पादित होती है, मुझे शर्त है कि i 0 का मान ले लेगा।तो आइए वह करें।मैं स्टेप ओवर पर क्लिक करने जा रहा हूँ, क्योंकि मुझे इसमें स्टेप इन करने की जरूरत नहीं है,क्योंकि वहाँ कोई अन्य फ़ंक्शन नहीं हैं, उस पर स्टेप ओवर करो।और तुरंत ऊपर बाईं ओर, i अब 0 है।अब लाइन 16 हाइलाइट है।आइए इस पर स्टेप ओवर करें।और टर्मिनल विंडो में ध्यान दो, तुम क्या देखते हो?हमारे हैशों में से पहला।आइए स्टेप ओवर, स्टेप ओवर, दूसरा हैश।और i अब 1 है।स्टेप ओवर, स्टेप ओवर।अब हम तीसरा हैश देखते हैं और i अब 2 है।स्टेप ओवर, स्टेप ओवर।ठीक है, वहाँ बग का लक्षण है।चार हैश।और फिर भी i 3 है।लेकिन रुकिए एक मिनट, यह अब मेरा ध्यान लाइन 14 की ओर आकर्षित करने जा रहा हैइससे पहले कि मैं आगे बढ़ूँ।रुकिए एक मिनट।3 बेशक 3 से कम या बराबर है,यही वजह है कि मुझे स्क्रीन पर वह चौथा हैश मिला।तो दिन के अंत में, तुम्हें अभी भी अपनी खुद की मानव बुद्धि का कुछ उपयोग करना होगायह पता लगाने और समझने के लिए कि क्या चल रहा है।लेकिन इस डिबगर का मूल्य यह है कि तुम पॉज़ कर सकते हो और चीज़ों के माध्यम से काम कर सकते होअपनी खुद की गति से और अपने खुद के कोड के अंदर घुसपैठ कर सकते होऔर बेहतर समझ सकते हो कि क्या हो रहा है इसके बजाय कि प्रोग्राम कंपाइल करो,इसे रन करो, और अब सिर्फ लक्षणों से अनुमान लगाना पड़ेकि समस्या का स्रोत क्या हो सकता है।तो वह बहुत कुछ था।मुझे यहाँ आगे बढ़ने दो और बस इसे अंत तक जारी रखने दूँ,क्योंकि मुझे अब पता है कि समस्या क्या है।मुझे less than or equal to साइन को सिर्फ less than में बदलना होगा।प्रश्न, हालाँकि, debug 50 पर, यदि तुम इनमें से कोई भी स्टेप हो।हाँ।ज़रूर।क्या तुम समझाते हो कि ब्रेकपॉइंट क्या है?और फिर मेरा दूसरा प्रश्न गार्बेज वैल्यू के आसपास है।दूसरी बार जब तुमने इसे रन किया, इसने अभी भी वही गार्बेज वैल्यू दीजो तुमने H को असाइन की थी।सही।तो तुम्हारे प्रश्नों के क्रम में, ये ब्रेकपॉइंट फिर से क्या हैं?ब्रेकपॉइंट या यहाँ छोटा लाल स्टॉप साइन बस डिबगर को बताता हैकहाँ निष्पादन पॉज़ करना है।तो ईमानदारी से, मुझे main पर निष्पादन पॉज़ नहीं करना पड़ा।यदि मुझे वास्तव में print column को डिबग करने की परवाह है,मैं यहाँ नीचे क्लिक कर सकता था।और फिर यह बस main को स्वचालित रूप से रन करता और केवल तब पॉज़ करताजब print column कॉल होता।तो एक ब्रेकपॉइंट वह जगह है जहाँ तुम्हारा कोड टूटेगा, वह बिंदु जिस पर यह टूटेगा।और गार्बेज वैल्यू के लिए, मैं कंप्यूटर की मेमोरी के अंदर वास्तव में क्या चल रहा हैउसे अति सरल बना रहा हूँ।और यह जरूरी नहीं कि पहले जैसी ठीक वही मेमोरी उपयोग कर रहा हो,लेकिन ऑपरेटिंग सिस्टम ठीक से नियंत्रित करेगा कि मेमोरी कैसे व्यवस्थित है।यह वास्तव में आज के कई सिस्टम में एक महत्वपूर्ण समस्या है, लंबी कहानी छोटी,क्योंकि मेरे लिए यह दिलचस्प नहीं है यह जानना कि वहाँ 32,000, जो भी वह संख्या है, या नकारात्मक संख्या थी।लेकिन मान लो कि उसने किसी के पासवर्ड का खुलासा किया, एक और प्रोग्रामया फ़ंक्शन जिसमें वहाँ कुछ जानकारी थी।डिबगर के साथ, अकेले C की बात छोड़ो, कंप्यूटर की मेमोरी में घुसपैठ करना बहुत आसान लगता है।और हम कुछ हफ्तों में उस पर वापस आएंगे।लेकिन अभी के लिए, यह एक गार्बेज वैल्यू है जहाँ तक तुमने वहाँ मान नहीं डाला।यह किसी तरह अपने आप वहाँ पहुँच गया अभी के लिए।अन्य प्रश्न?तो प्रश्न for लूप के संचालन के क्रम के बारे में है।तो पहली बार जब तुम for लूप से गुज़रते हो,इनिशियलाइज़ेशन होता है, पहली सेमीकोलन से पहले का सामान।और कंडीशन वास्तव में चेक होती है, बूलियन एक्सप्रेशन।फिर कर्ली ब्रेसेस के अंदर सब कुछ निष्पादित होता है।फिर इंक्रिमेंटेशन या अपडेट होता है, जो इस मामले में i++ है।और फिर कंडीशन फिर से चेक होती है, बूलियन एक्सप्रेशन।कोड निष्पादित होता है।अपडेट होता है।कंडीशन फिर।कोड अपडेट होता है।और तो यह इस तरह लूप होना शुरू होता है।डिबगर के ग्राफिक्स काफी सरल हैं,और यह पूरी लाइन को हाइलाइट करता है बिना यह बहुत स्पष्ट किए कि क्या हो रहा है।लेकिन वह बस for लूप की परिभाषा है।अच्छा प्रश्न।debug 50 या printf के बारे में अन्य?ठीक है।हाँ?क्या तुम i++ और i height की लोकेशन बदल सकते हो?क्या तुम i++ और height की स्थिति बदल सकते हो?संक्षिप्त जवाब, नहीं।पहली चीज़ इनिशियलाइज़ेशन है, वह वेरिएबल जो तुम बनाना और इनिशियलाइज़ करना चाहते हो।दूसरी चीज़ वास्तविक कंडीशन है, तथाकथित बूलियन एक्सप्रेशन।तीसरी चीज़ हमेशा अपडेट है।तो यह इस क्रम में आना चाहिए।जो तुम नहीं देख रहे हो वह यह है कि तुम्हारे पास वास्तव में कई बूलियन एक्सप्रेशन हो सकते हैं।तुम्हारे पास कई इनिशियलाइज़ेशन हो सकते हैं।तुम्हारे पास कई अपडेट हो सकते हैं।लेकिन हम अभी के लिए इसे सरल रख रहे हैं।और यह कैनोनिकल है।
ठीक है।
तो स्पष्ट करने के लिए, यह मानते हुए कि या तो printf या debug 50
ने मुझे यह पता लगाने में मदद की कि मेरे विचारों में लॉजिक कहाँ थी,
मुझे अब पता है कि यहाँ फिक्स बस less than or equal to
को सिर्फ less than में बदलना है।
और यदि मैं प्रोग्राम फिर से रन करूँ, बेशक,
यह मुझे तीन ईंटें देगा जो मैं हमेशा चाहता था।
लेकिन हम अन्य तकनीकों का भी उपयोग कर सकते हैं।
तो printf और debug के अलावा, तुम सोच सकते हो कि हमारे पीछे सात फुट का डक क्यों है,
फर्श पर ये सभी छोटे रबर डक।
तो रबर डक डिबगिंग सप्ताह शून्य के अनुसार वास्तव में एक चीज़ है।
यह कुछ साल पहले एक किताब में लोकप्रिय हुआ।
और विचार यह है कि जब तुम कुछ बग्स का सामना कर रहे हो, अपने प्रोग्राम में कुछ गलती,
या तुम किसी अवधारणा पर बस भ्रमित हो, वहाँ उपाख्यानात्मक सबूत हैं जो सुझाव देते हैं
कि बस एक निर्जीव वस्तु जैसे तुम्हारे डेस्क पर रबर डक के साथ समस्या के बारे में बात करना
अक्सर उस कहावत वाले लाइट बल्ब के लिए पर्याप्त होता है तुम्हारे सिर के ऊपर जलने के लिए
क्योंकि तुम अपने खुद के शब्दों में सुनते हो कि तुम्हारे पास क्या भ्रम है,
तुम्हारे पास क्या अतार्किक विचार हैं।
और तुम्हें कमरे में किसी और इंसान या TA या AI की भी जरूरत नहीं होती समस्या का जवाब देने के लिए।
तो वास्तव में, आज क्लास के अंत में बाहर निकलते समय,
हमारे पास सैकड़ों डक हैं और सबके लिए पर्याप्त हैं घर ले जाने के लिए
यदि तुम उसे एक और डिबगिंग तकनीक के रूप में उपयोग करना चाहो,
चाहे CS50 में हो या कुछ और में।
लेकिन बेशक, अब AI के युग में, तुम्हारे पास CS50.ai पर AI पावर्ड वर्चुअल डक भी है
और VS Code में भी CS50.dev पर, जो वास्तव में सवाल पूछने का एक तंत्र है
जिनके बारे में तुम सोचते हो कि तुम खुद हल नहीं कर सकते।
तो डक से पूछना उचित हो सकता है, इस त्रुटि संदेश का क्या मतलब है
यदि तुम्हें इसे समझने में परेशानी हो रही है?
लेकिन यह कम उचित है कि अपना कोड कॉपी पेस्ट करके डक में डालो और कहो,
मेरे कोड में क्या गलत है?
तुम्हें वास्तव में AI से आधा रास्ता मिलना चाहिए।
आखिरकार, वास्तव में यह या कोई और क्लास करने का बिंदु क्या है
वह मांसपेशी मेमोरी विकसित करना है, वे मानसिक मॉडल विकसित करना है,
कुछ व्यावहारिक कौशल प्राप्त करना है।
तो उस लाइन पर चलने की कठिन कोशिश करो कि डक से बहुत अधिक पूछने बनाम
इनमें से कुछ समान उपकरणों को खुद तैनात करने के बीच, printf, debug50, यहाँ तक कि एक भौतिक रबर डक
अपने डेस्क पर इससे पहले कि तुम इसे मानव-जैसे या डक मदद तक बढ़ाने का सहारा लो।
ठीक है, तो उन उपकरणों को किसी के टूलकिट में जोड़ने के साथ,
आइए वास्तव में विचार करें और प्रकट करें कि पिछले सप्ताह से हुड के नीचे क्या चल रहा है।
तो यह मानसिक मॉडल था जो हमने पिछले सप्ताह के लिए प्रस्तावित किया,
जहाँ जब तुम C जैसी भाषा में सोर्स कोड लिखते हो,
यह कुछ ऐसा नहीं है जो कंप्यूटर खुद मूल रूप से समझता हो,
क्योंकि कंप्यूटर हमने देखा केवल 0s और 1s समझते हैं, उर्फ मशीन कोड।
तो कंपाइलर वह प्रोग्राम है जिसका हम उपयोग तुम्हारे सोर्स कोड
को मशीन के कोड में बदलने के लिए करते हैं, इस मामले में C से 0s और 1 में।
अधिक सामान्यतः, एक कंपाइलर बस एक प्रोग्राम है जो एक भाषा को दूसरी में अनुवाद करता है।
और इस मामले में, हम सोर्स कोड से मशीन कोड की ओर जा रहे हैं।
तो आइए विचार करें कि वास्तव में क्या हो रहा है।
वास्तव में, यह इस सप्ताह के लक्ष्यों में शामिल है एक निचले स्तर पर नज़र डालना
ताकि जब तुम अधिक दिलचस्प, अधिक चुनौतीपूर्ण समस्याओं का सामना करो,
तुम तथाकथित प्रथम सिद्धांतों से समझोगे कि कंप्यूटर वास्तव में
क्या कर रहा है और क्या करना चाहिए ताकि तुम खुद के लिए निगमनात्मक रूप से चीज़ें पता लगा सको
और सामान्यतः कंप्यूटरों को जादू के रूप में न देखो, या मुझे नहीं पता कि यह कैसे काम करता है।
टर्म के अंत तक किसी भी कंप्यूटर, लैपटॉप, डेस्कटॉप फोन, या आजकल जैसी चीज़ों के अंदर
सब कुछ कैसे काम करता है इसका काफी नीचे से ऊपर का भाव होगा।
तो यहाँ सबसे सरल प्रोग्राम है जो हमने पिछले सप्ताह लिखा, भले ही वहाँ
बहुत सारी सिंटैक्टिक जटिलता है, जैसा हमने देखा।
लक्ष्य इसे मशीन कोड में लाना है।
ये यहाँ 0s और 1s हैं।
तो यह कैसे हो रहा है जब तुम पिछले सप्ताह से बस make रन करते हो?
खैर, ये दो कमांड हैं जो हम आमतौर पर
hello.c जैसी फाइल बनाने के बाद रन करते हैं।
हम फिर make hello के साथ कंपाइल करते हैं, और फिर हम इसे डॉट स्लैश hello के साथ रन करते हैं।
तो आइए खुद को यह शुरुआती बिंदु जल्दी दें,
बस ताकि हमारे मन में एक उदाहरण हो कि हम वास्तव में क्या कंपाइल कर रहे हैं।
तो मुझे यहाँ VS Code पर वापस जाने दो, buggy.c बंद करो,
और आइए पिछले सप्ताह की तरह एक नई फाइल बनाएँ जिसे hello.c कहा जाता है, जिसके अंदर
हमारा पुराना दोस्त, standard io.h, int main void,
और फिर इसके अंदर हम इसे सरल रखेंगे,
बस hello comma world प्रिंट करना, जो फिर से मेरा C में सोर्स कोड है।
मैं अब वास्तव में उसे कैसे कंपाइल करूँ?
खैर, बेशक, मैं अपनी टर्मिनल विंडो में जा सकता हूँ, make hello, डॉट स्लैश hello,
और हम चल पड़े।
तो यह मेरे लिए थोड़ा सफेद झूठ था तुम्हें सोचने देना, हालाँकि, कि पिछले सप्ताह
कंपाइलर खुद make कहलाता है।
Make एक कमांड है जो शाब्दिक रूप से तुम्हारा प्रोग्राम बनाता है।
यह कंपाइल करके बनाता है, लेकिन make तकनीकी रूप से कंपाइलर नहीं है।
यदि हम वास्तव में नुक्ताचीनी करना चाहें, तो कंपाइलर जिसका तुम उपयोग कर रहे होवास्तव में clang कहलाता है C language के लिए।और यह एक बहुत लोकप्रिय कंपाइलर है, स्वतंत्र रूप से उपलब्ध, ओपन सोर्स, बोलने के लिए।तुम कंपाइलर बनाने के लिए अन्य मनुष्यों द्वारा लिखा कोड ऑनलाइन भी देख सकते हो।और make वास्तव में हमारे लिए जो कर रहा है वह अनिवार्य रूप से इस कमांड को स्वचालित करना है।तो इस सारे समय मैं बस clang स्पेस hello.c रन कर सकता था,लेकिन clang, कंपाइलर से डिफ़ॉल्ट फाइल नाम,अजीब तरह से और ऐतिहासिक कारणों से, hello नहीं होने जा रहा जैसा तुम आशा करोगे,यह a.out होने जा रहा assembler output के लिए।और हम क्लास के सप्ताह एक में ऐसा नहीं करते,क्योंकि यह चीज़ों को अनावश्यक रूप से जटिल बना देता हैकि हम कुछ रैंडम नाम जोड़ रहे हैं जो तुम्हें बस टाइप करना जानना पड़ता है।हालाँकि, हम अब इस प्रकार कर सकते हैं।मुझे यहाँ VS Code पर वापस जाने दो।मुझे अपना टर्मिनल साफ करने दो और ls टाइप करो, और हम वह सब देखेंगे जो हमने अब तक बनाया है।buggy.c, जिसे जब मैंने कंपाइल किया, मुझे buggy मिला।और hello.c, जिसे मैंने अभी लिखा, और जब मैंने कंपाइल किया, मुझे hello मिला।आइए अब इस कमांड को मैन्युअली करें, हालाँकि।आइए hello.c पर clang उपयोग करें और एंटर दबाएँ।वह भी काम करता लगता है।लेकिन यदि मैं अब ls टाइप करूँ, तुम एक तीसरा प्रोग्राम देखोगे विशेष रूप से a.out कहा जाता है,जो hello जैसा ही होता है।यह बस मेरे कस्टम नाम hello के बजाय डिफ़ॉल्ट नाम उपयोग कर रहा है।लेकिन यदि मैं डॉट स्लैश a.out करूँ, वास्तव में, वह भी काम करेगा।लेकिन वजह हम वह नहीं करते, निश्चित रूप से कोर्स के पहले सप्ताह में,यह है कि चीज़ें थोड़ी परेशान करने वाली हो जाती हैं या उसके बाद तेज़ी से बढ़ जाती हैं।तो मुझे इस प्रोग्राम को बदलने दो जैसा हमने पहले ही कुछ बार किया है।मुझे cs50.h शामिल करने दो ताकि हमें get string की पहुँच मिले।मुझे string name equals get string करने दो, quote unquote,what’s your name, प्रश्न चिह्न, close quote।और फिर यहाँ नीचे, ठीक पहले की तरह, मुझे अपना percent s जोड़ने दो और अपना name जोड़ने दो।तो मैंने वह बहुत जल्दी किया।लेकिन यह वही प्रोग्राम है जो हमने कुछ मिनट पहले लिखा,और यह वही है जो हमने पिछले सप्ताह लिखा।अब क्या होता है, हालाँकि, इस प्रकार है।यदि मैं अब clang hello.c एंटर करने की कोशिश करूँ, मुझे वास्तव में एक त्रुटि संदेश मिलता है।यह शायद अधिकांश से अधिक क्रिप्टिक है।किसी तरह, मेरे पास यह त्रुटि है।Linker command failed with exit code 1 क्योंकि get string के लिए undefined reference।अब, अतीत में, जब हमने get string के undefined या वास्तव में undeclared उल्लेख देखे,समस्या बस इस लाइन के गायब होने से थी।यह लाइन स्पष्ट रूप से यहाँ है।लेकिन पकड़ यह है कि मुझे यह त्रुटि संदेश अब मिल रहा हैक्योंकि जब मैं clang of hello.c रन करता हूँ, मैं बस मान रहा हूँकि clang जानता है कि get string के cs50 संस्करण को कहाँ खोजना है।और वह मामला नहीं है।तकनीकी रूप से, यदि मैं चाहता हूँ कि कंपाइलर मेरे लिए इस कोड को कंपाइल करे,मुझे वास्तव में यह करना होगा।मुझे अपनी टर्मिनल विंडो पर वापस जाने दो।और मैं कहूँगा clang hello.c।लेकिन फिर मैं dash lcs50 निर्दिष्ट करने जा रहा हूँ, जो पहली नज़र में क्रिप्टिक है।लेकिन यह कंपाइलर को बता रहा है कि cs50 लाइब्रेरी को लिंक इन करेताकि यह जान सके कि get string फ़ंक्शन से संबंधित 0s और 1s क्या हैं।लंबी कहानी छोटी, यदि मैं अब एंटर दबाऊँ, त्रुटि संदेश चला गया है।यदि मैं ls टाइप करूँ, मेरे पास अभी भी a.out है, लेकिन यह उसका एक नया संस्करण है।और यदि मैं डॉट स्लैश a.out करूँ, अब मैं नया व्यवहार देखता हूँ जहाँ मैं अपना नाम टाइप कर सकता हूँऔर hello, David देख सकता हूँ।अब, यह थोड़ा बेवकूफी भरा हो रहा है कि मैं a.out का उपयोग करता रहता हूँ।हम उसे भी बदल सकते हैं।वास्तव में, ये कमांड, जैसा हम देखना शुरू कर रहे हैं,कमांड लाइन आर्गुमेंट्स का समर्थन करते हैं।और बहुत से प्रोग्राम जो हमने पहले ही रन किए हैं कमांड लाइन आर्गुमेंट्स लेते हैं।जब हम code, स्पेस, hello.c रन करते हैं, code के लिए तथाकथित कमांड लाइन आर्गुमेंटhello.c है।जब मैं make hello रन करता हूँ, make के लिए कमांड लाइन आर्गुमेंट hello है।दूसरे शब्दों में, एक प्रोग्राम के लिए कमांड लाइन आर्गुमेंट्सवे सभी शब्द हैं जो तुम अपने टर्मिनल में प्रोग्राम के नाम के बाद टाइप कर रहे होखुद, चाहे वह make हो या code या कुछ और।तो यह कहना है, जो मैंने अभी रन किया, clang of hello.c -lcs50,मैं दो कमांड लाइन आर्गुमेंट्स पास कर रहा था, hello.c, जो कोड हैजिसे मैं कंपाइल करना चाहता हूँ, और dash lcs50, जिसका मतलब है कृपया cs50 लाइब्रेरी उपयोग करो।लेकिन मैं मिक्स में एक और जोड़ सकता हूँ।मैं वास्तव में कुछ ऐसा कर सकता हूँ, जहाँ मैं clang dash o hello करता हूँ,फिर मैं hello.c कर सकता हूँ और फिर dash lcs50 एंटर।अब वह भी काम करता लगता है।और यदि मैं ls टाइप करूँ, खैर, मेरे पास पहले जैसे सभी प्रोग्राम हैं।तो आइए आगे बढ़ें और उन्हें हटा दें यह स्पष्ट करने के लिए कि क्या चल रहा है।मैं a.out हटाऊँगा।मैं hello हटाऊँगा।और अच्छे माप के लिए, मैं buggy भी हटा दूँगा,ताकि इस फोल्डर में मेरे पास सिर्फ सोर्स कोड बचे।तो यदि मैं ls टाइप करूँ, वहाँ मेरी दो फाइलें हैं।आइए यह फिर से करें।Clang dash o hello, hello.c -lcs50 एंटर।अब यदि मैं ls टाइप करूँ, मुझे अब a.out नहीं दिखता,क्योंकि जाहिर है, clang, वास्तविक कंपाइलर के डॉक्यूमेंटेशन के अनुसार,यदि तुम dash o को कमांड लाइन आर्गुमेंट के रूप में पास करते हो, उसके बाद अपनी पसंद का एक और शब्द,तुम प्रोग्राम को कुछ भी नाम दे सकते हो बिना mvया उस पर क्लिक करके और मैन्युअली नया नाम टाइप किए।तो यदि मैं अब डॉट स्लैश hello करूँ, मैं ठीक वैसा ही संस्करण देखता हूँ जहाँ यह बसमुझे मेरे नाम के लिए पूछ रहा है और फिर इसे प्रिंट कर रहा है।लेकिन लंबी कहानी छोटी, इस अभ्यास का पूरा बिंदुयह है कि इस तरह के कमांड रन करना जल्दी बहुत थकाऊ हो जाता है।तुम्हें याद रखना पड़ता है कि किस क्रम में करना है, कमांड लाइन आर्गुमेंट क्या है।मेरा मतलब है, यह बस समय की बेवकूफी भरी बर्बादी है।आमतौर पर, निश्चित रूप से कोर्स के सप्ताह एक में,तुम्हें चीज़ों को काम करने के लिए इस तरह के जादुई कमांड याद रखने पड़ते हैं।लेकिन अभी के लिए, नहीं, कि जब तुम make रन करते हो, यहअनिवार्य रूप से वह सब तुम्हारे लिए स्वचालित कर रहा है और इसे सिमेंटिक रूप से सरल बना रहा हैजैसे make hello या make buggy।लेकिन वास्तव में जो हो रहा है वह make कमांड है,जिस तरह से हमने cs50.dev को तुम्हारे लिए कॉन्फ़िगर किया है,वह सब पर्दे के पीछे कर रहा है।यह उतना जादुई नहीं है।इसका बस मतलब है कंपाइल करते समय फाइल नाम को hello में बदलो।इसका बस मतलब है इस कोड को कंपाइल करो।और इसका बस मतलब है cs50 लाइब्रेरी उपयोग करो।जैसे बस इतना ही।लेकिन उस संदेश के बारे में कुछ लिंक इन करने का,वहाँ कुछ रसीली बात चल रही है जैसे कि make वास्तव मेंकंपाइल करते समय समस्याओं के एक पूरे गुच्छे को हल करने में हमारी मदद कर रहा है।
और वास्तव में, मुझे प्रस्ताव करने दो कि यदि हम एक कदम पीछे हटें
और कुछ वास्तविक कोड देखें जो हम कंपाइल कर रहे हैं,
आइए विचार करें कि हम कंपाइलिंग से वास्तव में क्या मतलब रखते हैं।
हाँ, यह मामला है कि अपने कोड को कंपाइल करने का मतलब है
सोर्स कोड से मशीन कोड जाना।
लेकिन तकनीकी रूप से, कुछ और स्टेप्स शामिल हैं।
तकनीकी रूप से, जब तुम अपना कोड कंपाइल करते हो, वह तरह का
उद्योग का कला शब्द बन गया है जो वास्तव में चार अलग प्रक्रियाओं को संदर्भित कर रहा है,
जो सभी स्वचालित रूप से उत्तराधिकार में हो रही हैं,
लेकिन जिनमें से प्रत्येक एक अलग चीज़ कर रही है।
तो बस एक बार, आइए इन कई स्टेप्स के साथ चलें।
तो यह प्री-प्रोसेसिंग स्टेप क्या है?
तो इस प्रोग्राम पर विचार करो यहाँ, जिसे हमने पिछले सप्ताह संक्षेप में लिखा।
हमारे पास includestandardio.h है, जो वहाँ है क्योंकि हम अंततः
printf का उपयोग करने में सक्षम होना चाहते हैं।
फिर हमारे पास इस meow फ़ंक्शन के लिए एक प्रोटोटाइप है।
और meow फ़ंक्शन यह करता है।
यह बस quote unquote meow प्रिंट करता है उसके बाद एक न्यू लाइन,
कोई इनपुट नहीं लेता, कोई रिटर्न वैल्यू नहीं लौटाता।
Main फ़ंक्शन में अब एक for लूप है, तीन बार इटेरेट करता है,
प्रत्येक बार meow फ़ंक्शन को कॉल करता है।
और हमने यह पहले ही आज देखा।
यह कोड लाइन यहाँ, तथाकथित प्रोटोटाइप, आवश्यक है
क्योंकि हमें कंपाइलर को बताना होगा कि meow मौजूद है इससे पहले कि हम वास्तव में इसे यहाँ उपयोग करें,
विशेष रूप से यदि मैं इसे बाद तक लागू नहीं करता।
तो उस पहली कोड लाइन का यह कॉपी-पेस्ट, एक तथाकथित प्रोटोटाइप,
उस समस्या को हल किया।
यही हेडर फाइलें अनिवार्य रूप से हमारे लिए कर रही हैं।
इससे पहले कि मैं यहाँ नीचे printf का उपयोग करूँ, कंपाइलर को
जानने की जरूरत है कि यह क्या है, इसके इनपुट क्या हैं, इसके आउटपुट क्या हैं।
पता चलता है कि printf का प्रोटोटाइप standard io.h में होने जा रहा है।
और यही वह कोड लाइन हमारे लिए इस सारे समय कर रही है।
वास्तव में, आइए एक सरल उदाहरण लें जिसका हम यहाँ उपयोग करते रहते हैं,
जहाँ मैं cs50.h और standard io.h शामिल कर रहा हूँ।
और मैं cs50 getString फ़ंक्शन का उपयोग किसी का नाम पाने के लिए कर रहा हूँ
और इसे name नामक वेरिएबल में डाल रहा हूँ।
और फिर मैं hello comma ऐसा और वैसा प्रिंट कर रहा हूँ।
अब क्या हो रहा है जब मैं इस फाइल को प्री-प्रोसेस करता हूँ
make रन करके, जो बदले में clang रन करता है?
खैर, कंपाइलर सर्वर की हार्ड ड्राइव पर
cs50.h नामक फाइल ढूँढता है, अंदर जाता है और अनिवार्य रूप से कॉपी
और पेस्ट करता है इसकी सामग्री को मेरे खुद के कोड में।
इस बीच, जैसे कि हमें getString के लिए प्रोटोटाइप वहाँ मिलता है।
और हमने यह अभी तक नहीं देखा, लेकिन यह मानना उचित है
कि इस सारे समय printf का उपयोग करते हुए, हम एक प्रॉम्प्ट पास कर रहे हैं, जैसे what’syour name, और हमें एक स्ट्रिंग वापस मिल रही है।पेरेंटहेसिस के अंदर क्या है याद करो वह इनपुट है।फ़ंक्शन नाम से पहले क्या है वह आउटपुट है, तथाकथित रिटर्न वैल्यू।Standard io.h के बारे में क्या?उस फाइल में printf का प्रोटोटाइप है।तो अनिवार्य रूप से कंपाइलर इस फाइल को प्री-प्रोसेस करते समय क्या करता हैवह सर्वर की हार्ड ड्राइव पर कहीं standard io.h ढूँढता है, अंदर जाता हैऔर उन प्रासंगिक कोड लाइनों को मेरे कोड में भी कॉपी और पेस्ट करता है।यह मुझे वह सब खुद करने से बचाने के लिए है, फाइल ढूँढना, कॉपी,पेस्ट करना, या मैन्युअली प्रोटोटाइप टाइप करना।ये प्री-प्रोसेसर डायरेक्टिव बस उस सभी थकावट को स्वचालित करते हैं।तो प्रभावी रूप से मेरे कोड के शीर्ष पर फाइल प्री-प्रोसेस होने के बाद क्या होता हैवे सभी हैश सिंबल, उसके बाद include,उन हेडर फाइलों की वास्तविक सामग्री रखने के लिए बदल दिए जाते हैं।अब कंपाइलर जानता है कि getString क्या है और printf क्या है।वह फिर प्री-प्रोसेसिंग स्टेप है।
कंपाइलिंग तकनीकी रूप से क्या मतलब रखती है?
कंपाइलिंग का मतलब है उस प्री-प्रोसेस्ड कोड को लेना, जो फिर से कुछ ऐसा दिखता है
जैसे यह, और इसे असेंबली कोड नामक किसी चीज़ में बदलना।
और हम इस क्लास में असेंबली कोड पर ज्यादा समय नहीं बिताएंगे,
लेकिन प्रोग्रामर इसी तरह कोड लिखा करते थे।
C से पहले, Python और Java से पहले,
और इन सभी अन्य आधुनिक भाषाओं से पहले, प्रोग्रामर इस तरह कोड लिख रहे थे।
इसके मौजूद होने से पहले, वे शुरुआती
मेनफ्रेम कंप्यूटरों में पंच कार्ड्स और अन्य तकनीकों का उपयोग करके ज़ीरोस और वन्स प्रोग्राम कर रहे थे,
जैसे शाब्दिक रूप से छेद वाले कागज की शीट्स।
बहुत मज़ेदार नहीं, बहुत थकाऊ, तो दुनिया ने यह आविष्कार किया।
उतना मज़ेदार नहीं, तो दुनिया ने Python और इसी तरह आविष्कार किया,
कि हम कोड के साथ एक प्रजाति के रूप में विकसित होते रहते हैं।
लेकिन कंपाइलर तकनीकी रूप से तुम्हारे प्री-प्रोसेस्ड सोर्स कोड को लेता है
और इसे कुछ ऐसा बदल देता है जो इस तरह दिखता है, क्रिप्टिक।
और वह अपेक्षित है, लेकिन कुछ परिचित वाक्यांश हैं।
main का उल्लेख है, getString का उल्लेख है,
printf का उल्लेख है।
और बहुत सारी अन्य चीज़ें हैं।
Move और push और xor और call और ये अन्य कमांड यहाँ।
ये असेंबली इंस्ट्रक्शन्स हैं।
वे सबसे निचले स्तर के इंस्ट्रक्शन्स हैं जो कंप्यूटर के अंदर CPU समझता है।
CPU सेंट्रल प्रोसेसिंग यूनिट है।
Intel या AMD या Apple या अन्य कंपनियों द्वारा बनाई चीज़,
वे सबसे निचले स्तर के कमांड हैं जो कंप्यूटर के अंदर वास्तविक हार्डवेयर समझते हैं।
यह बस अच्छा है main और for और printf जैसे शब्द लिखने में सक्षम होना,
फिर इन बहुत अधिक रहस्यमय कमांड्स को रन करना होगा
जिन्हें तुम्हें एक मैनुअल में देखना पड़ता।
तो कंपाइलिंग बस C कोड लेती है और इसे असेंबली नामक निचले स्तर के कोड में बनाती है।
जब मैंने कहा a.out का मतलब assembler output है,
यही वजह है कि उस फाइल के अंदर अनिवार्य रूप से एक असेंबलर का आउटपुट है।
ठीक है, हम लगभग वहाँ हैं।
एक प्रोग्राम को असेंबल करने का क्या मतलब है,
जो कंपाइलेशन प्रक्रिया का स्टेप तीन है?
उसका मतलब है असेंबली कोड को वास्तविक ज़ीरोस और वन्स में बदलना जिनके बारे में हम बात करते रहते हैं।
तो यदि फाइल hello.c कहलाती है,
जब वह फाइल असेंबल होती है,
असेंबली कोड hello.c में तुम्हारे कोड के लिए ज़ीरोस और वन्स बन जाता है।
लेकिन तुम्हारा कोड वह सब नहीं है जो तुम्हारे अंतिम प्रोग्राम को बनाता है।
hello.c से तुम्हारा कोड CS50 की लाइब्रेरी के कोड के साथ जोड़ा जाना है,
स्टैंडर्ड IO लाइब्रेरी से जो अन्य मनुष्यों ने लिखा।
मैं और टीम ने CS50 कोड लिखा।
दुनिया में अन्य मनुष्यों ने printf कोड और स्टैंडर्ड IO लिखा।
तो अनिवार्य रूप से, चौथा और अंतिम स्टेप
उन सभी ज़ीरोस और वन्स को एक साथ लिंक करना है।
सर्वर पर कहीं, सिर्फ हेडर फाइल नहीं है,
CS50.h और standard IO.h, बल्कि तुम्हारा कोड, hello.c,
हमारा कोड, CS50.c, और वह कोड जिसमें printf का खुद का इम्प्लीमेंटेशन है।
थोड़ा सफेद रेखा।
यह तकनीकी रूप से standard IO.c नहीं कहलाता,
लेकिन बिंदु अंततः वही रहता है।
तो ये फाइलें तुम्हारे लिए पहले से ही कंपाइल की जा चुकी हैं।
यह तुम्हारा कोड है।
असेंबली प्रक्रिया जो करती है वह यह सब ज़ीरोस और वन्स में जोड़ती है,
और फिर ज़ीरोस और वन्स के सभी तीन चंक्स लिंक हो जाते हैं।
तो यदि तुम वापस सोचो जब मैंने dash LCS50 के बिना कोड कंपाइल करने की कोशिश की,
वहाँ लिंककर का कुछ उल्लेख था।
लिंकिंग का बस मतलब है कंप्यूटर नहीं जानता था
तुम्हारे कोड को CS50 के कोड के साथ कैसे लिंक करना है, क्योंकि हम dash LCS50 गायब थे,
जो कंपाइलर को हार्ड ड्राइव पर कहीं इसे ढूँढने के लिए कहता है।
और अंतिम स्टेप, फिर, लिंकिंग का उन सभी ज़ीरोस और वन्स को
एक बड़े ब्लोब में जोड़ना है, और यही
तुम्हारे hello प्रोग्राम के अंदर है जिसे तुम निष्पादित कर सकते हो।
तो लंबी कहानी छोटी, ये चार स्टेप्स हैं जो पिछले सप्ताह की शुरुआत से
हो रहे हैं।
प्री-प्रोसेसिंग, कंपाइलिंग, असेंबली, और लिंकिंग।
लेकिन thankfully, प्रोग्रामरों की दुनिया आम तौर पर
इन चारों स्टेप्स को वह मानती है जिसे हम अब कंपाइलिंग के रूप में जानते हैं।
यह बस बहुत से उपयोगकर्ता कंपाइल कहते हैं और
उन निचले स्तर के विवरणों के बारे में चिंता नहीं करते।
लेकिन वह तुम्हें बेहतर प्रकट कर सकता है कि इन सभी त्रुटि संदेशों का क्या मतलब है
जब तुम इस तरह की शब्दावली के संकेत देखते हो।
उसमें से किसी और सभी पर प्रश्न?
यहाँ से आगे, हम निचले से ऊँचे स्तर पर जाएंगे।
हाँ।
मुझे वह हिस्सा समझ नहीं आया, जैसे, जब हम बात कर रहे थे,
मुझे लगता है कि यह असेंबली प्रक्रिया है।
जब तुम इसे देखते हो, यह ज़ीरोस और वन्स हैं।
यह, जैसे, कई, जैसे, दो अलग-अलग पर नहीं जाता।
तो यदि पाँच अलग चीज़ों में ज़ीरोस और वन्स हैं,और एक पाँच टेक्स्ट में है, और दूसरा पाँच किसी और चीज़ में है,कंप्यूटर कैसे जानता है, जैसे, कौन सा हिस्सा, कौन सा आठकिस हिस्से से मेल खाता है?वाकई अच्छा प्रश्न।कंप्यूटर कैसे जानता है कि उन ज़ीरोस और वन्स में से कौन सा डेटा से मेल खाता है,जैसे संख्याएँ या टेक्स्ट की स्ट्रिंग्स या वास्तविक कमांड्स?हम क्लास के सप्ताह चार में उस पर वापस आएंगे।लेकिन लंबी कहानी छोटी, जो हमने स्क्रीन पर अभी देखाज़ीरोस और वन्स का एक बड़ा ब्लोब वास्तव में कुछ पैटर्न का पालन करता है,जहाँ ऊपर के बिट्स एक निश्चित कार्यक्षमता दर्शाते हैं।नीचे के बिट्स कुछ और दर्शाते हैं,और वे पैटर्न में व्यवस्थित हैं।तो लंबी कहानी छोटी, हम उस पर वापस आएंगे, लेकिन वे कन्वेंशन का पालन करते हैं।यह सिर्फ ज़ीरोस और वन्स का गड़बड़ नहीं है।अन्य प्रश्न?सही।प्रीप्रोसेसिंग स्टेप हेडर फाइल में जाता हैऔर अनिवार्य रूप से इसकी सामग्री को तुम्हारे खुद के कोड में कॉपी और पेस्ट करता हैताकि तुम्हें वह मैन्युअली खुद करने में समय बर्बाद न करना पड़े।अन्य प्रश्न?नहीं।तो जब तुम अपना कोड कंपाइल करते हो, तुम असेंबली कोड से ज़ीरोस और वन्स की ओर जा रहे हो।सॉरी।जब तुम कंपाइल करते हो, मुझे चार्ट फिर से खींचने दो।जब तुम अपना कोड कंपाइल करते हो, तुम C कोड से असेंबली कोड की ओर जा रहे हो।और पैटर्न जो तुम्हें असेंबली कोड देखने पर मिलते हैंएक निश्चित CPU के लिए विशिष्ट हैं।तो लंबी कहानी छोटी, यदि तुम iPhonesया Android डिवाइसेस या Macs या PCs के लिए सॉफ्टवेयर डिज़ाइन कर रहे हो, तुम्हें जरूरी रूप से एक अलग कंपाइलर उपयोग करना होगा।क्योंकि उसी C कोड को दिए जाने पर, तुम्हें आउटपुट में अलग असेंबली इंस्ट्रक्शन्स मिलेंगे।और यही वजह है कि तुम बस नहीं ले सकते, पुराने दिनों में,जैसे Mac से प्रोग्राम वाली CD और इसे PC पर रन करो या इसके विपरीत,क्योंकि यह इंस्ट्रक्शन्स के गलत पैटर्न हैं।लेकिन वजह हम जटिलता की इन सभी परेशान करने वाली परतों के लिए हैक्योंकि, एक, चार अलग लोग अब कंपाइलिंग की धारणा को इम्प्लीमेंट कर सकते हैं।कोई प्रीप्रोसेसर इम्प्लीमेंट कर सकता है।कोई कंपाइलर, असेंबलर, लिंककर इम्प्लीमेंट कर सकता है।और तुम वास्तव में इन क्वांटाइज्ड स्टेप्स में चीज़ों को तोड़कर सहयोग कर सकते हो।लेकिन भी, तुम यह स्टेप, यह स्टेप कर सकते हो।और फिर दो अलग लोग कंपाइलर लिख सकते हैं जो वास्तव में असेंबली कोड आउटपुट लिखने के लिएजैसे यहाँ iPhones के लिए और यहाँ Android डिवाइसेस के लिए।लेकिन हम सब अभी भी यहाँ ऊपर वही भाषा उपयोग करने का आनंद ले सकते हैं।तो इस जटिलता के लिए बहुत सारे कारण हैं।बस इसे समझना उपयोगी है, लेकिन तुम्हें दिन-प्रतिदिन इस तरह के ज्ञान का उपयोग करने की जरूरत नहीं होगी।लेकिन यह है जो आज की इतनी जटिलता को फिर भी सक्षम बनाता है।
ठीक है।
तो अब एक फूलिश के रूप में कि हम कंपाइलिंग के साथ क्या कर रहे हैं।
खैर, कंपाइलिंग अंततः सोर्स कोड से मशीन कोड जाना है।
क्या तुम बस प्रक्रिया को उल्टा नहीं कर सकते?
सही?
यदि किसी ने वास्तव में दिलचस्प सॉफ्टवेयर लिखा, जैसे Microsoft Word या Excel या कुछ ऐसा,
खैर, जब मैं इसे खरीदता हूँ या डाउनलोड करता हूँ, जैसे मेरे पास शाब्दिक रूप से उन सभी ज़ीरोस और वन्स की कॉपी है,
क्या मैं बस प्रक्रिया को उल्टा नहीं कर सकता और किसी और के कोड को रिवर्स इंजीनियर नहीं कर सकता
इसे डिकंपाइल करके?
और यह वास्तव में एक खतरा है।
और यह कानून और बौद्धिक संपदा के मामलों में आता है,
क्योंकि ज़ीरोस और वन्स तुम्हारे और तुम्हारे कंप्यूटर के लिए सुलभ होने चाहिए।
तो यह अच्छा एहसास नहीं है यदि किसी के पास पर्याप्त समय और पर्याप्त चतुराई हो तो वह Microsoft Word को फिर से बना सके
बस यह पता लगाकर कि उन सभी ज़ीरोस और वन्स का क्या मतलब है।
हालाँकि, इन ज़ीरोस और वन्स से कोड को रिवर्स इंजीनियर करना कहने से आसान है।
उदाहरण के लिए, स्क्रीन पर बिट्स का यह पैटर्न क्या करता था?
क्या हमने पिछले सप्ताह कहा?
मूर्खतापूर्ण प्रश्न।
कोई सामान्य व्यक्ति इसका जवाब नहीं दे पाएगा।
लेकिन मैंने पहले कहा था।
ये ज़ीरोस और वन्स क्या प्रिंट करते हैं?
यह बस hello world प्रिंट करता है।
और मैं उसे देखकर और अपने सिर के ऊपर से पता नहीं लगा सकता।
लेकिन यदि मैं जानता हूँ कि कौन सा आर्किटेक्चर, कौन सा CPU यह कोड कंपाइल किया गया है,
और मैं सप्ताह चार में ध्यान देता हूँ और जानता हूँ कि ज़ीरोस और वन्स का विभिन्न लेआउट क्या है,
मैं मेहनत से पता लगा सकता हूँ कि ज़ीरोस और वन्स के प्रत्येक पैटर्न का क्या मतलब है
उन्हें 8 या 16 या 32 या 64 के चंक्स में तोड़कर,
जो माप की आम इकाइयाँ हैं जिनकी मैंने पिछले सप्ताह ओर इशारा किया।
अब, वह पागल मात्रा का समय लेने वाला होगा।
और तरह की धारणा यह है कि यदि तुम इतने स्मार्ट और सक्षम हो
और उसके लिए पर्याप्त खाली समय हो, तो शायद तुम्हें कम समय लगे
बस Microsoft Word को सामान्य तरीके से इम्प्लीमेंट करने और सॉफ्टवेयर को फिर से बनाने में।
रिवर्स में जाने में तुम्हें आगे की दिशा में जाने से अधिक समय लगेगा।
लेकिन अन्य सूक्ष्मताएँ भी हैं।
इस कोड के अंदर न केवल printf जैसे कमांड हैं, printf जैसे फ़ंक्शन,
लेकिन मान लो कि इसमें एक लूप था, उदाहरण के लिए, meow, meow, meow प्रिंट करने के लिए।
खैर, हम पहले से जानते हैं कि तुम कभी-कभी for लूप का उपयोग कर सकते हो,
या तुम while लूप का उपयोग कर सकते हो, लेकिन वे कार्यात्मक रूप से समकक्ष हैं।
यह तरह की शैलीगत निर्णय है, तुम कौन सा उपयोग करते हो, जो भी तुम्हें अधिक सहज लगे,
या शायद थोड़ा बेहतर डिज़ाइन महसूस हो।
लेकिन तुम ज़ीरोस और वन्स से पता नहीं लगा सकते कि यह while लूप था
या for लूप क्योंकि यह बस ज़ीरोस और वन्स का वही पैटर्न परिणाम देता है।
यह बस एक प्रोग्रामर की पसंद है, जो कहना है, तुम सब कुछ पूरी तरह से रिवर्स इंजीनियर भी नहीं कर सकतेक्योंकि ज़ीरोस और वन्स से यह स्पष्ट नहीं होगा कि सोर्स कोड मूल रूप से कैसा दिखता था।लेकिन फिर से, बड़ा डील ब्रेकर यह है कि यदि तुम्हारे पास इतना समय और ऊर्जा और चतुराई है,बस Microsoft Word को खुद फिर से इम्प्लीमेंट करो, पूरी प्रक्रिया को उल्टा करने की कोशिश मत करो,जो बहुत अधिक मेहनत और समय लेने वाली होने वाली है।अब, यह सभी भाषाओं के लिए सच नहीं है।और बस एक टीज़र के रूप में कुछ हफ्तों में, जब हम वेब प्रोग्रामिंगऔर JavaScript नामक एक और भाषा के बारे में बात करेंगे,पता चलता है कि JavaScript सोर्स कोड वास्तव में वेब सर्वर्स से वेब ब्राउज़र्स को भेजा जाता है।और तुम इंटरनेट पर किसी भी वेबसाइट का सोर्स कोड देख सकते हो, harvard.edu, facebook.com, gmail.com।यह वहाँ होने जा रहा है।तो सभी भाषाएँ, पता चलता है, आमतौर पर कंपाइल भी नहीं होतीं।कभी-कभी सोर्स कोड बस अंतर्निहित कंप्यूटर द्वारा निष्पादित होता है।तो हम इस सब के कुछ निहितार्थों की सतह को बस खरोंच रहे हैं।थोड़े समय में, आइए आगे हुड के नीचे वास्तविक मेमोरी पर नज़र डालें,कुछ अन्य समस्याएँ हल करें।लेकिन मुझे लगता है कि अब चीज़ के लिए समय है।तो आइए 10 मिनट का ब्रेक लें।स्नैक्स अब सर्व किए जा रहे हैं।10 में मिलते हैं।
भाग 1 समाप्त। भाग 2 जारी...
रुक क्यों गए, कसम भूल गए क्याThought for 1m 51s
भाग 2
ठीक है।
हम वापस आ गए हैं।
और अब तक, जब हम कोड लिख रहे थे,
याद करो कि हमें निर्दिष्ट करना पड़ता है कि तुम वेरिएबल में किस प्रकार का मान डालना चाहते हो।
यही वजह है कि मुझे आज अपने पहले बग में name शब्द से पहले string जोड़ना पड़ा।
लेकिन पता चलता है कि C में, जैसा हमने पहले ही देखा है, इन डेटा टाइप्स का एक पूरा गुच्छा है।
मैंने इन्हें पिछले सप्ताह गिना था, bool, int, long, float, double, char, string।
लेकिन हम एक पल के लिए विचार करेंगे कि इनमें से प्रत्येक कितनी जगह लेता है
और देखेंगे कि क्या हम तुम्हें दिखा सकते हैं कि डिबगर पहले क्या देख रहा था।
अर्थात् मेमोरी में क्या कहाँ है।
तो एक bool, पता चलता है, वास्तव में एक बाइट लेता है, जो तरह का बेवकूफी भरा है
क्योंकि तकनीकी रूप से एक bool, true या false, वास्तव में सिर्फ एक बिट की जरूरत होती है।
बस पता चलता है कि पूरी बाइट, आठ बिट्स का उपयोग करना अधिक कुशल और आसान है,
भले ही उनमें से सात प्रभावी रूप से अनुपयोगी हों।
तो एक bool एक बाइट लेगा भले ही यह सिर्फ true और false हो।
एक int याद करो चार बाइट्स का उपयोग करता है।
तो यदि तुम int के साथ वास्तव में ऊँचा गिनना चाहते हो,
सबसे ऊँचा तुम जा सकते हो वह लगभग 4 बिलियन है, हमने दावा किया।
जब तक कि तुम नकारात्मक संख्याएँ दर्शाना नहीं चाहते, जिस मामले में सबसे ऊँचा लगभग 2 बिलियन है,
क्योंकि यदि तुम नकारात्मक 2 बिलियन तक गिनने में सक्षम होना चाहते हो,
तुम्हें अंतर को तरह से विभाजित करना होगा।
एक long, इस बीच, उसका दोगुना है।
यह 8 बाइट्स का उपयोग करता है, जो लगभग 9 क्वाड्रिलियन संभावनाएँ हैं,
जो 4 बिलियन से काफी अधिक हैं।
अर्थात्, यदि तुम नकारात्मक संख्याएँ भी शामिल करना चाहते हो।
फिर हमारे पास floats थे, जो दशमलव बिंदुओं वाली वास्तविक संख्याएँ थीं,
जो बताती हैं कि तुम महत्वपूर्ण अंकों के साथ कितने सटीक हो सकते हो।
एक float डिफ़ॉल्ट रूप से चार बाइट्स है।
लेकिन एक double तुम्हें खेलने के लिए दोगुने बिट्स देता है,
जो तुम्हें और अधिक सटीक होने देता है भले ही दिन के अंत में,
floats या doubles का उपयोग करते हुए, फ्लोटिंग पॉइंट इन प्रिसिजन, जैसा हमने देखा,
वैज्ञानिक, वित्तीय, और अन्य प्रकार के कंप्यूटिंग के लिए एक मौलिक समस्या है
जहाँ सटीकता इतनी महत्वपूर्ण है।
एक char, इस बीच, कम से कम जैसा हमने देखा है,
ASCII कैरेक्टर्स का उपयोग करते हुए एक सिंगल बाइट है।
और फिर string, मैं प्रश्न चिह्न के रूप में डालूँगा,
क्योंकि एक string पूरी तरह से उसकी लंबाई पर निर्भर करता है।
यदि तुम high स्टोर कर रहे हो, वह जैसे 1, 2 बाइट्स है।
यदि hello स्टोर कर रहे हो, वह जैसे 5 बाइट्स है और इसी तरह।
तो स्ट्रिंग्स इस पर निर्भर करते हैं कि तुम उनमें वास्तव में कितने कैरेक्टर्स स्टोर करना चाहते हो।
तो यह कहाँ जाता है?
खैर, यहाँ मेमोरी की एक स्टिक की तस्वीर है, एक dim, बोलने के लिए,
जहाँ इस मेमोरी स्टिक पर, जो तुम्हारे कंप्यूटर में स्लाइड की जाती है,तुम्हारे लैपटॉप, तुम्हारे डेस्कटॉप, या किसी अन्य डिवाइस में,ये सभी छोटे काले चिप्स हैं जो अनिवार्य रूप से ज़ीरोस और वन्स के लिए बहुत जगह रखते हैं।यह किसी तरह इलेक्ट्रॉनिक है, लेकिन उसके अंदर वे सभी ज़ीरोस और वन्स हैं जिनमें हम डेटा स्टोर कर सकते हैं।तो यदि हम इस पर तरह से ज़ूम इन करें, चर्चा के लिए यह मानना उचित है,यदि यह एक चिप जैसे 1 गीगाबाइट, 1 बिलियन बाइट्स दर्शाता है,यह मानना उचित है कि हम इन बाइट्स पर कुछ एड्रेस लगा सकते हैं,जहाँ हम कह सकते हैं यह पहली बाइट है और यह अंतिम बाइट है।या अधिक सटीक रूप से, यह बाइट 0, 1, 2, 3, डॉ, डॉ, बाइट 1 बिलियन है।और इससे कोई फर्क नहीं पड़ता कि यह ऊपर, नीचे, बाएँ, दाएँ, या कोई अन्य क्रम है,हम फिलहाल सिर्फ अवधारणात्मक रूप से बात कर रहे हैं।तो वास्तव में, आइए इसे वास्तव में मेमोरी के एक ग्रिड के रूप में बनाएँ,एक तरह का कैनवास जिसका हम बस डेटा टाइप्स स्टोर करने के लिए उपयोग कर सकते हैं, जैसे bools,और ints, और chars, और floats, और बाकी सब।यदि हम एक char स्टोर करने के लिए एक बाइट का उपयोग करने वाले हैं, खैर,तुम बस इन आठ बिट्स का उपयोग कर सकते हो यहाँ ऊपर, एक बाइट यहाँ ऊपर।यदि तुम एक int स्टोर करना चाहते हो, खैर, वह चार है।तुम इन चारों बाइट्स का उपयोग कर सकते हो, जरूरी रूप से संलग्न।तुम बस चारों ओर रैंडम बिट्स नहीं चुन सकते।जब तुम्हारे पास int जैसी चार बाइट वैल्यू हो, वे सभी संलग्न होने वाली हैं,मेमोरी में एक के बाद एक इस तरह।लेकिन यदि तुम्हारे पास long या double है, तुम इसके बजाय आठ बाइट्स का उपयोग कर सकते हो।तो वास्तव में, जब तुम मेमोरी में एक मान स्टोर करते हो, चाहे वह छोटी संख्या हो या बड़ी संख्या,तुम बस कंप्यूटर के हार्डवेयर में भौतिक रूप से कुछ ज़ीरोस और वन्स का उपयोग कर रहे होकहीं और इसे उन्हें परम्यूट करने दे रहे हो, उन्हें ऑन और ऑफ करके उस मान को दर्शाने के लिएजिसे तुम स्टोर करने की कोशिश कर रहे हो।ठीक है, तो आइए हार्डवेयर से अमूर्त हो जाएँ, हालाँकि।और आइए इस मेमोरी ग्रिड के बारे में तरह से ज़ूम-इन रूप में सोचना शुरू करें।और निचले स्तर पर विचार करें कि वास्तव में इसके अंदर क्या स्टोर हो रहा है?उदाहरण के लिए, मान लो कि हमारे पास इस तरह का कुछ कोड है,जिसमें प्रॉब्लम सेट्स पर तीन स्कोर्स हैं।तुम्हारे पास उनमें से एक पर 72 है, दूसरे पर 73, और तीसरे पर 33।हमने जानबूझकर अपने पुराने दोस्त चुने, 72, 73, 33, जो याद करो high की वर्तनी करते हैं।या साथ में, रंगों के संदर्भ में, यह पीले का एक शेड है,बस ताकि हम मिक्स में कुछ नए रैंडम नंबर न जोड़ें।ये हमारे पुराने दोस्त हैं, तीन integers।खैर, आइए इन्हें एक प्रोग्राम में उपयोग करें।मुझे यहाँ VS Code पर जाने दो।और मुझे code के साथ scores.c नामक एक प्रोग्राम बनाने दो।जो बस मुझे अपने प्रॉब्लम सेट्स पर अपना औसत स्कोर जल्दी से कैलकुलेट करने देगा।मैं अक्सर की तरह शीर्ष पर standard io.h शामिल करने जा रहा हूँ।मैं उसके बाद int main void करने जा रहा हूँ।और फिर अपने कर्ली ब्रेसेस के अंदर, मैं ठीक उन्हीं सैंपल कोड लाइनों को करने जा रहा हूँ।मेरा पहला स्कोर था, मान लो, 72।मेरा दूसरा स्कोर 73 था।और मेरा तीसरा स्कोर 33 था।तो मैंने तीन वेरिएबल्स घोषित किए, मेरे प्रत्येक प्रॉब्लम सेट स्कोर के लिए एक।अब आइए औसत कैलकुलेट करें।तो printf, quote unquote, average colon, बस ताकि मुझे पता चले कि मैं क्या प्रिंट कर रहा हूँ।और अब मैं शायद percent i backslash n का उपयोग करने जा रहा हूँ।और फिर जो मैं पास करने जा रहा हूँ वह थोड़ा गणित है।तो औसत कैलकुलेट करना बस score 1 plus score 2 plus score 3 divided by 3 है।और मैंने स्कोर्स, न्यूमरेटर को पेरेंटहेसिस में रखा बस जैसे स्कूल में,जैसे मुझे विभाजन करने से पहले वह ऑपरेशन पहले करना होगा।तो बस गणित क्लास की तरह।अपने विचार को समाप्त करने के लिए अंत में सेमीकोलन।आइए देखें यह कैसे जाता है।Make scores, एंटर, डॉट स्लैश scores।और ऐसा लगता है कि इन तीन प्रॉब्लम सेट्स में मेरा औसत 72 है, जो महान है।लेकिन मुझे नहीं लगता कि यह वास्तव में वह है जो मैं यहाँ चाहता हूँ।मैंने क्या गलत किया है?यह अनजाने में है।हाँ।हाँ, मैं यहाँ खुद के साथ थोड़ा उदार हो रहा हूँ।मैंने वास्तव में अपना सबसे खराब स्कोर फैक्टर नहीं किया।तो वह आकस्मिक था।तो अब मुझे यह सही से करने दो।Make scores, डॉट स्लैश scores।और अब, ठीक, मेरा औसत 59 है।लेकिन मैं असहमति जताना चाहता हूँ।मैं झगड़ना चाहता हूँ।मेरा स्कोर, तकनीकी रूप से, मुझे लगता है गणितीय रूप से वास्तव में 59 और एक तिहाई होना चाहिए।मुझे उस एक तिहाई अंक से धोखा हो रहा है।तो यहाँ क्या चल रहा है?मैं सिर्फ 59 क्यों देख रहा हूँ और अपना पूरा ग्रेड क्यों नहीं?परफेक्ट।क्योंकि मैं integers का उपयोग कर रहा हूँ।जब मैं 3 से विभाजित करता हूँ, यह दशमलव बिंदु के बाद सब कुछ ट्रंकेट कर देगा,जिस पर हमने सप्ताह 1 के बहुत अंत में स्पर्श किया,जो सामान्य रूप से ट्रंकेशन के साथ एक मुद्दा है।तो इसे ठीक करने का एक तरीका।मैं अपने percent i को percent f में बदल सकता हूँ, जो फॉर्मेट कोड है।पता चलता है float के लिए।और वह वह है जो मैं प्रिंट करना चाहता हूँ।तो आइए देखें कि क्या वह फिक्स अकेला पर्याप्त है।Make scores।उफ़, यह नहीं है।मैं वहाँ खुद से आगे निकल गया।और मुझे त्रुटि पर स्क्रॉल करने दो।Format specifies double, but the argument has type int।पता चलता है तुम doubles के लिए भी percent f का उपयोग कर सकते हो।तो यही वजह है कि मैं double कह रहा हूँ, भले ही मैंने इस मामले में float का इरादा किया।तो यहाँ एक समस्या है।आर्गुमेंट का टाइप int है, भले ही मैं percent f पास कर रहा हूँ।तुम यहाँ percent d का उल्लेख देख रहे हो, जो percent i का एक विकल्प है।हम आमतौर पर तुम्हें percent i उपयोग करने के लिए प्रोत्साहित करते हैं क्योंकि i integer के लिए।लेकिन वह इस समस्या का समाधान नहीं है,क्योंकि मैं अपना एक तिहाई अंक वापस चाहता हूँ।तो मैं इसे कैसे ठीक कर सकता हूँ?खैर, मौलिक समस्या यहाँ यह है कि मैंएक integer को float के रूप में, या यहाँ तक कि double के रूप में फॉर्मेट करने की कोशिश कर रहा हूँ।खैर, मुझे इन स्कोर्स को floats में बदलना होगा।तो मैं जाकर इसे float में बदल सकता हूँ, इसे float में, इसे float में।और हेक, सुपर सटीक होने के लिए, मैं उनमें से प्रत्येक के अंत में 0.0 जोड़ सकता हूँबस यह सुपर स्पष्ट करने के लिए कि ये floats हैं।लेकिन एक और तरीका है।मैं, उदाहरण के लिए, बस अपने डिनॉमिनेटर को 3.0 में बदल सकता हूँ।क्योंकि पता चलता है, जब तक तुम अपने गणित में जैसे एक float शामिल करते हो,पूरी चीज़ फ्लोटिंग पॉइंट वैल्यूज में प्रमोट हो जाएगीintegers के बजाय।मुझे उन सभी को बदलने की जरूरत नहीं है।तो मुझे लगता है कि अब, यदि मैं make scores डॉट स्लैश scores अब करता हूँ,आह, वहाँ मेरा एक प्रतिशत का तिहाई, अंक का तिहाई वापस है।इसे करने का एक और तरीका है, बस एक साइड नोट के रूप में।और हम इसे आगे की लाइन में फिर से देखेंगे।यदि तुम वास्तव में 3 के साथ रहना चाहते हो, क्योंकि यह थोड़ा अजीब है,बस सिमेंटिक रूप से, 3.0 से विभाजित करना।वह एक इम्प्लीमेंटेशन डिटेल है।लेकिन तुम वास्तव में तीन चीज़ों का औसत कैलकुलेट कर रहे हो।तुम तकनीकी रूप से तीन को float में कास्ट कर सकते हो।पेरेंटहेसिस में, तुम उस डेटा टाइप को निर्दिष्ट कर सकते हो जिसमें तुम दूसरे डेटा टाइप को बदलना चाहते हो।और यह भी कंपाइलर को खुश करना चाहिए।आह-हा, डॉट स्लैश scores, मुझे लगभग वही जवाब मिलता है।हम कुछ फ्लोटिंग पॉइंट इन प्रिसिजन देख रहे हैं, हालाँकि, फिर भी।लेकिन वह भी यहाँ लक्ष्य हासिल करेगा।लेकिन संक्षेप में, वह सब बस वहाँ फ्लोटिंग पॉइंट अरिथमेटिक का फ़ंक्शन है।
तो अब वास्तव में कंप्यूटर की मेमोरी में क्या चल रहा है?
मुझे सरल वाले पर वापस जाने दो बस 0.0 के साथ।
और मुझे प्रस्ताव करने दो कि हम विचार करें कि ये तीन चीज़ें मेमोरी में कहाँ हैं।
खैर, यदि हम इसे मेमोरी के अपने ग्रिड या कैनवास के रूप में मानते हैं, कौन जानता है कि वे कहाँ समाप्त होंगी।
लेकिन चर्चा के लिए, आइए मान लें कि 72 मेरी कंप्यूटर की मेमोरी के ऊपर बाईं ओर समाप्त हुआ।
मैंने इसे स्केल पर बनाया है, बोलने के लिए, और यह score one वेरिएबल स्पष्ट रूप से मेमोरी के चार बाइट्स ले रहा है।
और यह एक int है।
और सिस्टम पर आमतौर पर इतने बाइट्स उपयोग होते हैं।
तकनीकी रूप से, यह ठीक उस सिस्टम पर निर्भर करता है जिसका तुम उपयोग कर रहे हो।
लेकिन आजकल, यह काफी उचित है मान लेना कि एक integer अधिकांश आधुनिक सिस्टम पर 32 बिट्स होगा।
Score two शायद वहाँ है।
Score three शायद वहाँ है।
तो मैं कुल 12 बाइट्स उपयोग कर रहा हूँ, इन वैल्यूज में से प्रत्येक के लिए चार बाइट्स।
ठीक है, तो हुड के नीचे वास्तव में यही सब चल रहा है।
मुझे इसके बारे में चिंता करने की जरूरत नहीं है।
कंपाइलर ने अनिवार्य रूप से मेरे लिए यह पता लगा लिया कि मेमोरी में इन सभी चीज़ों को कहाँ रखना है।
लेकिन मेमोरी में वास्तव में क्या है, खैर, तकनीकी रूप से, इनमें से प्रत्येक वेरिएबल,
यदि यह 32 बिट्स से बना है, वास्तव में शाब्दिक रूप से 32 ज़ीरोस और वन्स का एक पैटर्न है।
और मैंने यहाँ पैटर्न पता लगा लिया।
मैंने उन्हें वहाँ स्पेस में ठूस दिया।
लेकिन तुम यहाँ 32 बिट्स के तीन पैटर्न देखते हो, जो सामूहिक रूप से उन संख्याओं को बनाते हैं।
लेकिन आइए अब डिज़ाइन पर विचार करें।
मेरे कोड के संदर्भ में, यह काम पूरा कर देता है।
यह तीन स्कोर्स के औसत की गणना के लिए उतना बुरा या बड़ा सौदा नहीं है।
लेकिन यह इस सप्ताह से आगे डिज़ाइन की बात आने पर तुम्हें गलत भी रगड़ना शुरू कर देना चाहिए।
जैसे, यह सही है, विशेष रूप से अब जब मैंने अपना एक तिहाई अंक वापस माँग लिया।
लेकिन इस तरीके से वेरिएबल्स का उपयोग करना खराब डिज़ाइन है।
तुम क्यों सोच सकते हो?
हाँ?
हाँ, मुझे प्रत्येक स्कोर मैन्युअली टाइप करना पड़ेगा प्रत्येक गुज़रते सप्ताह के साथ
जब मुझे चौथा प्रॉब्लम सेट और पाँचवाँ मिलेगा।
मेरा मतलब है, निश्चित रूप से हमसे पहले आए लोगों ने इस समस्या को हल करने का एक बेहतर तरीका निकाला
बजाय कि सेमेस्टर के अंत तक 10 वेरिएबल्स, 20 वेरिएबल्स, जो भी हो, मैन्युअली बनाएँ।
यह थोड़ा स्लoppy महसूस होता है।
और वास्तव में, वह अक्सर किसी चीज़ की डिज़ाइन की गुणवत्ता के बारे में सोचने का तरीका है।
चरम के बारे में सोचो।
यदि तुम्हारे पास तीन स्कोर्स नहीं हैं, बल्कि 30 या 300,
क्या यह वास्तव में इसे करने का सबसे अच्छा तरीका होगा?
और यदि तुम्हें लगता है, नहीं, नहीं, एक बेहतर तरीका होना चाहिए, संभावना है कि हैं।
निश्चित रूप से यदि भाषा खुद अच्छी तरह डिज़ाइन की गई है।
तो आइए विचार करें कि हम इसे हल करने के लिए और कैसे जा सकते हैं।खैर, पता चलता है कि हम मेमोरी के अपने कैनवास, बाइट्स के उस ग्रिड को,मेमोरी के चंक्स में बदल सकते हैं जिन्हें arrays कहा जाता है।एक array मेमोरी का एक संलग्न चंक है, एक के बाद एक,जहाँ यदि तुम तीन चीज़ें स्टोर करना चाहते हो,तुम कंप्यूटर से तीन चीज़ों के लिए मेमोरी का एक चंक माँगते हो।यदि तुम 30 चाहते हो, तुम साइज 30 का एक चंक माँगते हो।यदि तुम और भी अधिक चाहते हो, तुम साइज 300 का एक चंक माँगते हो।Chunk कला का शब्द नहीं है।मैं बस इसे बोलचाल में समझाने के लिए उपयोग कर रहा हूँ कि array वास्तव में क्या है।यह मेमोरी का एक चंक या ब्लॉक है जो एक के बाद एक है।तो व्यवहार में इसका क्या मतलब है?खैर, इसका मतलब है कि हम C में थोड़ा नया सिंटैक्स पेश कर सकते हैं।यदि मैं तीन के बजाय एक वेरिएबल बनाना चाहता हूँ,और निश्चित रूप से 30 के बजाय एक वेरिएबल, मैं इस तरह के सिंटैक्स का उपयोग कर सकता हूँ।हे कंपाइलर, मुझे scores नामक एक वेरिएबल दो, बहुवचन।उसमें तीन integers के लिए जगह दो।तो यह थोड़ा अजीब सिंटैक्स है,लेकिन तुम array में सभी वैल्यूज का टाइप निर्दिष्ट करते हो।तुम array का नाम निर्दिष्ट करते हो, इस मामले में scores,और मैंने इसे बहुवचन किया बस सिमेंटिक रूप से क्योंकि अब इसे score कहने से अधिक मतलब रखता है।और फिर स्क्वायर ब्रैकेट्स में, बोलने के लिए,तुम निर्दिष्ट करते हो कि तुम मेमोरी के उस चंक में कितने integers डालना चाहते हो।तो यह एक कोड लाइन अब अनिवार्य रूप से मुझे स्वचालित रूप से 12 बाइट्स देगी।लेकिन वे सभी scores, बहुवचन नाम से रेफरेबल होंगे।तो आइए इसे कुछ कोड में इस प्रकार बुनें।मुझे यहाँ VS Code पर वापस जाने दो, अपना टर्मिनल साफ करो।और अब आइए उसी तरह का प्रोग्राम बनाएँ,लेकिन इन तीन स्वतंत्र वेरिएबल्स को हटा दें।और इसके बजाय, आइए बस कहें int, scores, बहुवचन, bracket three।अब मुझे तीन वैल्यूज इनिशियलाइज़ करने का तरीका चाहिए, लेकिन यह मैं भी कर सकता हूँ।पता चलता है कि यदि मैं इसमें तीन वैल्यूज डालना चाहता हूँ,मुझे थोड़ा नया सिंटैक्स चाहिए।मैं कह सकता हूँ scores, bracket zero equals 72।Scores, bracket one equals 73।Scores, bracket two equals 33।तो यह तीन वेरिएबल्स होने से उतना अलग नहीं है,लेकिन अब मेरे पास तकनीकी रूप से एक वेरिएबल है,और मैं इसमें अलग-अलग लोकेशन्स पर इंडेक्स कर रहा हूँ, लोकेशन zero, one, और two।और यह zero है क्योंकि हम हमेशा, कंप्यूटिंग में, शून्य से गिनती शुरू करते हैं।तो मैं scores, bracket zero करता हूँ वह मेरा 72 प्रॉब्लम सेट होगा।Scores, bracket one मेरा 73 प्रॉब्लम सेट है।और scores, bracket two मेरा सबसे कमजोर था, मेरा 33 p set।अब यहाँ नीचे मेरे सिंटैक्स को बदलना होगा क्योंकि अब कोई score नहीं हैं।One score, two score, three वेरिएबल्स।लेकिन scores, brackets zero plus scores, bracket one plus हैं।और ध्यान दो कि VS Code मेरे लिए क्या करने की कोशिश कर रहा है।यह मुझे कुछ कीस्ट्रोक्स बचा रहा है।जैसे ही मैं scores टाइप करता हूँ और एक सिंगल bracket टाइप करता हूँ,ध्यान दो कि यह मेरे विचार को मेरे लिए पूरा करता है और जादुई रूप से कर्सर वहाँ रखता है जहाँ मैं चाहता हूँताकि मैं two वहाँ रख सकूँ और सामान्यतः कीस्ट्रोक्स बचा सकूँ।लेकिन उसका C से कोई लेना-देना नहीं है।इसका बस VS Code के अब मददगार होने की कोशिश से लेना-देना है।तो मुझे लगता है कि अब, यदि मैं यहाँ नीचे जाऊँ और make scores डॉट स्लैश scores करूँ,हमें वही जवाब मिलता है।लेकिन यह तर्कपूर्वक बेहतर डिज़ाइन है क्योंकि अब मेरे पास तीन के बजाय एक वेरिएबल है,अकेले बहुत अधिक की बात छोड़ो।और वास्तव में, यदि मैं स्कोर्स की कुल संख्या बदलना चाहता हूँ,मैं बस उस शुरुआती स्क्वायर bracket में जो है उसे बदल सकता हूँ।तो यदि हम विचार करें कि अब क्या चल रहा है, यदि हम कंप्यूटर की मेमोरी देखें,यह ठीक वही लेआउट है।लेकिन अब तीन वेरिएबल नाम नहीं हैं।एक है, scores, brackets zero, scores, bracket one, और scores, bracket two।और यहाँ ध्यान दो, और भी अधिक महत्वपूर्ण, arrays में वैल्यूज वास्तव में संलग्न हैं।एक के बाद एक।अब, स्क्रीन सिर्फ इतनी चौड़ी है, तो वे तरह से बाइट्स की अगली पंक्ति पर रैप हो जाते हैं।लेकिन कंप्यूटर को ऊपर, नीचे, बाएँ, दाएँ की कोई धारणा नहीं है।मेरा मतलब है, यह बस हार्डवेयर का एक टुकड़ा है जिसमें बहुत सारी बाइट्स उपलब्ध हैंजिन्हें पहली बाइट से अंतिम बाइट तक एड्रेस किया जा सकता है।रैपिंग बस इस यहाँ स्क्रीन पर एक विजुअल आर्टिफैक्ट है।ठीक है, तो यदि मैंने यह अब किया है, शायद हमइस प्रोग्राम को मेरे स्कोर्स को हार्ड कोड करने से थोड़ा अधिक गतिशील बना सकते हैं।मुझे अंदर जाकर CS50 हेडर लाइब्रेरी जोड़ने दो ताकि हम उदाहरण के लिए,getInt का भी उपयोग कर सकें और इन स्कोर्स को गतिशील रूप से पाना शुरू कर सकें।तो मैं getInt कर सकता हूँ और उपयोगकर्ता को एक स्कोर के लिए प्रॉम्प्ट कर सकता हूँ।मैं getInt फिर से उपयोग कर सकता हूँ।और मैं उपयोगकर्ता को एक और pset स्कोर के लिए प्रॉम्प्ट कर सकता हूँ।मैं getInt तीसरी बार उपयोग कर सकता हूँ और उपयोगकर्ता को तीसरे ऐसे स्कोर के लिए प्रॉम्प्ट कर सकता हूँ।और फिर मेरे कोड का बाकी लगभग वैसा ही रह सकता है।आइए makeScores फिर से करें।डॉट स्लैश scores, 72, 73, 33।और अब मेरा प्रोग्राम थोड़ा अधिक इंटरैक्टिव है।जैसे, यह सिर्फ मेरे तीन स्कोर्स के लिए काम नहीं करता।यह क्लास में किसी के भी स्कोर्स के लिए काम कर सकता है।अब, यह भी खराब डिज़ाइन का संकेत देता है।मुझे array का परिचय पसंद है क्योंकि अब मेरे पास तीन के बजाय एक वेरिएबल है।लेकिन अब लाइनों 7, 8, और 9 में तुम्हें क्या गलत लग सकता है?हाँ।यह दोहराव वाला है।मेरा मतलब है, मैंने इसे मैन्युअली टाइप किया, लेकिन मैंने बस कॉपी और पेस्ट भी कर सकता था,जैसे, शाब्दिक रूप से वही चीज़।तो इसे ठीक करने का एक उम्मीदवार क्या है?जैसे, कौन सा प्रोग्रामिंग कंस्ट्रक्ट इसे साफ कर सकता है?हाँ।हाँ, हम for लूप या while लूप या जो भी उपयोग कर सकते हैं।लेकिन for लूप काम पूरा कर देगा।और वह अक्सर मेरा गो टू है।तो आइए उसके बजाय वह करें।आइए array की घोषणा के नीचे जाएँ और for int i equals 0, i less than 3,i plus plus करें, जो हम बार-बार देख रहे हैं।अब, मैं array में सही लोकेशन पर कैसे इंडेक्स करूँ?खैर, यहाँ स्क्वायर ब्रैकेट्स तरह के शक्तिशाली हैं।मैं बस कह सकता हूँ मेरा scores array लोकेशन i पर उपयोगकर्ता से get int इस प्रकार प्राप्त करे।तो अब मैं लूप के अंदर get int एक बार उपयोग कर रहा हूँ।लेकिन क्योंकि i बढ़ता रहता है, जैसा हमने कई बार meowingऔर अन्य लक्ष्यों के लिए किया है, मैं पहला लोकेशन 0 पर डाल रहा हूँ।क्यों?क्योंकि i 0 पर इनिशियलाइज़ है।मैं दूसरा लोकेशन 1 पर डाल रहा हूँ।क्यों?क्योंकि मैं अगले इटरेशन पर plus plus या इंक्रिमेंट करने जा रहा हूँ फिर अगले इटरेशन पर।तो इसका अंतिम प्रभाव इन तीन स्कोर्स को लोकेशन 0, 1, और 2 पर डालना है,बजाय कि मुझे वह सब मैन्युअली टाइप करना पड़े।अब, मुझे अभी भी यह कैसे किया है पसंद नहीं है।यदि हम वास्तव में नुक्ताचीनी करना चाहें, यह समस्या को सही ढंग से हल करता है।लेकिन इसमें अभी भी एक खराब डिज़ाइन निर्णय है।इसमें एक जादुई संख्या है, जैसा लोग कहते हैं।यहाँ जादुई संख्या क्या है?और यह क्यों बुरी है?हाँ, यहाँ।हाँ, यह थोड़ा नरम था।लेकिन मुझे लगता है कि संख्या तीन दो जगहों पर हार्ड-कोडेड है।हमारे पास यह लाइन छह पर है, जो array का साइज है।और फिर फिर से, लाइन सात पर, जो कितनी बार मैं इटेरेट करना चाहता हूँ।लेकिन वे ठीक वही अवधारणाएँ हैं।लेकिन यह ऑनर सिस्टम पर है कि मैंने दोनों बार संख्या तीन सही टाइप की।तो मुझे लगता है कि हम इसे थोड़ा बेहतर ठीक कर सकते हैं।मैं कुछ ऐसा कर सकता हूँ जैसे int n equals three।और फिर मैं यहाँ n उपयोग कर सकता हूँ।और फिर मैं यहाँ n उपयोग कर सकता हूँ ताकि अब मैं इसे सिर्फ एक जगह बदलूँ।यदि तुम्हारी आँखें प्रोग्राम के नीचे घूम रही हैं,अभी भी एक समस्या है क्योंकि मैंने अभी भी zero, one, और two हार्ड-कोडेड किए हैं।लेकिन हम उस पर वापस आएंगे।लेकिन यह तर्कपूर्वक थोड़ा बेहतर है।लेकिन आइए शैली के बारे में थोड़ा बात करें।आमतौर पर, जब तुम्हारे पास एक वेरिएबल हो जिसका मान नहीं बदलना चाहिए,हमने पिछले सप्ताह देखा कि हमें इसे कॉन्स्टेंट घोषित करना चाहिए।और वहाँ ट्रिक शाब्दिक रूप सेconst लिखना है वेरिएबल के टाइप के सामने शॉर्ट के लिए।और अब इसे तुम्हारे द्वारा, एक सहयोगी, एक सहयोगी,या जैसे द्वारा बदला नहीं जाना चाहिए।लेकिन आमतौर पर भी, कन्वेंशन द्वारा, शैलीगत रूप से,दूसरे प्रोग्रामर को विजुअली स्पष्ट करने के लिए कि यह एक कॉन्स्टेंट है,यह कन्वेंशन भी है कॉन्स्टेंट को कैपिटलाइज़ करने का।तो वास्तव में यहाँ सभी जगहों पर कैपिटल n उपयोग करने के लिए,बस विजुअली स्पष्ट करने के लिए कि इस वेरिएबल के बारे में कुछ दिलचस्प है।और वास्तव में, यह एक कॉन्स्टेंट है जिसे बदला नहीं जा सकता।ठीक है, उस परिष्करण के साथ, मुझे नहीं लगताकि हमने प्रोग्राम को मौलिक रूप से सुधारा है।मुझे लगता है कि हमें इसे वास्तव में अच्छी तरह करने के लिए थोड़ा और काम करने की जरूरत होगी।तो मैं यह थोड़ा जल्दी करने जा रहा हूँ, लेकिन ज्यादातर बिंदु बनाने के लिएकि हम इसे वास्तव में अधिक गतिशील बना सकते हैं।तो मुझे वहाँ अपनी टर्मिनल विंडो छिपाने दो।मुझे अब आगे बढ़ने दो और स्कोर्स पाने दो जैसा मैं पहले से कर रहा हूँ इस प्रकार यहाँ।और मुझे आगे बढ़ने दो और समय के लिए मान लेना दो,कि हमारे पास पहले से एक फ़ंक्शन मौजूद है जिसे average कहा जाता है।और मैं बस उस average फ़ंक्शन में पास करना चाहता हूँ, स्कोर्स,जिनका औसत मैं कैलकुलेट करना चाहता हूँ।तो average ऑफ द शेल्फ मौजूद नहीं है।जैसे मैं बस इसके लिए एक मौजूदा लाइब्रेरी उपयोग नहीं कर सकता।मुझे इस चीज़ को खुद इम्प्लीमेंट करना होगा।लेकिन कैसे?ठीक है, खैर, आइए आगे बढ़ें और यह करें।अपनी फाइल के शीर्ष पर, मैं average नामक एक फ़ंक्शन कंप्यूट या डिफाइन करने जा रहा हूँजो क्या लेता है?संख्याओं का एक array।तो यह सिंटैक्स थोड़ा नया होने जा रहा है।लेकिन जिस तरह से मैं यह करता हूँ वह int, कहो array bracket 0।या array थोड़ा बहुत सामान्य लगता है।आइए इसे बस numbers कहें, उदाहरण के लिए यहाँ।तो वह कहता है मेरा average फ़ंक्शन आर्गुमेंट के रूप में numbers का एक array लेने जा रहा है।यह average फ़ंक्शन, हालाँकि, एक वैल्यू भी लौटाना चाहिए।और इसे अब तक जो हमने देखा है उससे किस प्रकार का मान लौटाना चाहिए?एक संख्या float, विशेष रूप से।यह int हो सकता है, लेकिन फिर मुझे संभावित रूप से अपना एक तिहाई अंक कम मिलेगा।तो मुझे लगता है कि मैं चाहता हूँ कि यह एक float लौटाए।या यदि तुम वास्तव में सटीकता चाहते हो, तुम एक double लौटा सकते हो, बस वास्तव में नुक्ताचीनी करने के लिए।लेकिन वह यहाँ अत्यधिक लगता है।ठीक है, खैर, अब अपने average फ़ंक्शन के अंदर, मैं औसत कैसे कैलकुलेट कर सकता हूँ?खैर, यह बस तरह की गणित चीज़ है।तो मैं sum नामक एक वेरिएबल घोषित कर सकता हूँ और इसे 0 के बराबर सेट कर सकता हूँ।मैं फिर इस फ़ंक्शन के अंदर एक for लूप रख सकता हूँ for int i gets 0 i less than, हह।मैं इस पर वापस आने वाला हूँ, array में numbers।और फिर मैं i plus plus करने जा रहा हूँ।और फिर प्रत्येक इटरेशन पर, मैं sum equals जो भी वर्तमान sum हैplus जो भी numbers array में उस लोकेशन पर है करने जा रहा हूँ।तो मैं थोड़ा जल्दी जा रहा हूँ।लेकिन फिर से, मैं बस वही सबक लागू कर रहा हूँ।Numbers मेरा array है।Numbers bracket i का मतलब है वहाँ ith लोकेशन पर जाओ।लेकिन यदि मेरा लूप 0 से शुरू होता है, इसका मतलब लोकेशन 0 पर जाओ, और फिर 1, और फिर 2।और हेक, यदि इस array में अधिक स्कोर्स हैं,यह बस वहाँ से ऊपर जाता रहेगा plus plus के कारण।लेकिन मैं यहाँ कुछ कारणों से हिचकिचाया।तो मैंने यहाँ to do डाला, जो एक चीज़ नहीं है।वह खुद के लिए नोट है।मैं कितनी दूर इटेरेट करूँ?खैर, यदि तुम प्रोग्रामिंग के साथ पहले CS50 में आए हो,तुम आमतौर पर बस एक array से पूछ सकते हो, उर्फ एक vector उसकी लंबाई क्या है Javaऔर Python और जैसे में।तुम C में वह नहीं कर सकते।तो यदि मैं जानना चाहता हूँ कि इस array की लंबाई क्या है,मुझे फ़ंक्शन को मुझे बताना होगा।तो मैं अतिरिक्त रूप से प्रस्ताव करने जा रहा हूँ कि यह average फ़ंक्शन सिर्फ array नहीं ले सकता।इसे एक और आर्गुमेंट भी लेना होगा, एक दूसरा इनपुट,उदाहरण के लिए, length कहा जाता है, जो मुझे बताता है कि यह कितना लंबा है।और फिर यहाँ नीचे, जहाँ हमने कहानी शुरू की,जब मैंने इस तथाकथित average फ़ंक्शन का उपयोग किया,मुझे average फ़ंक्शन को n पास करके बताना होगाकि उस array में कितनी संख्याएँ हैं, बस क्योंकि।यह परेशान करने वाला है कि तुम्हें न केवल array पास करना पड़ता है,बल्कि उसका साइज भी अलग से।C में यही तरीका है।अधिक हाल की भाषाओं ने इसमें सुधार किया है,ताकि तुम बस पता लगा सको कि array की लंबाई क्या है,जैसा हम कुछ हफ्तों में Python में देखेंगे।ठीक है, हाथ में average फ़ंक्शन पर वापस।मुझे लगता है कि हम लगभग वहाँ हैं।यह थोड़ा अनावश्यक रूप से विस्तृत है।याद करो कि हम इसे सिर्फ plus equals करके कस सकते हैं,जो भी numbers bracket i में है, वह बस इसे कस रहा है।यह सिंटैक्टिक शुगर है, बोलने के लिए।और फिर अपने average फ़ंक्शन में अंतिम चीज़ जो मैं करने जा रहा हूँ वह क्या है?वास्तव में औसत कैलकुलेट करना।तो औसत क्या है?बस न्यूमरेटर, जैसे सभी स्कोर्स का योग,सभी स्कोर्स की कुल संख्या से विभाजित।खैर, मेरे पास sum है, तो मुझे लगता है कि मैं बसsum को क्या से विभाजित करना चाहता हूँ वास्तविक औसत पाने के लिए अब?हाँ।बिल्कुल।Sum divided by length मुझे औसत देगा,क्योंकि sum प्रभावी रूप से न्यूमरेटर है,सभी स्कोर्स एक साथ जोड़े गए, और डिनॉमिनेटर length है।वास्तव में कितनी संख्याएँ थीं?अब, मैं बस यहाँ यह गणित एक्सप्रेशन नहीं लिख सकता।यदि यह मेरे फ़ंक्शन की रिटर्न वैल्यू होने वाली है,और हमने यह एक या दो बार पहले किया है,मैं शाब्दिक रूप से अपने average फ़ंक्शन में कहता हूँ, return this value।तो यह काम वापस सौंपता है।मैं printf उपयोग कर सकता हूँ और बस इसे स्क्रीन पर प्रिंट कर सकता हूँ,लेकिन मैं वह विजुअल साइड इफेक्ट नहीं चाहता।मैं इसे वापस सौंपना चाहता हूँ ताकि लाइन 23 पर,मैं बस उन n स्कोर्स का औसत कैलकुलेट कर सकूँऔर printf को उस फॉर्मेट कोड, percent f के मान के रूप में उपयोग करने दूँ।ठीक है।मुझे लगता है कि हम उचित रूप से अच्छी स्थिति में हैं।मुझे अब अपनी उंगलियाँ क्रॉस करने दो, और आशा है कि मैंने इसे गड़बड़ नहीं किया।Make scores।ठीक।डॉट स्लैश scores।हम कितने करना चाहते हैं?तो हम 72, 73, 33 करेंगे।एंटर।और वहाँ इतना करीब औसत है।मेरे पास एक रिग्रेशन है।मैंने वही गलती फिर से की है, बस एक अलग तरीके से।मुझे लगता है कि मैंने तुम्हारा हाथ उठते देखा।मुझे 59 क्यों मिल रहा है?और मुझे अपना एक तिहाई अंक क्यों नहीं मिल रहा?मुझे लगता है कि फ़ंक्शन में, मैंरिटर्न लाइन में लाइन के बाद कर सकता हूँ।हाँ।इस रिटर्न लाइन पर लाइन 11 पर अभी,मैं फिर से मूर्खता से integer को integer से विभाजित कर रहा हूँ।वह हमें integer ट्रंकेशन से पीड़ित करेगा।क्योंकि यदि तुम एक integer लौटा रहे हो, वहाँदशमलव बिंदु या उसके बाद की किसी भी संख्या के लिए कोई जगह नहीं है।तो हम इसे कैसे ठीक करें?खैर, मैं sum को float में बदल सकता हूँ।जैसे वह उचित होगा।तो फिर मैं length से एक float विभाजित करता हूँ।मैं अपनी कास्टिंग ट्रिक कर सकता हूँ, जैसे length को float में बदलना,बस फ्लोटिंग पॉइंट अरिथमेटिक के लिए।इसे हल करने के बहुत सारे तरीके हैं।लेकिन मुझे लगता है कि मैं अब इस एक के साथ जाऊँगा।मुझे अब make scores फिर से करने दो।डॉट स्लैश score, 72, 73, 33।और अब मेरे पास, कुछ इन प्रिसिजन के साथ,मुझे लगता है इस मामले में कॉलेज ग्रेड के लिए पर्याप्त सटीकता, 59.333 और इसी तरह।ठीक।तो यहाँ वास्तव में किन चीज़ों की परवाह करनी है?तो यहाँ काफी मात्रा में कोड है।ज्यादातर वह सामान है जो हमने पहले देखा है।लेकिन दिलचस्प हिस्से मैं प्रस्ताव करूँगा ये हैं।जब तुम अपना खुद का फ़ंक्शन बनाते हो जो इनपुट के रूप में एक array लेता है,तुम्हें इनपुट के रूप में array की लंबाई लेनी होगी।तुम इसे आधुनिक नई भाषाओं की तरह सही ढंग से पता नहीं लगा पाओगे।तुम्हें बेशक array खुद भी पास करना होगा।तुम एक array कैसे पास करते हो?खैर, जब तुम फ़ंक्शन डिफाइन कर रहे हो, तुम array में वैल्यूज का टाइप निर्दिष्ट करते हो,जो भी तुम इस फ़ंक्शन के अंदर array का नाम रखना चाहते हो,और फिर तुम खाली स्क्वायर ब्रैकेट्स इस तरह उपयोग करते हो।तुम्हें वहाँ n या कोई अन्य संख्या डालने की जरूरत नहीं है।तुम्हें बस कंपाइलर को बताना है कि मेरा average फ़ंक्शनवैल्यूज का कुछ array लेने जा रहा है, विशेष रूप से इतने।तुम स्क्वायर ब्रैकेट्स के अंदर नहीं डालते।फिर जब मैं इसका उपयोग करता हूँ, अब यह बस अब परिचित सिंटैक्स है।जब तुम अपने array में इंडेक्स करना चाहते हो, अर्थात् लोकेशन 0 या 1 या 2 पर जाना,तुम बस यहाँ स्क्वायर bracket नोटेशन उपयोग करते हो।लेकिन array खुद, याद करो, वास्तव में main में बनाया गया था जब मैंने यह कोड लाइन की,जहाँ मैंने कहा मुझे scores नामक एक array दो, जिसकी प्रत्येक वैल्यू int होने वाली है,और मैं इनमें से इतने चाहता हूँ।और तो शायद अंतिम फूलिश जो मैं यहाँ जोड़ूँगा, बस तरह की नुक्ताचीनी करने के लिए,मैं कहता रहता हूँ कि main वास्तव में शीर्ष पर जाना चाहिए।ठीक, कोई बड़ी बात नहीं।मुझे अपना average फ़ंक्शन हाइलाइट करने दो, इसे अपनी फाइल के नीचे ले जाऊँ, बस क्योंकि।और फिर, और केवल तब, मैं उस पहली लाइन, तथाकथित प्रोटोटाइप को कॉपी और पेस्ट करूँगा,ताकि clang average फ़ंक्शन क्या है न जानने से घबराए नहीं।तो संक्षेप में, यहाँ प्रतीत होता है बहुत सारी जटिलता,लेकिन हम वास्तव में जो नया है इस एक उदाहरण मेंयह है कि तुम एक फ़ंक्शन को एक array पास कैसे करते हो जो पहले से कहीं और मौजूद है।उसके नाम से नहीं, बल्कि वहाँ स्क्वायर ब्रैकेट्स से।ठीक।Arrays या इस नए सिंटैक्स में से किसी पर प्रश्न?हाँ?मैं बस धीमा हूँ, लेकिन जब तुमने more average चीज़ की,तुमने कहा कि हम इसे float के रूप में स्टोर कर सकते हैं।और 3.0 को float कहने के बजाय, तुमने बस कहा क्योंकि 3.0 एक float है।यह कैसे जानता है कि यह double नहीं है?ओह, यह कैसे जानता है कि यह double नहीं है?तो डिफ़ॉल्ट रूप से, यदि तुम अपने कोड में 3.0 जैसी संख्या बस टाइप करते हो,इसे double माना जाएगा, बस क्योंकि।कच्चे मान, दशमलव बिंदु वाली शाब्दिक संख्याएँकंपाइलर द्वारा doubles के रूप में ट्रीट की जाएँगी और 64 बिट्स आवंटित की जाएँगी।तुम अभी भी percentage app क्यों करते हो?बस क्योंकि।जैसे, दुनिया को नया फॉर्मेट कोड बनाने की जरूरत नहीं थी।जैसे, percent d double नहीं है।Percent d डेसिमल integer है, लेकिन उसके बारे में चिंता मत करो।हम क्लास में इसके बारे में बहुत अधिक बात नहीं करते।Percent i integer है, percent f float है, लेकिन percent f double भी है।और यह सुसंगत नहीं है, क्योंकि long क्या है?Percent lli, मैंने पिछले सप्ताह क्या कहा?Percent lli तुम्हें long integer देता है।यह बस एक गड़बड़ है।इसके लिए कोई अच्छा कारण नहीं है सिवाय ऐतिहासिक बोझ के।ज़रूर, मुझे यकीन नहीं है कि वह आश्वस्त करने वाला है, लेकिन ठीक है।
ठीक, आइए अब इस ज्ञान का उपयोग किसी उपयोगी चीज़ के लिए करें,
और वास्तव में यह बेहतर समझें कि कंप्यूटर के अंदर क्या चल रहा है इस प्रकार।
मुझे मेमोरी के हमारे ग्रिड पर जाने दो।
और इस बार, आइए कुछ संख्याएँ स्टोर न करें,
बल्कि ये तीन कोड लाइनें स्टोर करें, ये तीन वेरिएबल्स।
तो तीन chars, भले ही तुम जानते हो कि यह कहाँ जा रहा है।
यह अच्छा डिज़ाइन नहीं है, क्योंकि मेरे पास तीन मूर्खता से नामित वेरिएबल्स हैं,
लेकिन आइए पहले एक बिंदु बनाएँ।
पहले वेरिएबल का मान quote unquote h है।
दूसरा i है।
तीसरा विस्मयादिबोधक चिह्न है।
क्यों, हालाँकि, मैं अचानक डबल कोट्स के बजाय सिंगल कोट्स का उपयोग कर रहा हूँ?
यह एक कैरेक्टर है।
Chars सिंगल कोट्स हैं।
Strings डबल कोट्स हैं।
और हम एक पल में अंतर क्यों देखेंगे।
तो उदाहरण के लिए, यदि यह मेरी मेमोरी का ग्रिड है,
और इस प्रोग्राम में बस तीन वेरिएबल्स हैं, उनमें से प्रत्येक एक char,
संभावना है कि वे मेमोरी में इस तरह समाप्त होंगे।
C1, C2, C3, hi, विस्मयादिबोधक चिह्न।
यह मानते हुए कि मेरे प्रोग्राम में और कुछ नहीं चल रहा,
वे बस इस तरीके से एक के बाद एक होने वाले हैं,
भले ही यह इस तरीके से न हो।
तो इसका वास्तव में क्या मतलब है कि क्या चल रहा है?
खैर, आइए आगे बढ़ें और घुसपैठ करें।
मुझे यहाँ VS Code पर वापस जाने दो।
आइए scores.c बंद करें, अपना टर्मिनल फिर से खोलें,
और आइए hi.c नामक एक नया प्रोग्राम बनाएँ, और बस कुछ मज़ेदार करें।
तो मुझे शीर्ष पर standard io.h शामिल करने दो।
मुझे उसके बाद int main void करने दो।
और अपने कर्ली ब्रेसेस के अंदर, आइए बस इसे दोहराएँ।
C1 equals h कैप्स में, char C2 equals i कैप्स में, और फिर char C3 equals
विस्मयादिबोधक चिह्न विस्मयादिबोधक चिह्न में।
बस इतना ही।
अब, आइए वास्तव में घुसपैठ करें और देखें कि कंप्यूटर की मेमोरी के अंदर क्या है।
तो मैं कुछ ऐसा कर सकता हूँ।
मैं printf कर सकता हूँ, उदाहरण के लिए, %c, %c, %c, backslash n, और %c।
पता चलता है इसका मतलब कैरेक्टर है।
तो मैं क्या प्लग इन करना चाहता हूँ?
C1, C2, और C3, सेमीकोलन।
तो आइए आगे बढ़ें और यह करें।
Make, hi, एंटर, डॉट स्लैश hi, और वोइला।
वहाँ मेरा hi विस्मयादिबोधक चिह्न है।
यहाँ कोई जादू नहीं है।
मैं शाब्दिक रूप से बस तीन char वेरिएबल्स प्रिंट कर रहा हूँ।
मुझे स्पेसेस की जरूरत नहीं है।
यदि मैं शब्द के बीच उन स्पेसेस से छुटकारा पाना चाहता हूँ, मैं इसे फिर से बना सकता हूँ।
Make hi, डॉट स्लैश hi, और अब हम वापस बिजनेस में हैं, hi विस्मयादिबोधक चिह्न।
लेकिन यहाँ टाइप्स की समझ तुम्हें थोड़ी शक्ति दे सकती है
और तरह की जिज्ञासा संतुष्ट कर सकती है।
यदि मैं अपने %c को %i, %i, %i में बदल दूँ तो क्या?
तो int, int, int।खैर, पता चलता है कि एक char वास्तव में बस एक संख्या है,क्योंकि यह 0 से 255 तक ASCII वैल्यू है।तो मुझे कंपाइलर को यह बताने से कुछ नहीं रोकता, इन्हें char के रूप में प्रिंट मत करो।इन्हें integers के रूप में प्रिंट करो।तो आइए make hi, डॉट स्लैश hi, एंटर करें।और वह थोड़ा क्रिप्टिक है।ऐसा लगता है कि यह 727,333 कह रहा है, लेकिन नहीं।मुझे उन स्पेसेस को प्रत्येक प्लेसहोल्डर्स के बीच वापस जोड़ने दो।Make hi फिर से, डॉट स्लैश hi।वहाँ हमारे पुराने दोस्त हैं, 72, 73, 33।इस मामले में int, int, int कहना आवश्यक नहीं है,क्योंकि कंपाइलर काफी स्मार्ट है और printf काफी स्मार्ट है कि यदि तुम इसेएक वैल्यू सौंपते हो जो char होती है, यह पहले से जानता है कि यह एक integer होने वाली है,तो तुम्हें इस तरीके से स्पष्ट रूप से कास्ट करने की भी जरूरत नहीं है।हम अनिवार्य रूप से उन फॉर्मेट कोड्स का उपयोग करके इसे एक integer में इंप्लिसिटली कास्ट कर रहे हैं।ठीक है, तो वह बस साबित करता है कि जो मैंने दावा किया है वह मामला है,कि कैरेक्टर्स और संख्याओं के बीच यह समकक्षता है,वास्तव में कंप्यूटर की मेमोरी के अंदर मामला है।तो भले ही तुम hi विस्मयादिबोधक चिह्न स्टोर कर रहे हो,तकनीकी रूप से तुम आठ बिट्स में से प्रत्येक के तीन पैटर्न स्टोर कर रहे होजो तुम्हें ये डेसिमल संख्याएँ देते हैं, 72, 73, और 33,या विशेष रूप से ये पैटर्न यहाँ।
ठीक है, फिर एक string क्या है?
और यहाँ चीज़ें थोड़ी अधिक दिलचस्प हो जाती हैं।
एक string, जैसा हमने इसका उपयोग किया है, जैसे एक पूरा शब्द या एक वाक्यांश
या जब हमने आज क्लास शुरू की, जैसे टेक्स्ट का एक पूरा पैराग्राफ।
तो वह कई वैल्यूज हैं।
अब, वह हमारे लिए संभावित रूप से क्यों दिलचस्प है?
खैर, आइए एक लाइन कोड को string के रूप में लिखें।
तो यहाँ, उदाहरण के लिए, एक string के साथ एक कोड लाइन है।
आइए आगे बढ़ें और उसे अपने प्रोग्राम में डालें।
तो मैं यहाँ VS Code पर वापस जाने जा रहा हूँ और अपना टर्मिनल साफ करने जा रहा हूँ।
और मैं आगे बढ़कर यहाँ इस सारे कोड को एक पल के लिए हटाने जा रहा हूँ।
और मैं कुछ ऐसा करने जा रहा हूँ।
String s equals quote unquote high अब डबल कोट्स के साथ।
और अब, ठीक सप्ताह एक की तरह, मैं percent s backslash n प्रिंट करने जा रहा हूँ
और s का मान प्रिंट करने जा रहा हूँ।
पहले के अनुसार, क्योंकि string तकनीकी रूप से हमारे ट्रेनिंग व्हील्स में से एक है
बस कुछ हफ्तों के लिए, मैं अतिरिक्त रूप से
cs50.h शीर्ष पर शामिल करने जा रहा हूँ ताकि कंपाइलर इस शब्द, string के बारे में जाने।
ठीक है, आइए टर्मिनल में जाएँ, make high, डॉट स्लैश high, एंटर।
और हम वापस बिजनेस में हैं, अब इसे एक पूरी string के रूप में प्रिंट कर रहे हैं।
खैर, इस बार कंप्यूटर की मेमोरी के अंदर क्या चल रहा है?
खैर, मेरे पास अभी भी hi विस्मयादिबोधक चिह्न है, लेकिन अब यह एक string है।
खैर, पता चलता है कि कंप्यूटर की मेमोरी में वह जिस तरह से व्यवस्थित होने जा रहा है
ठीक पहले जैसा है।
c1, c2, c3 का कोई उल्लेख नहीं है, क्योंकि वे वेरिएबल्स मौजूद नहीं हैं।
बस एक वेरिएबल है, s, लेकिन यह मेमोरी के तीन बाइट्स को रेफर कर रहा है।
ऐसा लगता है hi विस्मयादिबोधक चिह्न।
और तुम तरह से देख सकते हो कि यह कहाँ जा रहा है।
जैसे एक string एक स्पॉइलर के रूप में पता चलता है वास्तव में बस क्या है?
यह बस कैरेक्टर्स का एक array होने जा रहा है।
अतः आज हम जो डॉट्स कनेक्ट करने की कोशिश कर रहे हैं।
तो फिलहाल, हालाँकि, यह एक सिंगल वेरिएबल है, s एक string,
जिसका मान hi विस्मयादिबोधक चिह्न है।
लेकिन तुम जानते हो क्या, यदि यह वास्तव में एक array है,
मुझे शर्त है कि हम अपने नए स्क्वायर bracket नोटेशन के साथ खेलना शुरू कर सकते हैं
और अपने वास्तविक कोड में उतना देख सकते हैं।
तो वास्तव में, मुझे आगे बढ़ने दो और यह करने दो।
VS Code में अब, आइए percent s उपयोग न करें।
आइए percent c, percent c, और percent c तीन बार उपयोग करें।
फिर बस s के बजाय, आइए इसे प्रिंट करें जैसे कि यह एक array है,
s bracket 0, s bracket 1, s bracket 2।
आइए VS Code में अपने टर्मिनल पर वापस जाएँ।
Make hi डॉट स्लैश hi, और कुछ नहीं बदला।
लेकिन मैं अब इसे एक कैरेक्टर एक समय में प्रिंट कर रहा हूँ
क्योंकि मैं इस मामले में हुड के नीचे क्या चल रहा है समझता हूँ।मैं वास्तव में अब इन वैल्यूज को देख सकता हूँ।आइए percent c को percent i में बदलें,और एक स्पेस जोड़ें बस इसे पढ़ना आसान बनाने के लिए।Percent i स्पेस, percent i स्पेस।मुझे पेरेंटहेसिस में अपने कास्ट्स की जरूरत नहीं है क्योंकि printf मेरे लिए यह करने के लिए काफी स्मार्ट है।Make hi फिर से डॉट स्लैश hi।वहाँ फिर से मेरा 72, 73, 33 है।हालाँकि, वह इस तथ्य से आया कि मैंने डबल कोट्स में hi विस्मयादिबोधक चिह्न डाला।तो वास्तव में यहाँ जो हो रहा है वह ऐसा लगता है कि एक string वास्तव में बस कैरेक्टर्स का एक array है।लेकिन कंप्यूटर percent s करते समय कैसे जानता है कि वास्तव में क्या प्रिंट करना है?दूसरे शब्दों में, यह मानना उचित है कि अंततः,यदि मेरे पास अधिक वेरिएबल्स, अधिक कोड हैं, वहाँकंप्यूटर की मेमोरी में अन्य सामान होने जा रहा है।Printf percent s उपयोग करते समय क्यों जानता है यहाँ रुकना है और बस वहाँ कैरेक्टर्स प्रिंट करते रहना नहीं है,विशेष रूप से यदि मेरे पास अधिक वेरिएबल्स और मेमोरी में अधिक सामान होते?खैर, आइए देखें कि इस array के अंत के ठीक बाद क्या है।आइए VS Code पर वापस जाएँ, और अब आइए थोड़ा पागल हों और एक चौथा percent i जोड़ें।और भले ही यह मौजूद नहीं होना चाहिए, आइए s bracket 3 करें, जो भले ही संख्या 3 है,यह चौथी लोकेशन है, लेकिन hi विस्मयादिबोधक चिह्न सिर्फ तीन वैल्यूज है।तो आइए इस array के अंत से एक लोकेशन आगे देखें।Make hi डॉट स्लैश hi दिलचस्प।ऐसा लगता है, और शायद यह सिर्फ किस्मत है, अच्छी या बुरी,कि कंप्यूटर की मेमोरी में चौथी बाइट शून्य लगती है।खैर, वह वास्तव में बहुत अधिक डिज़ाइन द्वारा है।पता चलता है यदि हम थोड़ा आगे देखें कन्वेंशन द्वारा,कंपाइलर हमारे लिए स्वचालित रूप से क्या करेगा वह समाप्त करना है, अर्थात्,डबल कोट्स में हम जो भी string डालते हैं उसे आठ ज़ीरो बिट्स के पैटर्न के साथ समाप्त करना।अधिक संक्षेप में, यह बस संख्या शून्य है, क्योंकि यदि तुम गणित करो,जहाँ तुम्हारे पास आठ ज़ीरोस हैं, यह तुम्हें डेसिमल में शून्य देता है।या अधिक तकनीकी रूप से, जिस तरह से यह आमतौर पर लिखा जाता है वह यह है,क्योंकि यह संख्या शून्य नहीं है जिसे हम स्क्रीन पर देखना चाहते हैं।Backslash zero, backslash n के समान, तरह का एक विशेष एस्केप कैरेक्टर है।इसका बस मतलब है शाब्दिक रूप से आठ ज़ीरो बिट्स, संख्या शून्य नहींजो तुम फोन नंबर या कुछ में देख सकते हो।तो भले ही हमने कहा string s equals quote unquote hi विस्मयादिबोधक चिह्न के साथ,प्रतीत होता तीन कैरेक्टर्स, तीन लंबाई की stringमेमोरी में वास्तव में कितने बाइट्स लेती लगती है?यह वास्तव में चार होने जा रही है।और यह स्वचालित रूप से होता है।यही डबल कोट्स तुम्हारे लिए कर रहे हैं।वे कंपाइलर को बता रहे हैं, यह सिर्फ एक सिंगल कैरेक्टर नहीं है।यह कैरेक्टर्स का एक अनुक्रम है।कृपया सुनिश्चित करो कि इसे मेरे लिए स्वचालित रूप से आठ ज़ीरो बिट्स के विशेष पैटर्न के साथ समाप्त करो।और आठ ज़ीरो बिट्स का वह विशेष पैटर्न वास्तव में एक नाम रखता है।यह तथाकथित null कैरेक्टर है, या संक्षेप में N-U-L।Null कैरेक्टर बस ज़ीरो बिट्स की एक बाइट है, और यह string के अंत को दर्शाता है।तुमने वास्तव में इसे पहले देखा है, यदि सुपर संक्षेप में, दो सप्ताह पहले।यहाँ हमारा ASCII चार्ट था, और हमने ज्यादातर इस कॉलम पर और इस कॉलम पर ध्यान केंद्रित किया।और फिर हमने यहाँ विस्मयादिबोधक चिह्न देखा।लेकिन इस सारे समय यहाँ, ASCII कैरेक्टर शून्य null है, N-U-L, जिसका बस मतलब है,तुम सभी आठ ज़ीरो बिट्स का उच्चारण कैसे करते हो।यह इस पूरे समय यहाँ रहा है।तो यह इस तरीके से क्यों किया जाता है?खैर, कंप्यूटर वास्तव में मेमोरी में कुछ कैसे प्रिंट कर रहा है?खैर, इसे जानने की जरूरत है कहाँ रुकना है।Printf काफी बेवकूफ है।संभावना है printf के अंदर।बस एक लूप है जो पहला कैरेक्टर, अगला कैरेक्टर,अगला कैरेक्टर प्रिंट करना शुरू करता है, और यह string के अंत की तलाश कर रहा है।क्यों?खैर, विचार करो क्या हो सकता है।मान लो तुम्हारे पास एक प्रोग्राम है जिसमें सिर्फ एक string नहीं, बल्कि दो हैं।उदाहरण के लिए, इस तरह दो strings।तो वास्तव में, मुझे यहाँ VS Code पर वापस जाने दो, अपना टर्मिनल साफ करो,और आइए इस प्रोग्राम को एक पल के लिए थोड़ा अधिक दिलचस्प बनाएँ।String t equals quote unquote by, उदाहरण के लिए।और फिर यहाँ नीचे, आइए दो printf करें।Percent s, backslash n, और printout s।Printf, percent s, backslash n, printout t।अब स्पष्ट होने के लिए, percent s का मतलब string प्लेसहोल्डर है।t और s बस वेरिएबल्स के नाम भी हैं।यहाँ कोई percent t नहीं है जिसका हम उपयोग करना चाहते हैं।ठीक है।मुझे अपने टर्मिनल में जाने दो, make high डॉट स्लैश high,और वोइला, मुझे high और by मिलता है, ठीक जैसे तुम पिछले सप्ताह उम्मीद करते।लेकिन कंप्यूटर की मेमोरी के अंदर क्या चल रहा है?खैर, जहाँ तक मैंने इसे दो वेरिएबल्स बनाने के लिए कहा है,s और t इस तरह, संभावना है कि कंप्यूटर की मेमोरी में जो हो रहा हैhigh यहाँ समाप्त हो रहा है, उर्फ s।t, क्योंकि इस प्रोग्राम में और कुछ नहीं है,शायद यहाँ समाप्त होने जा रहा है, b.y.e. विस्मयादिबोधक चिह्न।लेकिन यह इस विशेष स्क्रीन पर रैप करता है।t कुल 1, 2, 3, 4, 5 बाइट्स ले रहा है।ठीक जैसे high कुल 4 बाइट्स ले रहा है।क्योंकि कंपाइलर मेरे लिए स्वचालित रूप से जोड़ रहा हैbackslash 0, null कैरेक्टर, अन्य फ़ंक्शन्स को स्पष्ट करने के लिएकि यह string कहाँ समाप्त होती है।तो वास्तविक शब्दों में इसका क्या मतलब है?और यह 0 क्यों है?यह 0 क्यों है?जैसे बस क्योंकि, जैसे दिन के अंत में, हमारे पास सिर्फ बिट्स हैं।Chars के लिए हमारे पास आठ बिट्स हैं।तुम्हें कोई पैटर्न चुनना होगा।हम सभी वन्स चुन सकते थे।हम सभी ज़ीरोस चुन सकते थे।हम कुछ मनमाना चुन सकते थे।कमरे में मनुष्यों के एक गुच्छे ने सालों पहले फैसला किया कि आठ ज़ीरोस null कैरेक्टर का मतलब होगा।वह विशेष कैरेक्टर है जिसका हम स्ट्रिंग्स को इस तरीके से समाप्त करने के लिए उपयोग करेंगे।खैर, हमारे नए सिंटैक्स के साथ इसका क्या मतलब है?खैर, इसका मतलब है कि हम स्ट्रिंग्स के साथ भी घुसपैठ कर सकते हैं।तो भले ही पहला वेरिएबल s है और दूसरा t है,तुम तकनीकी रूप से घुसपैठ कर सकते हो और s bracket 0 और 1 और 2 और 3,t bracket 0, 1, 2, 3, और 4, और इसी तरह एक्सेस कर सकते हो।तो वास्तव में, यदि मैं वहाँ गहराई से डुबकी लगाना चाहता हूँ और वास्तव में वह देखना चाहता हूँ,खैर, मुझे आगे बढ़ने दो और यह करने दो।यहाँ VS Code में वापस।मुझे यहाँ एक परिष्करण करने दो।मेरे पास अब यहाँ मेरी दो स्ट्रिंग्स हैं।मैं जा सकता हूँ और, उदाहरण के लिए, यहाँ नीचे ठीक पहले की तरह, percent c, percent c,percent c, percent c, percent c, percent c, percent c।और यदि मैं फिर s bracket 0, s bracket 1, s bracket 2, उफ़, 2 करूँ,और फिर यहाँ नीचे, t bracket 0, t bracket 1, t bracket 2,t bracket 3।और मैं वह सिर्फ इसलिए कर रहा हूँ क्योंकि शब्द buy शब्द high से लंबा है।यदि मैं make high डॉट स्लैश high करूँ, वही सिद्धांत इस संदर्भ में भी काम करते हैं।लेकिन आइए एक दिलचस्प मोड़ जोड़ें बस क्योंकि यदि मेरे पास मेमोरी में ये वैल्यूज हैंइस प्रकार, खैर, यदि मेरे पास मेमोरी में दो शब्द हैं,मैं उन्हें एक array में भी उपयोग कर सकता हूँ।s और t या word 1 और word 2 होने के बजाय,मैं वास्तव में स्ट्रिंग्स को एक array में भी डाल सकता हूँ।तो आइए आगे बढ़ें और यह करें।मुझे VS Code पर वापस जाने दो।और अब मज़े के लिए, आइए आगे बढ़ें और यह करें।मुझे words नामक एक array दो जो दो स्ट्रिंग्स फिट करने जा रहा है।फिर पहले words में, words bracket 0, high डालो।फिर words bracket 1 में, buy डालो।यहाँ एकमात्र नई चीज़ यह है कि मैं अब स्ट्रिंग्स का एक array बना रहा हूँints के array के बजाय।लेकिन सारा सिंटैक्स ठीक वैसा ही है।मैं इन चीज़ों को कैसे प्रिंट कर सकता हूँ?खैर, ठीक पहले की तरह, मैं printf percent s backslash n कर सकता हूँऔर words bracket 0 प्रिंट कर सकता हूँ।फिर मैं printf quote unquote s backslash n words bracket 1 कर सकता हूँ।फिर से, मैं बस वही सरल सिंटैक्स लागू कर रहा हूँ जो हमने पहले देखा,डॉट स्लैश high।फिर से, इस प्रोग्राम के छठे संस्करण का, सही?मैं बस सिंटैक्टिक रूप से कूद रहा हूँयह प्रदर्शित करने के लिए कि ये बस अलग लेंस हैं जिनके माध्यम सेठीक वही विचार देखना है।और जबकि एक सामान्य व्यक्ति यह नहीं करेगा,हम शब्दों के arrays के साथ मेमोरी में वास्तव में क्या चल रहा है के बारे में सोच सकते हैंजब वे शब्द खुद कैरेक्टर्स के arrays हैंक्योंकि एक शब्द बस एक string है।तो यह कोड यहाँ हमें मेमोरी में कुछ ऐसा देता है।एक पल पहले उस प्रोग्राम में, यह words bracket 0 है।यह words bracket 1 है।एकमात्र चीज़ जो अलग है वह है मैं उन्हें s और t नहीं कह रहा।मैंने उन्हें एक नाम दिया है दो लोकेशन्स के साथ, 0 और 1।खैर, यदि इनमें से प्रत्येक वैल्यू खुद एक string है,खैर, तुमने पहले कहा कि एक string बस एक array है।तो हम वास्तव में इन दो स्ट्रिंग्स के बारे में सोच सकते हैं,भले ही सिंटैक्स थोड़ा पागल हो रहा हो,दो सेट स्क्वायर bracket नोटेशन का उपयोग करके,जहाँ मैं अपने शब्दों के array में इंडेक्स कर सकता हूँऔर फिर उस शब्द के व्यक्तिगत अक्षरों में इंडेक्स कर सकता हूँबस अधिक स्क्वायर ब्रैकेट्स उपयोग करके।और फिर से, यह बस एक बिंदु प्रदर्शित करने के लिए है,क्योंकि एक सामान्य व्यक्ति यह करेगा।लेकिन यदि मैं VS Code पर वापस जाऊँ, इन दो स्ट्रिंग्स को प्रिंट करने के बजाय,क्यों न मैं कुछ ऐसा करूँ?Printf quote unquote percent c, percent c, percent c, backslash n।फिर आइए पहला शब्द प्रिंट करें, लेकिन उसमें पहला कैरेक्टर।आइए पहला शब्द प्रिंट करें, लेकिन उसमें दूसरा कैरेक्टर।पहला शब्द, लेकिन उसमें तीसरा कैरेक्टर।और भले ही मैं तीसरा और दूसरा और पहला कह रहा हूँ,हम दूसरा शब्द प्रिंट करने जा रहे हैं, percent c, percent c, percent c,percent c, backslash n।फिर words bracket।मैं इस array में दूसरे शब्द तक कैसे पहुँचूँ?Words bracket one, उसमें पहला कैरेक्टर।Words bracket one, उसमें दूसरा कैरेक्टर।Words bracket one, उसमें तीसरा कैरेक्टर।Words bracket one, उसमें अंतिम कैरेक्टर।और फिर से, यह बस एक बिंदु प्रदर्शित करने के लिए है,लेकिन यदि मैं अब make high करूँ, डॉट स्लैश high,हम जो कुछ भी चल रहा है उस पर पूरा नियंत्रण रखते हैं।यदि तुम अब सहमत हो और समझते हो कि एक array को स्क्वायर bracket नोटेशन के साथ इंडेक्स किया जा सकता हैजैसा कि एक string कर सकता है, क्योंकि एक string खुद बस एक array है।स्ट्रिंग्स आज के उद्देश्यों के लिए arrays हैं फिर।इनमें से किसी और सभी ट्रिक्स पर प्रश्न?नहीं?ठीक है।हाँ, आगे।यह एक स्थापित करने योग्य string है।यह बोर्ड के पहले भाग में एक array में था।ठीक।यह जैसे इस अंतिम संख्या में एक पूर्ण औसत था।क्या वह एक array स्थापित कर रहा है?जैसे तुम एक array कैसे स्थापित करते हो?तुम एक array कैसे स्थापित या बनाते हो?खैर, इस प्रोग्राम के संदर्भ में, यदि मैं VS Code पर वापस जाऊँ, लाइन छह यहाँमुझे साइज दो का एक array देता है, दो स्ट्रिंग्स का एक array, यदि तुम चाहो।पिछला उदाहरण जिसके साथ हम खेल रहे थे, जो मेरे स्कोर्स थे।उफ़, गलत प्रोग्राम।गलत फाइल।यदि मैं पहले की तरह scores.c खोलूँ, यह लाइन यहाँ, लाइन नौ,मुझे n integers का एक array देता है।तो वह है जो मेमोरी में array स्थापित या बनाता है।तुम एक नाम, साइज, और टाइप निर्दिष्ट करते हो।बस इतना ही।और आज एकमात्र नई चीज़, फिर से, स्क्वायर bracket नोटेशन है,जो इस संदर्भ में उस साइज का एक array बनाता है।लेकिन एक बार जब यह मौजूद होता है, तुम फिर मेमोरी के उस चंक कोस्क्वायर ब्रैकेट्स का उपयोग करके भी एक्सेस कर सकते हो।Arrays पर अन्य प्रश्न?हाँ, आगे।क्या तुम array में सभी वैल्यूज को एक व्यवहार के रूप में टॉप कर सकते हो?या तुम्हें इंडेक्स बाय इंडेक्स जाकर एक ऐप घोषित करने की जरूरत है?अच्छा प्रश्न।क्या तुम्हें array के अंदर चीज़ें डालने के लिए इंडेक्स बाय इंडेक्स जाने की जरूरत है?संक्षिप्त जवाब, नहीं।तो मुझे फिर से, scores.c पहले वाला खोलने दो।और जो मैं अपने प्रोग्राम के पहले संस्करण में कर सकता थावह कुछ ऐसा होता।मैं 72, 73, 33 कर सकता था।और मैंने जानबूझकर यह नहीं दिखाया क्योंकि मैं बहुत अधिक जटिलता नहीं जोड़ना चाहता था।लेकिन तुम कर्ली ब्रेसेस का इस नए तरीके से उपयोग कर सकते होऔर array को एक लाइन में इनिशियलाइज़ कर सकते हो।और उस मामले में, तुम्हें साइज भी निर्दिष्ट करने की जरूरत नहीं हैक्योंकि कंपाइलर बेवकूफ नहीं है।यह पता लगा सकता है कि यदि दाईं ओर तीन संख्याएँ हैं,यह जानता है कि उन्हें डालने के लिए बाईं ओर तीन एलिमेंट्स की जरूरत है।लेकिन मुझे उसे अनडू करने दो और इसे बस जैसा मैंने किया छोड़ दूँ।लेकिन संक्षिप्त जवाब, हाँ।तुम एक array को स्टैटिकली इनिशियलाइज़ कर सकते हो यदि तुम सभी वैल्यूज पहले से जानते होऔर getInt उपयोग करते समय नहीं उस मामले में।
ठीक।
तो यदि तुम इस विचार पर बोर्ड हो कि एक string बस एक array है
और वह array हमेशा null टर्मिनेटेड है,
हम अब उस ज्ञान का उपयोग कुछ सरल समस्याएँ हल करने के लिए कर सकते हैं
और समस्याएँ जो दूसरों ने हमसे पहले हल की हैं।
तो मुझे VS Code में उस फाइल को बंद करने दो।
मुझे यहाँ एक और प्रोग्राम खोलने दो जिसे length.c कहा जाता है।
और आइए स्ट्रिंग्स की लंबाई के साथ इस प्रकार खेलें।
मुझे शीर्ष पर CS50 लाइब्रेरी शामिल करने दो।
मुझे उसके बाद standard IO शामिल करने दो।
मुझे उसके बाद int main void करने दो।
और फिर main के अंदर, आइए उपयोगकर्ता से उनके नाम के लिए प्रॉम्प्ट करें
getString का उपयोग करके और आज बस name colon कहें।
और फिर उसके बाद, आइए व्यक्ति के नाम की लंबाई पता लगाएँ।
जैसे DAVID, मुझे पाँच का जवाब मिलना चाहिए।
और KELLY, हमें पाँच का जवाब मिलना चाहिए।
और उम्मीद है लंबे या छोटे नाम के लिए,
हमें सही जवाब भी मिलेगा।
तो मैं एक string में कैरेक्टर्स की संख्या कैसे गिन सकता हूँ?
खैर, string बस एक array है और वह array null कैरेक्टर के साथ समाप्त होता है।
इसके करने के बहुत सारे तरीके हैं, लेकिन मुझे आगे बढ़ने दो और यह करने दो।
मुझे n नामक एक वेरिएबल बनाने दो, जिसमें अंततः नाम की लंबाई होगी।
और मैं इसे शून्य के बराबर सेट करने जा रहा हूँ क्योंकि मुझे लंबाई के बारे में अभी कुछ नहीं पता।
फिर मैं यह for लूप के साथ कर सकता हूँ, लेकिन इस बार मैं while लूप उपयोग करना पसंद करता हूँ।
मैं निम्नलिखित कहने जा रहा हूँ।
जबकि व्यक्ति का नाम उस लोकेशन पर backslash zero के बराबर नहीं है,
आगे बढ़ो और n के मान में एक जोड़ो।
और फिर इस सब के बाद, आगे बढ़ो और percent i backslash n के साथ n का मान प्रिंट करो।
तो यहाँ क्या चल रहा है?
यह कहने में आसान है जब तुम पहले से जानते हो कि तुम कहाँ जाना चाहते हो,
लेकिन अभ्यास के साथ तुम भी इसे काफी जल्दी बैंग आउट कर सकते हो।
n मेरी string की लंबाई रखने जा रहा है।
मेरे लूप में यहाँ एक बूलियन एक्सप्रेशन है जो बस प्रश्न पूछ रहा है,
क्या name वर्तमान n के मान पर null कैरेक्टर के बराबर नहीं है?
दूसरे शब्दों में, तुम खुद से पूछ रहे हो, क्या यह कैरेक्टर null है?
क्या यह कैरेक्टर null है?
क्या यह कैरेक्टर null है?
क्या यह कैरेक्टर null है?
क्या यह कैरेक्टर null है?
और यदि नहीं, तुम जाते रहते हो।
तुम जाते रहते हो।
और यह तरह की चतुर ट्रिक है क्योंकि मैं n उपयोग कर रहा हूँ और लूप के अंदर इसे इंक्रिमेंट कर रहा हूँ।
तो जब मैं d देखता हूँ, वह backslash zero के बराबर नहीं है।
तो मैं n इंक्रिमेंट करता हूँ।
अब n एक है।
तो मैं name bracket one देखता हूँ।
name bracket one क्या है?
यदि यह मेरा नाम है?
a।
a backslash zero के बराबर नहीं है।तो यह n इंक्रिमेंट करता है।लोकेशन दो में d, a, v, id क्या है?v।v backslash n के बराबर नहीं है।तो हम i के साथ दोहराते हैं।हम d के साथ दोहराते हैं।और फिर हम मेरे नाम के अंत तक पहुँचते हैं, जो null कैरेक्टर है,क्योंकि getString फ़ंक्शन और c ने इसे मेरे लिए स्वचालित रूप से वहाँ रखा।Null कैरेक्टर backslash zero के बराबर है और किसी और समय इंक्रिमेंट नहीं होता।तो कहानी में इस बिंदु पर लाइन 13 पर, n अभी भी पाँच है, क्योंकि मैंनेnull कैरेक्टर नहीं गिना।तो मुझे उम्मीद है कि मैं स्क्रीन पर पाँच देखूँगा।यह बस तरह का बहुत यांत्रिक तरीका है चेक करने, चेक करने, चेक करने,चेक करने का, इन्फरेंस के माध्यम से पता लगाने की कोशिश करने का कि string कितनी लंबी है,क्योंकि यह उतनी लंबी है जितना backslash zero, null कैरेक्टर तक पहुँचने में लगता है।तो आइए make length एंटर डॉट स्लैश length करें।मेरा नाम टाइप करो, David, और मुझे वास्तव में पाँच मिलता है।आइए आगे बढ़ें और डॉट स्लैश length करें।Kelly, मुझे वास्तव में पाँच मिलता है।और उम्मीद है छोटे और लंबे नामों के लिए,मुझे ठीक वही चीज़ भी मिलेगी।वास्तव में, हम एक कॉर्नर केस आज़मा सकते हैं, डॉट स्लैश length एंटर।आइए इसे बिल्कुल नाम न दें।यदि मैं यहाँ बस एंटर दबाऊँ, व्यक्ति के नाम की लंबाई क्या होनी चाहिए?शून्य, जो गलत नहीं है।यह शाब्दिक रूप से सच है।लेकिन वह इसलिए क्योंकि हमें अनिवार्य रूप से quote unquote वापस मिलने जा रहा है।लेकिन भले ही यह कंप्यूटर की मेमोरी में quote unquote है,यह अभी भी एक बाइट लेगा, क्योंकि get string फ़ंक्शनstring के अंत में अभी भी null डालेगा, भले ही उसमें कोई कैरेक्टर न हो।तो पता चलता है कि यह कुछ ऐसा नहीं है जो तुम्हें बार-बार करने की जरूरत है,जैसे एक वेरिएबल इनिशियलाइज़ करना, इस तरह के लूप का उपयोग करना।पता चलता है कि इस समस्या के बेहतर समाधान हैं।तुम्हें इस पहिए को खुद फिर से आविष्कार करने की जरूरत नहीं है,क्योंकि पता चलता है, standard io.h और cs50.h के अलावा,और जैसा तुमने शायद प्रॉब्लम्स एट वन में देखा, math.h और शायद अन्य,वहाँ अन्य लाइब्रेरियाँ हैं, अर्थात् string लाइब्रेरी खुद।वास्तव में, यदि तुम cs50 मैनुअल में जाओ, तुम string.h नामक हेडर फाइलके लिए डॉक्यूमेंटेशन देख सकते हो, जिसमें घोषणाएँ हैं,अर्थात् प्रोटोटाइप, बहुत सारे मददगार फ़ंक्शन्स के लिए।वास्तव में, इसके मैनुअल पेज इस URL पर हैं।सबसे महत्वपूर्ण फ़ंक्शन, और वह जिसे हम अगले कुछ हफ्तों के लिए इतनी बार उपयोग करने वाले हैं,अद्भुत रूप से stirlang कहलाता है string length के लिए।किसी और ने शाब्दिक रूप से दशकों पहले कोड लिखा जो अनिवार्य रूप से काफीइस तरह दिखता है, लेकिन इसे एक फ़ंक्शन में पैकेज किया जिसे तुम और मैं उपयोग कर सकते हैं,ताकि हमें string की लंबाई गिनने के लिए इन मूर्खतापूर्ण छल्लों से न कूदना पड़े।हम बस stirling length फ़ंक्शन से पूछ सकते हैं कि string की लंबाई क्या है।लेकिन संभावना है, यदि हम उस C कोड को देखें जो किसी ने दशकों पहले लिखा,यह वास्तव में काफी इस तरह दिखेगा।तो मैं इस प्रोग्राम को कैसे सरल बना सकता हूँ?खैर, मैं यहाँ इस सारे कोड से छुटकारा पा सकता हूँ।मैं अपनी फाइल के शीर्ष पर string.h शामिल कर सकता हूँ।और फिर मैं काफी सरलता से कुछ ऐसा कर सकता हूँ।int length equals stirlang of name।वह वेरिएबल length में डालने जा रहा है।वास्तव में, आइए इसे सुसंगत रखें।int n equals stir length of name।और फिर लाइन नौ पर, आइए इसे प्रिंट करें।आइए यह आज़माएँ।Make length डॉट स्लैश length।David।ठीक।Kelly।ठीक।और कोई नहीं।और शून्य।ऐसा लगता है कि अब काम कर रहा है।तो यह एक पहिया है जिसे हमें फिर से आविष्कार करने की जरूरत नहीं है।और ईमानदारी से, अब डिज़ाइन के मामले में, मुझे वास्तव में वेरिएबल n की अब जरूरत नहीं है।याद करो कि हम अपने फ़ंक्शन्स को नेस्ट कर सकते हैं ठीक जैसे हमने average के साथ पहले किया।तो मुझे उस लाइन से छुटकारा पाने दो और बस कहें,stirlang of name वास्तव में यहाँ पूरी तरह से उचित है।
ठीक।
तो हम इसके साथ और क्या कर सकते हैं?
खैर, आइए डिज़ाइन के कुछ अन्य मामलों पर विचार करें।
मुझे length.c बंद करने दो।
और आइए अपना एक और प्रोग्राम बनाएँ जिसे string.c कहा जाता है,
जिसमें हम अब इस लाइब्रेरी और अन्य के साथ खेलेंगे।
मुझे cs50.h शामिल करने दो।
मुझे standard io.h शामिल करने दो।
मुझे string.h भी शामिल करने दो।
ठीक।
अब मैं क्या करना चाहता हूँ?
खैर, int main void और main के अंदर, आइए एक प्रोग्राम लिखें जो
एक string को कैरेक्टर बाय कैरेक्टर प्रिंट करता है बस इन मैकेनिक्स को प्रदर्शित करने के लिए।
तो string s equals getString।
और मैं उपयोगकर्ता से कुछ इनपुट पूछने जा रहा हूँ,
क्योंकि मैं बस किसी भी पुरानी string के साथ खेलना चाहता हूँ।
मैं आगे बढ़कर प्रोएक्टिवली यहाँ output कहने जा रहा हूँ।
और मैं जानबूझकर वहाँ न्यू लाइन कैरेक्टर उपयोग नहीं करने जा रहा।
इसके नीचे अब, मेरे पास एक for लूप होगा, हालाँकि मैं while लूप उपयोग कर सकता था,
जो कहता है int i equals 0 i is less than stirlang of s, वह string जो मैंने मानव से अभी ली,
और प्रत्येक इटरेशन पर i इंक्रिमेंट करो।
और प्रत्येक इटरेशन पर, उस string में सिर्फ एक कैरेक्टर प्रिंट करो, विशेष रूप से s लोकेशन i पर।
और फिर इस प्रोग्राम के बहुत नीचे, आइए बस एक सिंगल backslash n प्रिंट करें
कैरेक्टर को नई लाइन पर ले जाने के लिए।
लंबी कहानी छोटी, मैंने क्या किया?
मैंने एक मूर्खतापूर्ण छोटा प्रोग्राम लिखा जो उपयोगकर्ता से एक string के लिए प्रॉम्प्ट करता है,
उसके बाद शब्द output प्रिंट करता है, और फिर यह वह शब्द प्रिंट करता है जो उन्होंने टाइप किया कैरेक्टर बाय कैरेक्टर बाय कैरेक्टर बाय कैरेक्टर
जब तक कि यह string की लंबाई के आधार पर string के अंत तक नहीं पहुँच जाता जो stirlang द्वारा लौटाया गया।
तो आइए आगे बढ़ें और इसे रन करें।
अपनी टर्मिनल विंडो में, मैं make string डॉट स्लैश string करने जा रहा हूँ,
और मैं अपना खुद का नाम टाइप करूँगा और पहले।
यह एक सूक्ष्मता थी।
मैंने जानबूझकर यहाँ दो स्पेसेस लिखे, क्योंकि नुक्ताचीनी करने के लिए,
मैं चाहता था कि input और output पूरी तरह से लाइन अप हों।
तो तुम देख सकते हो क्या हो रहा है।
वास्तव में, यदि मैं यहाँ एंटर करूँ, अब मैं देखता हूँ input is David, output is David भी।
तो वह बस एक फॉर्मेटिंग ट्रिक थी जिसका मैंने पूर्वाभास किया।
यह प्रोग्राम सही क्यों है लेकिन तर्कपूर्वक अच्छी तरह डिज़ाइन नहीं है?
यह काफी अच्छा है कि यह stirlang फ़ंक्शन का उपयोग कर रहा है।
मैंने अनावश्यक रूप से एक पहिया फिर से आविष्कार नहीं किया, लेकिन एक अक्षमता है जो तरह की सूक्ष्म है।
और यह for लूप कैसे काम करता है से संबंधित है।
कोई विचार?
यह प्रोग्राम, मैं दावा करता हूँ, कहीं अनावश्यक काम कर रहा है।
तुम्हें कैरेक्टर बाय कैरेक्टर आउटपुट क्यों करना पड़ता है?
ठीक।वह निश्चित रूप से बेवकूफी भरा है।तुम्हें कैरेक्टर बाय कैरेक्टर आउटपुट करने की जरूरत नहीं है।वह बस मेरा शैक्षणिक निर्णय यहाँ है।तो सही, लेकिन वह प्रश्न नहीं है जिसकी हम तलाश कर रहे हैं।एक दूसरी बेवकूफी भरी चीज़ है।हाँ?इस लूप से हर बार, और यह मेरी सचेत पसंद उतनी नहीं है,बल्कि मेरी गलती, मैं s की लंबाई बार-बार चेक कर रहा हूँ।क्यों?क्योंकि याद करो for लूप कैसे काम करता है।इनिशियलाइज़ेशन बहुत शुरुआत में एक बार होता है।फिर तुम बूलियन एक्सप्रेशन चेक करते हो।फिर यदि यह true है, तुम कोड करते हो।फिर तुम अपडेट करते हो।फिर तुम बूलियन एक्सप्रेशन चेक करते हो।फिर तुम कोड करते हो।अपडेट, बूलियन एक्सप्रेशन, तुम कोड करते हो।लेकिन हर बार जब तुम इस बूलियन एक्सप्रेशन का मूल्यांकन करते हो, तुम पूछ रहे हो,क्या i s की stir length से कम है?लेकिन यह एक फ़ंक्शन कॉल है।जैसे तुम शाब्दिक रूप से stirlang बार-बार बार-बार उपयोग कर रहे हो।और जैसे एक पागल व्यक्ति, तुम कंप्यूटर से पूछ रहे हो, s की लंबाई क्या है?s की लंबाई क्या है?s की लंबाई क्या है?s की लंबाई क्या है?यह बदलने वाला नहीं है।यह वही रहने वाला है चाहे जो हो।तो हम इसे कैसे ठीक करें?खैर, मैं इसे कुछ तरीकों से हल कर सकता हूँ।जैसे मैं, उदाहरण के लिए, यहाँ नीचे, int n equals stirlang of s कर सकता हूँऔर इसे एक वेरिएबल n में स्टोर कर सकता हूँ और बस वह कर सकता हूँ।मुझे लगता है कि वह अक्षमता को खत्म करता है क्योंकि अब मैंs की लंबाई एक बार कैलकुलेट करता हूँ।यह बदलने वाला नहीं है, न ही मेरा वेरिएबल।तो मैं अब उस वेरिएबल का उपयोग और पुन: उपयोग कर सकता हूँ।यह बस मुझे थोड़ा समय बचा रहा है, शायद माइक्रोसेकंड्स।लेकिन जब तुम बड़े प्रोग्राम लिख रहे हो और तुम लूप्स में चीज़ें कर रहे हो,यदि वह लूप तीन बार या पाँच नहीं, बल्कि एक मिलियन बार,मिलियन्स ऑफ टाइम्स रन हो रहा है, वे सभी माइक्रोसेकंड्स, मिलिसेकंड्स,बहुत अच्छी तरह जुड़ सकते हैं।लेकिन पता चलता है कि हम कुछ सिंटैक्टिक ट्रिक्स भी कर सकते हैं।मैंने पहले इसकी ओर इशारा किया।यदि तुम एक नहीं बल्कि दो वेरिएबल्स इनिशियलाइज़ करना चाहते हो,तुम वास्तव में इसे पहली सेमीकोलन से पहले सब कर सकते हो, जैसे वह।तो अब लाइन 9 पर, मैं i नामक एक वेरिएबल घोषित कर रहा हूँ और इसे 0 के बराबर सेट कर रहा हूँ।और मैं n नामक दूसरा वेरिएबल घोषित कर रहा हूँ, वही टाइप, int,और इसे s की लंबाई के बराबर सेट कर रहा हूँ।और अब मैं उसका बार-बार उपयोग कर सकता हूँ।अब एक साइड नोट के रूप में, यह थोड़ा सफेद झूठ हैक्योंकि स्मार्ट कंपाइलर्स आजकल इतने उन्नत हैंकि वे नोटिस करेंगे कि तुम एक लूप के अंदर stirling बार-बार कॉल कर रहे होऔर वे बस इसे तुम्हारे लिए ठीक कर देंगे, तुम्हारे अनजान।लेकिन यह समस्याओं के एक क्लास का प्रतिनिधि हैजिसे तुम्हें अपनी खुद की मानव आँखों से स्पॉट करने और पूरी तरह से बचने में सक्षम होना चाहिएताकि तुम अधिक समय और अधिक कंप्यूट और अधिक पैसे कुछ अर्थ मेंबर्बाद न करो जितना तुम्हें अन्यथा इस मामले में जरूरत हो सकती है।उस पर कोई प्रश्न?ऑप्टिमाइज़ेशन, हाँ।तुम फिर से int नहीं कहते।बाधा यह है कि तुम्हें अपने सभी इनिशियलाइज़ेशन के लिए वही डेटा टाइप उपयोग करना होगा।तो तुम्हें बेहतर आशा करनी चाहिए कि तुम इस मामले में सिर्फ ints चाहते हो।अन्यथा, तुम्हें इसे बाहर निकालना होगा और वह करना होगा जो मैंने पहले किया।अच्छा प्रश्न।इस पर अन्य?हाँ?यह स्पेसेस के लिए कब हिसाब करता है?एक स्पेस बस एक कैरेक्टर है, ASCII कैरेक्टर संख्या 32।तो इसके बारे में कुछ खास नहीं है।यह तरह का अदृश्य है, लेकिन यह वहाँ है।इसे किसी भी अन्य कैरेक्टर की तरह ट्रीट किया जाता है।कोई विशेष हिसाब बिल्कुल नहीं है।Null कैरेक्टर, जो भी अदृश्य है, विशेष है क्योंकि printf और sterlingउस वेरिएबल के अंत, उस वैल्यू के अंत की तलाश करना जानते हैं।
ठीक, आइए यहाँ इनमें से कुछ विचारों का एक और प्रदर्शन आज़माएँ।
मुझे एक और फाइल में जाने दो जिसे हम बनाएंगे कैसे about uppercase.c।
आइए एक सुपर सरल प्रोग्राम लिखें जो उस string को अपरकेस करता है जो मानव टाइप करता है
और देखें कि हम इसे कैसे अच्छा, बेहतर, और सर्वश्रेष्ठ कर सकते हैं।
तो मैं इस फाइल को uppercase.c कहूँगा इसके अंदर।
आइए अपने अब दोस्तों का उपयोग करें, include cs50.h।
आइए include standard IO.h करें।
आइए फिर अंत में include कैसे about string.h करें।
और यहाँ main के अंदर लक्ष्य उपयोगकर्ता से एक string पाना होगा।
तो string s equals get string।
और हम उपयोगकर्ता से एक before string पूछने जा रहे हैं, जो दर्शाता है कि उन्होंने क्या टाइप किया
इससे पहले कि हम सब कुछ अपरकेस करें।
फिर मैं उसके बाद आगे बढ़कर बस एक प्लेसहोल्डर के रूप में after प्रिंट करने जा रहा हूँ
और दो स्पेसेस बस नुक्ताचीनी करने के लिए ताकि टेक्स्ट स्क्रीन पर वर्टिकली लाइन अप हो।
अब मैं निम्नलिखित करने जा रहा हूँ for int i equals 0, n equals sterling of s,
सेमीकोलन i less than n, ठीक पहले की तरह, i plus plus।
तो मैं बस एक लूप शुरू कर रहा हूँ जो उस string पर इटेरेट करने जा रहा है जो मानव ने टाइप की।
अब, यदि मेरे जीवन में लक्ष्य उपयोगकर्ता के इनपुट को लोअर केस से, यदि वास्तव में लोअर केस में है
उपरकेस में बदलना है, आइए उसे शाब्दिक रूप से व्यक्त करें।
यदि string में वर्तमान कैरेक्टर, तो s bracket i, quote
unquote a से अधिक या बराबर है, और s bracket i quote unquote z से कम या बराबर है सिंगल कोट्स का उपयोग करके,
यह तर्कपूर्वक प्रश्न व्यक्त करने का एक बहुत चतुर तरीका है, क्या यह लोअर केस है?
हम जानते हैं अपने ASCII चार्ट से सप्ताह 0 से कि ASCII चार्ट में न केवल सभी अपरकेस अक्षरों को दर्शाने वाली संख्याएँ हैं,
बल्कि सभी लोअर केस अक्षरों को दर्शाने वाली संख्याएँ भी हैं।
लोअर केस a, उदाहरण के लिए, 97 है, और उसके बाद वे सभी संलग्न हैं।
तो हम वास्तव में ठीक पहले की तरह, chars को ints और ints को chars के रूप में ट्रीट कर सकते हैं
और इन chars के बारे में गणितीय प्रश्न पूछ सकते हैं और कह सकते हैं,
क्या s bracket i a और z के बीच है समावेशी?
तो यदि यह लोअर केस है, और मैं स्पष्टता के लिए यहाँ एक कमेंट जोड़ूँगा,
यदि s bracket i लोअर केस है, हम क्या करना चाहते हैं?
हम इसे अपरकेस में मजबूर करना चाहते हैं।
तो यह एक छोटी ट्रिक है जो मैं इस प्रकार कर सकता हूँ।
Print f, वर्तमान कैरेक्टर, लेकिन आइए उस पर कुछ गणित करें।
आइए s bracket i को कुछ मान घटाकर बदलें।
खैर, वह मान क्या हो सकता है?
खैर, याद करो सप्ताह 0 से, हमारा ASCII चार्ट यहाँ।
और आइए ध्यान केंद्रित करें, उदाहरण के लिए, यहाँ लोअर केस अक्षरों पर
और यहाँ अपरकेस अक्षरों पर।
सभी अपर और लोअर केस अक्षरों के बीच दूरी क्या है?
यह 32 है, सही?
और लोअर केस अक्षर बड़े हैं।
तो यह मानना उचित है, यदि मैं बस लोअर केस अक्षर से 32 घटा दूँ,यह तुरंत मुझे उसके अपरकेस संस्करण पर ले जाएगा।तो यह तरह का कूल है।तो मैं वास्तव में VS Code पर वापस जा सकता हूँ, और मैं शाब्दिक रूप से संख्या 32 घटा सकता हूँइस मामले में, क्योंकि ASCII एक स्टैंडर्ड है, यह बदलने वाला नहीं है।Else, यदि अक्षर लोअर केस नहीं है, मैं बस आगे बढ़करइसे बिना किसी गणित के अपरिवर्तित प्रिंट करने जा रहा हूँ।और मैं एक कमेंट के साथ स्पष्ट करूँगा, else if not lower case,वहाँ क्या चल रहा है स्पष्ट करता है।ठीक है, मुझे अपनी टर्मिनल विंडो में make uppercase करने दो,डॉट स्लैश uppercase, आइए अपना नाम सब लोअर केस में टाइप करें,और मुझे वापस मिलता है, David, ओह, मामूली बग, कुछ बग्स, वास्तव में।मुझे अपनी स्पेसिंग ठीक करने दो।मुझे लगता है कि मुझे शब्द after के बाद एक और स्पेस चाहिए।और अपने प्रोग्राम के बहुत नीचे, मुझे लगता है कि मुझे एक backslash n चाहिए।अब, आइए फिर से रन करें, make an uppercase, डॉट स्लैश uppercase, एंटर, d-a-v-i-d।और अब, यह सब को अपरकेस में मजबूर कर रहा है।इस बीच, यदि मैं इसे एक बार और करूँ और नाम कैपिटलाइज़्ड टाइप करूँ,यह अभी भी बाकी सब को अपरकेस में मजबूर करने जा रहा है।प्रश्न?ओह, मैं बेवकूफ हूँ।ठीक, धन्यवाद।हाँ, मैंने after की वर्तनी गलत की, अन्यथा मेरा अलाइनमेंट काम करता।तो आइए यह फिर से करें, make uppercase, यदि केवल ताकि हम साबित कर सकें कि यह वही है,d-a-v-i-d सब लोअर केस में, और वहाँ हम जाते हैं।वह था, धन्यवाद, इरादा।ठीक, तो यह तरह की छोटी ट्रिक है, लेकिन यह तरह की थकाऊ है, सही?जैसे Microsoft Word, Google Docs सभी में केस टॉगल करने की क्षमता हैउपरकेस से लोअरकेस या लोअरकेस से अपरकेस।यह तरह का परेशान करने वाला है कि उन्हें कुछ इतना सरल, प्रतीत होता,और इतना आम हासिल करने के लिए इतना कोड लिखना पड़ता है।खैर, पता चलता है कि यहाँ भी एक बेहतर तरीका है।String लाइब्रेरी होने के अलावा, ctype लाइब्रेरी भी है।ctype.h में, एक और हेडर फाइल, बहुत सारे अन्य फ़ंक्शन्स हैं जो उपयोगी हैंजो ASCII में कैरेक्टर्स से संबंधित हैं।तो उदाहरण के लिए, यदि हम आगे बढ़ें और इसका उपयोग इस प्रकार करें,मैं अपनी फाइल के शीर्ष पर अब ctype.h शामिल करने जा रहा हूँ।पता चलता है कि ऐसे फ़ंक्शन्स होने जा रहे हैं जिनके माध्यम से मैं वास्तव में ये प्रश्न खुद पूछ सकता हूँ।उदाहरण के लिए, प्रोग्राम के इस अगले संस्करण में, मुझे इस चतुर लेकिन काफी विस्तृत गणित की जरूरत नहीं है।मैं बस कह सकता हूँ यदि is lower फ़ंक्शन, जो ctype लाइब्रेरी से आता है,sbracket i पास करने पर true लौटाता है तो फिर अक्षर को लोअर अपरकेस में बदलो 32 घटाकर।लेकिन मुझे यह मानसिक गणित या कोड में गणित करने की भी जरूरत नहीं है।मैं ctype लाइब्रेरी से, toUpper नामक एक फ़ंक्शन भी उपयोग कर सकता हूँ, जो इनपुट के रूप में sbracket i जैसा कैरेक्टर लेता हैऔर किसी और के फ़ंक्शन को मेरे लिए काम करने दो।तो मुझे यहाँ अपनी टर्मिनल विंडो में वापस जाने दो।मुझे make uppercase अब डॉट स्लैश uppercase एंटर before david करने दो।यह अब भी काम करता है।लेकिन यदि मैं वास्तव में ctype लाइब्रेरी के डॉक्यूमेंटेशन में गहराई से देखूँ,तुम देखोगे कि तुम बस किसी भी कैरेक्टर पर is lower फ़ंक्शन उपयोग कर सकते हो,और यह बहुत बुद्धिमत्ता से इसे अपरकेस करेगा यदि यह वास्तव में लोअरकेस है।तो किसी और ने सालों पहले कंडीशनल कोड लिखा जो चेक करता है कि यह छोटे a और छोटे z के बीच है या नहीं।तो यह जानते हुए, और तुम वास्तव में डॉक्यूमेंटेशन में देखोगे, मुझे इस else की भी जरूरत नहीं है।मैं इसके बजाय इस पूरे कंडीशनल से छुटकारा पा सकता हूँ, यहाँ अपना कोड काफी कस सकता हूँ,और बस कह सकता हूँ printf percent c का उपयोग करके, उस वही अक्षर का two upper संस्करण।और फ़ंक्शन खुद को एहसास होने दो यदि यह अपरकेस है, इसे अपरिवर्तित पास थ्रू करो।यदि यह लोअरकेस है, पहले बदलो और फिर लौटाओ।तो अब यदि मैं अपनी टर्मिनल विंडो फिर से खोलूँ और इसे साफ करूँ, make uppercase डॉट स्लैश uppercase एंटर david।और हम वापस बिजनेस में हैं।तो फिर से, यह प्रदर्शित करता है कि यदि तुम पाते हो कि कोडिंग थकाऊ होती जा रही हैया तुम एक समस्या हल कर रहे हो जो निश्चित रूप से किसी और ने हल की है, संभावना है कि वास्तव में इसके लिए एक लाइब्रेरी फ़ंक्शन है,चाहे CS50 से हो या स्टैंडर्ड लाइब्रेरी से जिसे तुम खुद उपयोग कर सकते हो।और CS50 लाइब्रेरी के विपरीत, जो वास्तव में CS50 विशिष्ट है,यही वजह है कि Clang को dash L CS50 के बारे में जानने की जरूरत थी, इनमें से कई लाइब्रेरियाँ बस स्वचालित रूप से काम करती हैं।तुम्हें C type लाइब्रेरी लिंक इन करने की जरूरत नहीं है।तुम्हें अन्य लाइब्रेरियाँ लिंक इन करने की जरूरत नहीं है।लेकिन नॉन-स्टैंडर्ड लाइब्रेरियाँ जैसे CS50 के ट्रेनिंग व्हील्स पहले कुछ हफ्तों के लिए, हमें वह करना पड़ता है।लेकिन make वह सब तुम्हारे लिए स्वचालित रूप से करने के लिए कॉन्फ़िगर है।
ठीक।
हमारे अंतिम मिनटों में एक साथ, आइए अब आगे बढ़ें और main के बारे में कुछ विवरण प्रकट करें जिन्हें हम कालीन के नीचे झाड़ रहे थे।
मैंने सप्ताह एक पर कहा कि तुम बस विश्वास पर लो कि तुम्हें void करना होगा।
तुम्हें int करना होगा।
तुम्हें void और वह सब करना होगा।
खैर, आइए देखें कि वह वास्तव में क्यों है।
तो main विशेष है।
जहाँ तक C में, यह वह फ़ंक्शन है जो स्वचालित रूप से कॉल होगा जब तुमने कंपाइल किया और फिर अपना कोड रन किया,
बस क्योंकि सभी भाषाएँ फ़ंक्शन के नाम को स्टैंडर्डाइज़ नहीं करतीं, लेकिन C और C++ और Java और कुछ अन्य इस मामले में करती हैं।
यहाँ main का सबसे कैनोनिकल, सरल रूप है।
हम जानते हैं कि standard io.h शामिल करना बस हमें printf जैसे फ़ंक्शन्स के प्रोटोटाइप की पहुँच देता है।
लेकिन int के साथ क्या चल रहा है और void के साथ क्या चल रहा है?
खैर, यहाँ पेरेंटहेसिस में void का बस मतलब है कि main, और बदले में, सभी प्रोग्राम जो हमने इस क्षण तक लिखे हैं, कमांड लाइन आर्गुमेंट्स नहीं लेते।
शाब्दिक रूप से हर प्रोग्राम जो हमने लिखा, डॉट स्लैश a डॉट out, डॉट स्लैश hello, डॉट स्लैश scores, डॉट स्लैश बाकी सब,
मैंने कभी एक बार भी हमारे प्रोग्राम के नाम के बाद एक और शब्द टाइप नहीं किया जो हमने क्लास में लिखे।
वह इसलिए क्योंकि हर प्रोग्राम में इन पेरेंटहेसिस के अंदर void है जो कंप्यूटर को बताता है कि यह प्रोग्राम कमांड लाइन आर्गुमेंट्स नहीं लेता,
प्रोग्राम के नाम के बाद शब्द।
वह make और code और CD और अन्य कमांड्स से अलग है जो तुमने उनके नामों के बाद शब्दों के साथ प्रॉम्प्ट पर टाइप किए।
लेकिन पता चलता है कि C में main फ़ंक्शन के लिए अन्य समर्थित सिंटैक्स भी इस तरह दिख सकता है,
जो एक नज़र में तरह का मुँह भरा लगता है, लेकिन इसका बस मतलब है कि main शून्य आर्गुमेंट्स ले सकता है या यह दो ले सकता है।
यदि यह दो लेता है, पहला एक integer है और दूसरा स्ट्रिंग्स का एक array है।
कन्वेंशन द्वारा, वे इनपुट्स argc और argv कहलाते हैं।
Argc प्रोग्राम के नाम के बाद टाइप किए गए आर्गुमेंट्स की गिनती है।
Argv आर्गुमेंट वेक्टर है, उर्फ वास्तविक शब्दों का array।
दूसरे शब्दों में, अब जब हमारे पास arrays उपयोग करने की क्षमता है,
हम उपयोगकर्ताओं से प्रॉम्प्ट पर शून्य या एक या दो या तीन या अधिक शब्द प्राप्त कर सकते हैं जब वे हमारे खुद के प्रोग्राम रन करते हैं।
तो मेरा इससे क्या मतलब है?
हम अब प्रोग्राम लिख सकते हैं जिनमें वास्तव में कमांड लाइन आर्गुमेंट्स हों इस प्रकार।
मुझे यहाँ VS Code में जाने दो और अपना पुराना प्रोग्राम uppercase बंद करो।
आइए अपने टर्मिनल में यहाँ एक नया सरल प्रोग्राम लिखें जिसे greet.c कहा जाता है और उपयोगकर्ता का कुछ अलग तरीकों से अभिवादन करें।
तो मैं शुरू में cs50.h शामिल करने जा रहा हूँ और फिर मैं यहाँ standard io.h शामिल करने जा रहा हूँ।
फिर मैं int main void कहने जा रहा हूँ बिना अभी कुछ नया पेश किए।
मैं उपयोगकर्ता से पूछने जा रहा हूँ जैसे हमने पिछले सप्ताह get string से रिटर्न वैल्यू के लिए,
उनसे what’s your name पूछते हुए जैसा हमने कई बार किया।फिर मैं printf hello comma percent s backslash n कहने जा रहा हूँ उनका जवाब इस प्रकार थूकते हुए।पिछले सप्ताह जैसा ही प्रोग्राम फिर से।मैं make greet करने जा रहा हूँ।मैं डॉट स्लैश greet कहने जा रहा हूँ और अब मुझे अपने नाम के लिए प्रॉम्प्ट किया जाता है।मैं एंटर दबाता हूँ।ध्यान दो कि मैंने कोई कमांड लाइन आर्गुमेंट्स नहीं लिए।एकमात्र कमांड जो मैंने रन किया वह डॉट स्लैश greet था कोई अन्य शब्द नहीं।आइए अब इस नई ट्रिक का उपयोग करें और वास्तव में उपयोगकर्ता को अपना नाम टाइप करने दें जब वे मेरा प्रोग्राम रन कर रहे हों बजाय कि get string उपयोग करके और उन्हें प्रॉम्प्ट करके उनका समय बर्बाद करें।मुझे अपने एडिटर में जाने दो।आइए cs50 लाइब्रेरी से छुटकारा पाएँ।आइए get string के अपने उपयोग से छुटकारा पाएँ और बस void को int argc then string argv open print open bracket close bracket में बदलें।बस इतना ही यहाँ नीचे।आइए बस argv bracket one प्रिंट करें कारणों के लिए जो हम जल्द ही देखेंगे जो मैं वास्तव में कर रहा हूँ वह main के प्रोटोटाइप को पहले संस्करण से बदलना है,जिसे हम जैसे एक सप्ताह और थोड़ा अब उपयोग कर रहे हैं दूसरे संस्करण में, जो एकमात्र अन्य समर्थित संस्करण है।मैं अब अपनी टर्मिनल विंडो पर वापस जाने जा रहा हूँ।Make greet और धत्, मैं इतना करीब नहीं होना चाहिए।मैंने क्यों बनाया?मैंने गलती से जो गलती की उसे कैसे ठीक करूँ?हाँ, पीछे।ओह, नहीं, आगे।हाँ, मुझे cs50 लाइब्रेरी रखनी चाहिए थी क्योंकि cs50 लाइब्रेरी में string डिफाइंड है।तो include cs50.h सप्ताह चार में, हम वास्तव में उस लाइन को हटा देंगे और वास्तव में तुम्हें दिखाएँगे कि string वास्तव में क्या है।मैंने क्लास की शुरुआत में वादा किया कि string कला का शब्द है, लेकिन यह C में कीवर्ड नहीं है।लेकिन हम कुछ हफ्तों में देखेंगे कि इसका क्या मतलब है।ठीक, मुझे यह ठीक करने दो।Make greet डॉट स्लैश greet।लेकिन अब मैं एंटर दबाने से पहले अपना वास्तविक नाम टाइप करने जा रहा हूँ।और जब मैं अब एंटर दबाता हूँ, मैं hello comma David देखता हूँ।यदि मैं इसके बजाय डॉट स्लैश greet kelly, एंटर करूँ।अब मैं hello comma kelly देखता हूँ।यदि मैं कुछ नहीं करूँ जैसे greet, एंटर, मैं बस hello null देखता हूँ, जो पहले वाला null नहीं है, nul।यह nul है कारणों के लिए जिन पर हम जल्द ही वापस आएंगे।लेकिन स्पष्ट रूप से printf जानता है कि कुछ चल रहा है।वहाँ कोई वास्तविक शब्द नहीं है।क्यों, हालाँकि, मैंने argv bracket one किया?खैर, पता चलता है कि बस C की एक विशेषता के रूप में, यदि मैं इस प्रोग्राम को फिर से कंपाइल करूँ और डॉट स्लैश greet करूँ,और और कुछ न टाइप करूँ, मैं कुछ तरह का उत्सुक देखने जा रहा हूँ, hello डॉट स्लैश greet।क्योंकि स्वचालित रूप से, argv वेरिएबल में शून्य लोकेशनस्वचालित रूप से प्रोग्राम का खुद का नाम रखेगा।यह क्यों उपयोगी है?यदि तुम कभी कुछ सेल्फ-रेफरेंशियल करना चाहो, जैसे मेरे प्रोग्राम को रन करने के लिए धन्यवाद,या तुम अपने प्रोग्राम के नाम में अपने प्रोग्राम के लिए डॉक्यूमेंटेशन दिखाना चाहो,कि यह इस पर निर्भर करता है कि फाइल खुद क्या कहलाती है,तुम argv bracket zero उपयोग कर सकते हो, जो हमेशा प्रोग्राम का नाम रखेगा,चाहे फाइल का नाम जो भी हो या फिर से नाम दिया गया हो।लेकिन हम उस null मुद्दे को अब कुछ तरीकों से ठीक कर सकते हैं।तो argc दूसरा इनपुट है जो मैंने कहा अब मौजूद हो सकता है, जो प्रॉम्प्ट पर आर्गुमेंट्स की गिनती है।तो यदि मैं चेक करना चाहता हूँ कि उपयोगकर्ता ने वास्तव में अपना नाम टाइप किया,मैं कुछ कह सकता हूँ जैसे, यदि argc equals equals two, खैर, तब, और केवल तब,आगे बढ़ो और उनका नाम प्रिंट करो।Else, आइए बस कुछ चतुर डिफ़ॉल्ट करें, जैसे printf, quote unquote, hello world, या हेक, बिल्कुल कुछ नहीं।प्रोग्राम का यह संस्करण अब थोड़ा स्मार्ट है,क्योंकि जब मैं make greet रन करता हूँ और डॉट स्लैश greet of my name करता हूँ, ठीक इरादे के अनुसार काम करता है।लेकिन यदि मैं भूल जाता हूँ और सिर्फ डॉट स्लैश greet करता हूँ, यह hello world कहने जा रहा है।इसके अलावा, यदि मैं पूरी तरह सहयोग नहीं करता और मैं कहता हूँ, David Maylan, एंटर,यह इसी तरह मुझे अनदेखा कर देता है क्योंकि arg count अब दो नहीं है।यह अब तीन है।तो argc प्रॉम्प्ट पर शब्दों की कुल संख्या रखता है,लेकिन पहला हमेशा प्रोग्राम का नाम है।प्रश्न?सॉरी, क्या तुम वह एक बार थोड़ा जोर से कह सकते हो?यह जानकारी क्यों है जो हमारे पास बस है, या?ओह, तो संक्षिप्त जवाब बस क्योंकि है।जैसे C की परिभाषा, यदि तुम C के डॉक्यूमेंटेशन को देखो,तुम या तो main को void शब्द के साथ कोई आर्गुमेंट न लेने के रूप में डिफाइन कर सकते हो,या तुम निर्दिष्ट कर सकते हो कि main दो आर्गुमेंट्स ले सकता है।और कंपाइलर और ऑपरेटिंग सिस्टम बस सुनिश्चित करेंगे कि यदि तुम दो प्रदान करते हो,वे दो वेरिएबल्स, argc और argv, उन दो वैल्यूज से स्वचालित रूप से भर जाएँगे।किसी और ने वह फैसला किया, हालाँकि।यही तरीका है।तुम वहाँ तीन नहीं डाल सकते।तुम वहाँ चार नहीं डाल सकते।तुम उन वेरिएबल्स के नाम बदल सकते हो, लेकिन टाइप्स नहीं।इस कन्वेंशन के कारण।तो main की एक अंतिम विशेषता है, फिर।यह वास्तविक वैल्यू है जो लौटाती है।अब तक, हर प्रोग्राम जो मैंने लिखा int main something से शुरू होता है।Int main something।वह int क्या है?हमने अभी तक इसका उपयोग नहीं किया।तकनीकी रूप से, वैल्यू जो main लौटाती है उसे तथाकथित exit status कहा जाएगा,जो एक न्यूमेरिक स्टेटस है जो सफलता या विफलता दर्शाता है।कंप्यूटिंग की दुनिया में संख्याएँ हर जगह हैं।तो उदाहरण के लिए, यहाँ Zoom से एक स्क्रीनशॉट है जहाँ यदि Zoom के साथ कुछ गलत होता है,जैसे तुम्हारे पास खराब इंटरनेट कनेक्टिविटी या कुछ ऐसा है,तुम 1132 जैसे एरर कोड देख सकते हो।उसका सामान्य लोगों के लिए कोई मतलब नहीं है जब तक कि तुम इसे गूगल न करो, डॉक्यूमेंटेशन देखो।लेकिन इसका उन सॉफ्टवेयर इंजीनियरों के लिए बहुत मतलब है जिन्होंने यह कोड लिखाक्योंकि वे जानते हैं, ओह शूट, 1132 का मतलब यह एरर है।और उनके पास शायद एक स्प्रेडशीट या चीट शीटकहीं है जो उन कोड्स को वास्तव में उपयोगी एरर मैसेजेस में बदलती है।और ईमानदारी से, एक बेहतर दुनिया में, वे तुम्हें बस बताएँगे कि समस्या क्या हैबजाय कि बस समस्या रिपोर्ट करो और इस संख्या का उल्लेख करो।उसने कहा, वेब पर, संभावना है कि तुम इस संख्या, 404 से परिचित हो,जो इतने सारे सामान्य लोगों के जानने के लिए भी एक अजीब चीज़ है।लेकिन यह सामान्यतः मतलब file not found।यह एक न्यूमेरिक कोड है जो दर्शाता है कि कुछ गलत हो गया है।Exit status बिल्कुल यह नहीं है, लेकिन आत्मा में समान है।Main में, तुम 0 या 1 या 2 या कुछ और जैसी वैल्यू लौटा सकते होयह दर्शाने के लिए कि कुछ सफल था या नहीं।कन्वेंशन द्वारा, main जैसा फ़ंक्शन सफलता पर 0 लौटाता है, यदि सब ठीक है।और वह तुम्हें फिर कई सौ संभावित चीज़ें छोड़ता है जो गलत हो सकती हैंक्योंकि तुम एक चीज़ दर्शाने के लिए एक लौटा सकते हो, दो दूसरी लौटाने के लिए,तीन एक और दर्शाने के लिए।और जब तक तुम्हारे पास एक स्प्रेडशीट या चीट शीट या कुछ है,तुम बस प्रोग्रामर के रूप में ट्रैक रख सकते हो कि कौन सा एरर क्या मतलब रखता है।तो वास्तविक शब्दों में इसका क्या मतलब है?खैर, यदि मैं यहाँ VS Code पर जाऊँ, मुझे एक अपेक्षाकृत सरल प्रोग्राम इम्प्लीमेंट करने दो,हमारा अंतिम, जिसे status.c कहा जाता है।तो status.c में, मैं शीर्ष पर CS50 लाइब्रेरी उपयोग करने जा रहा हूँ,शीर्ष पर standard IO लाइब्रेरी।और फिर int main के अंदर और हमारे नए फॉर्मेट int argc string argvस्क्वायर ब्रैकेट्स के साथ main के अंदर, मैं अब निम्नलिखित करने जा रहा हूँ।यदि argc 2 के बराबर नहीं है, तो मैं आगे बढ़कर इस बार एक चेतावनी प्रिंट करने जा रहा हूँ।मेरे पास hello world जैसा कोई बेवकूफी भरा डिफ़ॉल्ट नहीं होगा।आइए उपयोगकर्ता को बताएँ कि उन्होंने मेरे प्रोग्राम का सही उपयोग नहीं किया।और मैं कहूँगा printf missing command line argument।और हम मान लेंगे कि वे जानते हैं इसका क्या मतलब है।फिर एक एरर दर्शाने के लिए, मैं return 1 कहूँगा।यह 2 हो सकता है।यह 3 हो सकता है।लेकिन यह पहला संभावित एरर है, तो मैं 1 के साथ सरल शुरू करने जा रहा हूँ।अन्यथा, यदि argc 2 के बराबर है और मैं अपने कोड के इस हिस्से तक पहुँचता हूँ,मैं hello comma percent s backslash n कहूँगा और argv bracket 1 पास करूँगाठीक पहले की तरह।और सुपर विशिष्ट होने के लिए, मैं return 0 कहूँगा कंप्यूटर को बताने के लिए,ऑपरेटिंग सिस्टम को, कि यह सफलता है।0 सफलता दर्शाता है।कोई अन्य वैल्यू एरर दर्शाती है।आइए अब make status करें।आइए डॉट स्लैश status करें।और यह थोड़ा जादुई है।लेकिन मुझे शुरू में सहयोग करने दो।मैं अपना नाम David टाइप करने जा रहा हूँ।और मैं hello comma David देखने जा रहा हूँ।अधिकांश लोग यह नहीं जानते, लेकिन तुम्हारे टर्मिनल पर टाइप किए जा सकने वाले कमांड्स मेंयह एक यहाँ है।और TFs और मैं, TAs और मैं कुछ ऐसा करेंगे।हम, तुम्हारा कोड रन करने के बाद, echo, स्पेस, डॉलर साइन, प्रश्न चिह्न कर सकते हैं।और हम गुप्त रूप से देख सकते हैं कि तुम्हारे प्रोग्राम ने कौन सी रिटर्न वैल्यू लौटाई, इस मामले में 0।इस बीच, यदि हम यह फिर से करें, डॉट स्लैश status और मुझे इस बार अपना नाम न टाइप करने दो।जब मैं यह करता हूँ, मैं missing command line argument देखता हूँ।कोड ने तब कौन सी वैल्यू लौटाई होनी चाहिए?1।तो आइए देखें।Echo, डॉलर साइन, प्रश्न चिह्न।वहाँ 1 है।तो भले ही CS50 के सिर्फ एक सप्ताह के बाद, यदि तुमने कभी सोचा कि check50कैसे जानता है कि तुम्हारा कोड सही था या नहीं, उन तरीकों में से जिनसे हम उसके लिए चेक करते हैंइस सेमी-सीक्रेट स्टेटस कोड, इस exit status को चेक करके है, जो वास्तव में सीक्रेट नहीं है।यह बस सामान्य लोगों को डिस्प्ले नहीं किया जाता क्योंकि यह उतना ज्ञानवर्धक नहीं हैजब तक कि तुम सॉफ्टवेयर डेवलपर न हो जिसने प्रश्न में कोड लिखा।लेकिन इसका मतलब है कि हम कुछ मामलों में 1 लौटा सकते हैं या अन्य मामलों में 2या फिर भी अन्य में 3 या 4।और ये कमांड लाइन आर्गुमेंट्स तरह से हर जगह हैं।और वास्तव में, एक प्रोग्राम जिसे मैंने एक पल पहले छोड़ दिया वह यह होने जा रहा था।जो तुम देखने वाले हो उसका कोई अकादमिक मूल्य नहीं है।लेकिन एक और प्रोग्राम जो कमांड लाइन आर्गुमेंट्स लेता है वह COSE के रूप में जाना जाता है।और यह कंप्यूटिंग सर्कल्स में तरह का बहुत प्रसिद्ध हैक्योंकि यह कई सालों से सिस्टम पर रहा है।COSE एक प्रोग्राम है जो तुम्हें प्रॉम्प्ट के बाद एक शब्द टाइप करने देता है जैसे moo।और यह ASCII आर्ट प्रिंट करेगा।एक प्यारा छोटा गाय स्पीच बबल के साथ जो moo कहती है।तो तरह का scratch की याद दिलाने वाला।लेकिन यह अन्य कमांड लाइन आर्गुमेंट्स लेता है, सिर्फ शब्द नहींजो तुम इसके मुँह से निकलवाना चाहते हो, बल्कि उपस्थिति भी जो तुम इसे रखना चाहते हो।तो उदाहरण के लिए, मैं dash f duck कह सकता हूँ और इसे फिर से रन कर सकता हूँ, एंटर।और अब मेरे पास एक छोटा प्यारा डक है जो moo कह रहा है, जो थोड़ा बग है।तो मुझे उसे quack में बदलने दो, उदाहरण के लिए, इसके बजाय।फिर से, यहाँ कोई अकादमिक मूल्य नहीं है।यह बस मज़ेदार है अब विभिन्न विकल्पों के साथ खेलना।लेकिन यदि हम वास्तव में इसके साथ मज़ा करना चाहते हैं, हम एक और कर सकते हैं।तो COSE dash f dragon।और हम कुछ कह सकते हैं जैसे roar।और अब हमारे पास यह पागल ड्रैगन स्क्रीन पर दिखाई दे रहा है, जो कहना है, फिर से, यहाँ कोई मूल्य नहीं।यह बस कमांड लाइन आर्गुमेंट्स के साथ कभी-कभी खेलना मज़ेदार है।और COSE यह कैसे कर रहा है?खैर, किसी ने कोड लिखा शायद C में या किसी अन्य भाषा में argc और argv का उपयोग करकेऔर उनकी वैल्यूज पर घुसपैठ करके और शायद एक कंडीशनल जो कहता है यदि dash f वैल्यू dragon है,तो यह ग्राफिक प्रिंट करो।Else if वैल्यू duck है, तो यह दूसरा प्रिंट करो।यह सब सप्ताह 0 के फ़ंक्शन्सऔर कंडीशनल्स और लूप्स और बूलियन एक्सप्रेशन्स और जैसे के मौलिक बातों तक सिमट जाता है।यह बस अधिक से अधिक दिलचस्प चीज़ों में कंपोज़ किया जा रहा है।और वास्तव में, समापन में, अन्य दिलचस्प चीज़ों में जिन्हें हम इस सप्ताह खेलेंगेपूर्ण सर्कल आने के लिए वह क्रिप्टोग्राफी की है, जानकारी को स्क्रैम्बल करने की कलाताकि सुरक्षित संचार हो।आजकल पासवर्ड्स और क्रेडिट कार्डनंबर्स और व्यक्तिगत मैसेजेस के साथ इतना महत्वपूर्ण जिन्हें तुम भेजना चाह सकते हो।और हम तुम्हें कोड के माध्यम से कुछ एल्गोरिदम्स एक्सप्लोर करवाएँगे जिनके माध्यम से तुम खुदजानकारी एन्क्रिप्ट कर सकते हो।और इस रूप के एन्क्रिप्शन के करने के कई तरीके हैं।और वे सब इस मानसिक मॉडल तक सिमट जाते हैं।तुम्हारे पास कुछ इनपुट है जैसे संदेश जो तुम भेजना चाहते हो।और तुम इसे किसी तरह एन्साइफर करना चाहते हो, किसी तरह एन्क्रिप्ट करना चाहते होताकि कोई न जाने कि तुमने क्या संदेश भेजा है।तो तुम अपना प्लेन टेक्स्ट चाहते हो, जो अंग्रेजीया किसी अन्य भाषा में मानव पठनीय संस्करण है, अंततः साइफर टेक्स्ट बनना।तो कोड जो तुम इस सप्ताह लिखने वाले हो इस ब्लैक बॉक्स के अंदर किसी तरह का साइफर हैएक एल्गोरिदम जो जानकारी एन्क्रिप्ट करता है ताकि तुम ठीक यह कर सको।अब पकड़ यह है कि तुम बस इसे प्लेन टेक्स्ट नहीं दे सकतेऔर इसे एक एल्गोरिदम से गुज़ारो और साइफर टेक्स्ट प्राप्त करोक्योंकि तुम्हें आमतौर पर एन्क्रिप्शन काम करने के लिए किसी तरह एक सीक्रेट की जरूरत होती है।जैसे यदि मैं पीछे किसी को संदेश भेजने जा रहा हूँ,खैर, मैं बस उन अक्षरों को रैंडमाइज़ कर सकता हूँ जो मैं लिख रहा हूँ।लेकिन वे कैसे जानेंगे कि उस प्रक्रिया को कैसे उल्टा करना है?शायद हमें पहले से सहमत होना होगा कि, तुम जानते हो क्या?मैं हर A को B में बदलने जा रहा हूँ और हर B को C में और C को D मेंऔर Z को A में। मैं अल्फाबेट के अंत में वापस रैप करूँगा।यह बहुत परिष्कृत नहीं है, लेकिन कौन जानता है, मिडिल स्कूल टीचर,यदि वे क्लास में नोट्स पास करते दो बच्चों को इंटरसेप्ट करते हैं,इस साइफर को पता लगाने में समय बर्बाद करेंगे।लेकिन यह इस बात को पूर्वकल्पित करता है कि उनके बीच एक सीक्रेट है, उस मामले में संख्या एक,क्योंकि मैं हर अक्षर को एक जगह बदल रहा हूँ।तो यह कैसे काम कर सकता है?खैर, यदि मैं शब्द high, hi, विस्मयादिबोधक चिह्न को एन्क्रिप्ट करना चाहता हूँ,और मेरी सीक्रेट की किसी के साथ जो मैंने पहले से सोची है वह एक है,मुझे साइफर टेक्स्ट ij विस्मयादिबोधक चिह्न भेजना चाहिए।अब, यह एक सरल साइफर है, तो मैं वास्तव में पंचुएशन को एन्क्रिप्ट नहीं कर रहा,जो अच्छी बात हो भी सकती है और नहीं भी।लेकिन मैं कम से कम अल्फाबेटिकल अक्षरों को एन्क्रिप्ट कर रहा हूँ।लेकिन प्राप्तकर्ता को फिर इस संदेश को डिक्रिप्ट करने के लिए क्या करना होगा?जब वे कागज पर ij विस्मयादिबोधक चिह्न देखते हैं, वे कैसे जानें कि मैंने क्या कहा?खैर, वे उसी की का उपयोग करते हैं, लेकिन घटाते हैं।तो B A बन जाता है, C B बन जाता है, A Z बन जाता है, और इसी तरह,अनिवार्य रूप से की को पॉजिटिव एक से नेगेटिव एक में उल्टा करना।बेशक, एक की के साइफर से थोड़ा अधिक सुरक्षित, एक की होगा 13।और वास्तव में, कंप्यूटिंग सर्कल्स में, 13 का विशेष महत्व है।ROT 13, R-O-T 13 एक एल्गोरिदम है जिसका कई सालों से ऑनलाइन उपयोग किया जाता रहा है।बस स्पॉइलर्स से बचने के लिए, जैसे Reddit यह कर सकता है या अन्य वेबसाइट्सजहाँ वे चाहते हैं कि तुम्हें संदेश क्या कहता है देखने के लिए कुछ प्रयास करना पड़े।लेकिन यह उतना कठिन नहीं है।तुम्हें बस एक बटन क्लिक करना होगा या कोड लिखना होगा जो वास्तव में यह करता है।लेकिन यदि तुम 13 उपयोग करते हो, तुम्हें ij नहीं मिलेगा, तुम्हें uv मिलेगा।क्योंकि u और v क्रमशः h और i से 13 जगह दूर हैं।लेकिन फिर से, हम पंचुएशन को नहीं छू रहे।या हम कुछ अधिक व्यक्तिगत भेज सकते हैं, जैसे I love you,और संदेश उस तरह निकलता है।उससे थोड़ा अधिक सुरक्षित होगा ROT 26, नहीं?नहीं।क्यों?क्योंकि यह वही चीज़ है।यह शाब्दिक रूप से पूरे रास्ते घूमता है।A A बन जाता है, B B बन जाता है। तो इसकी एक सीमा है।लेकिन अधिक गंभीरता से, वह बताता है कि यह एन्क्रिप्शन कितना मजबूत है या नहीं।क्योंकि यदि तुम अब इसके बारे में एक विरोधी के दृष्टिकोण से सोचो,जैसे कमरे में टीचर पेपर की स्लिप इंटरसेप्ट करते हुए,उन्हें कितना काम करने की जरूरत है?खैर, वे बस सभी संभावनाएँ आज़माते हैं।की ऑफ वन, की ऑफ टू, की ऑफ थ्री, डॉट, डॉट, डॉट, की ऑफ 25।और किसी बिंदु पर, वे स्पष्ट रूप से देखेंगे कि उन्होंने की का अनुमान लगाया, जिसकामतलब है कि साइफर बहुत सुरक्षित नहीं है।फिर भी, जिसके बारे में हम बात कर रहे हैं वह ऐतिहासिक रूप से सीज़र साइफर के रूप में जाना जाता है।क्योंकि पुराने दिनों में, जब सीज़र किंवदंतियों द्वारा अपने जनरल्स के साथ संचार कर रहा था,यदि तुम पृथ्वी पर पहले इंसान हो एन्क्रिप्शन के साथ आने वाले या इस विशिष्ट साइफर के साथ आने वाले,इससे वास्तव में कोई फर्क नहीं पड़ता कि यह कितना जटिल नहीं हैयदि कोई और नहीं जानता कि क्या चल रहा है।आजकल, कुछ C कोड या किसी अन्य भाषा को लिखना बिल्कुल कठिन नहीं है जोबस ब्रूट फोर्स से इसके माध्यम से जा सके।तो आजकल बहुत अधिक परिष्कृत एल्गोरिदम्स हैं बजाय अल्फाबेट के अक्षरों के सरल रोटेशन्स केजैसा हम जल्द ही देखेंगे।लेकिन डिक्रिप्शन की बात आने पर, यह वास्तव में बस उस प्रक्रिया को उल्टा करने की बात है।तो यह संदेश यहाँ, यदि हम सभी अक्षरों को विपरीत दिशा में घुमाएँएक घटाकर, आज के लिए हमारा अंतिम फूलिश होगा।वहाँ थोड़ा संकेत है, जो प्रकट करेगा कि यह संदेशऔर हमारे लिए अंतिम शब्द जैसे ही घड़ी 4.15 बजेगी वह होगा u t बन जाता हैऔर i h बन जाता है।मैं अकेला हूँ जिसे यह मनोरंजक लग रहा है।h i s w a s c s 50।और यह CS50 था।हम अगली बार मिलेंगे।हम अगली बार मिलेंगे।
अविकल अनुवाद पूरा हुआ।
