[Powered by Google Translate] [धारा 5 और अधिक आरामदायक]
[रोब Bowden - हार्वर्ड विश्वविद्यालय]
[यह CS50 है. - CS50.TV]
>> मुझे लगता है कि मैं अपने ईमेल में कहा, वहाँ बातें आप उपयोग कर सकते हैं की एक बहुत कुछ कर रहे हैं
वास्तव में समस्या सेट कर उपकरण के अलावा अन्य.
हम सुझाव है कि आप यह उपकरण में करते हैं तो सिर्फ इसलिए कि हम और अधिक आसानी से आप मदद कर सकते हैं
और हम जानते हैं कि कैसे सब कुछ करने के लिए काम चल रहा है.
लेकिन जहाँ आप बातें करते हैं यदि हां, तो कह सकते हैं की एक उदाहरण के रूप में, आप पहुँच नहीं है
एक उपकरण या आप विज्ञान केंद्र के तहखाने में काम करना चाहते हैं -
जो वास्तव में वे उपकरण भी है -
अगर आप कहीं भी काम करना चाहते हैं.
एक उदाहरण देखा है / SSH के बारे में सुना है?
SSH कुछ करने के लिए कनेक्ट की तरह सिर्फ मूल रूप से है.
दरअसल, अभी मैं उपकरण में SSHed रहा हूँ.
उपकरण में मैं सीधे काम कभी नहीं.
यहाँ उपकरण है, और अगर तुम यहाँ नीचे देखो, तुम इस आईपी पते को देखने.
उपकरण ही में मैं काम कभी नहीं;
मैं हमेशा एक iTerm2 खिड़की खिड़की / टर्मिनल पर आते हैं.
आप कर सकते हैं कि आईपी पते, jharvard@192.168.129.128 ssh SSH.
मुझे लगता है कि संख्या बहुत आसानी से याद है क्योंकि यह एक अच्छा तरीका है.
लेकिन यह है कि मुझे मेरा पासवर्ड के लिए पूछना है, और अब मैं उपकरण में हूँ.
असल में, इस बिंदु पर, यदि आप उपकरण खुद के अंदर एक टर्मिनल खोला,
इस इंटरफ़ेस है, लेकिन आप यह प्रयोग करेंगे, बिल्कुल वैसी ही है
इंटरफ़ेस के रूप में मैं का उपयोग कर रहा हूँ, लेकिन यहाँ अब आप SSHed रहे हैं.
आप उपकरण को SSH के लिए नहीं है.
एक अन्य जगह तुम सकता SSH का एक उदाहरण है कि मुझे यकीन है कि आप डिफ़ॉल्ट रूप से कर रहा हूँ -
ओह. बड़ा.
तुम सब FAS सर्वर पर मूलभूत FAS खातों के द्वारा होना चाहिए.
मेरे लिए, मैं SSH rbowden@nice.fas.harvard.edu के लिए.
यह आपको लगता है कि पहली बार पूछने के लिए जा रहा है, और आप हाँ कहते हैं.
मेरा पासवर्ड सिर्फ मेरे FAS कूटशब्द होने जा रहा है.
और तो अब, मैं अच्छा सर्वरों के लिए SSHed रहा हूँ, और मैं कुछ भी मैं यहाँ पर चाहते हैं कर सकते हैं.
वर्गों तुम ले सकता है, 124 की तरह का एक बहुत कुछ है, तुम यहाँ के लिए सामान अपलोड करने के लिए जा रहे हैं
वास्तव में अपनी समस्या सेट प्रस्तुत.
लेकिन कहते हैं कि तुम अपने उपकरण के लिए पहुँच नहीं है.
तो फिर तुम बातें करते हैं, यहाँ पर की तरह कहेंगे कर सकते हैं -
यह सिर्फ हमारे सवालों का अनुभाग है.
यह पूछने के लिए उपकरण में यह करना होगा.
इसके बजाय मैं सिर्फ यह सर्वर पर करूँगा.
मुझे लगता है कि खोलना करने के लिए जा रहा हूँ.
समस्या हो सकता है कि आप जीएडिट की तरह कुछ का उपयोग करने के लिए इस्तेमाल कर रहे हैं के लिए जा रहा है
या उपकरण के अंदर जो भी हो.
आप के लिए कि FAS सर्वर पर नहीं जा रहे हैं.
यह सब सिर्फ इस शाब्दिक इंटरफेस हो जा रहा है.
तो आप या तो एक, एक पाठ संपादक है कि वे है जानने के लिए कोशिश कर सकते हो.
वे नैनो है.
नैनो आम तौर पर उपयोग करने के लिए बहुत आसान है.
आप अपने तीर का उपयोग कर सकते हैं और सामान्य रूप से टाइप कर सकते हैं.
तो यह है कि मुश्किल नहीं है.
यदि आप सच में फैंसी प्राप्त करना चाहते हैं आप Emacs का उपयोग कर सकते हैं,
जो मैं शायद इसलिए क्योंकि मैं भी कैसे Emacs बंद करने के लिए नहीं पता नहीं है है नहीं खोला जाना चाहिए.
नियंत्रण एक्स, नियंत्रण सी? हाँ.
या आप विम का उपयोग कर सकते हैं, जो मैं क्या उपयोग है.
और इसलिए वे अपने विकल्प हैं.
यदि आप ऐसा नहीं करना चाहते हैं, तो आप भी कर सकते हैं, अगर आप को देखो manual.cs50.net -
ओह.
एक पीसी पर, आप ssh पोटीन का उपयोग कर सकते हैं,
जो आप करने के लिए अलग से डाउनलोड करने के लिए जा रहे हैं.
एक पर MAC, आप बस डिफ़ॉल्ट का उपयोग टर्मिनल या आप iTerm2 डाउनलोड कर सकते हैं कर सकते हैं,
जो एक अच्छा, फैंसी टर्मिनल की तरह है.
यदि आप manual.cs50.net जाना आप नोटपैड के लिए एक लिंक देखेंगे + +,
जो है क्या आप एक पीसी पर उपयोग कर सकते हैं.
यह आप SFTP Notepad से देता है + +, जो मूल रूप से SSH है.
यह आपको करना क्या है आपकी फ़ाइलों को स्थानीय रूप से संपादित करने के लिए,
और फिर जब भी आप उन्हें बचाने के लिए करना चाहते हैं, यह nice.fas के लिए बचाने के लिए होगा,
जहाँ आप तो उन्हें चलाने के लिए कर सकते हैं.
और एक मैक पर बराबर TextWrangler होने जा रहा है.
तो यह आपको एक ही बात करते हैं.
यह आपको फ़ाइलें स्थानीय रूप से संपादित करें और उन्हें nice.fas को बचाने,
जहाँ आप तो उन्हें चलाने के लिए कर सकते हैं.
तो अगर तुम कभी एक उपकरण के बिना फंस रहे हैं, आप इन विकल्पों
अपनी समस्या सेट अब भी है.
एक समस्या हो सकता है कि आप CS50 पुस्तकालय नहीं जा रहे हैं जा रहा है
क्योंकि nice.fas डिफ़ॉल्ट रूप से है कि नहीं है.
आप या तो CS50 पुस्तकालय डाउनलोड कर सकते हैं -
मुझे नहीं लगता कि मैं इस बिंदु पर है कि जरूरत है.
आप या तो CS50 पुस्तकालय डाउनलोड कर सकते हैं और यह nice.fas पर कॉपी,
या मुझे लगता है कि इस बिंदु पर हम इसे अब और नहीं का उपयोग करते हैं वैसे भी.
या अगर हम करते हैं, तो आप के साथ कुछ समय के लिए यह कर सकते हैं की जगह किया जा रहा है
CS50 पुस्तकालय में कार्यों का भी implementations.
तो यह है कि एक प्रतिबंध की है कि ज्यादा नहीं होना चाहिए.
और वह है कि.
>> मैं वापस करने के लिए उपकरण को अब जाना होगा, हम उपकरण में सब कुछ करूँगा.
प्रश्नों की अनुभाग में देख रहे हैं, शुरुआत में, जैसे मैं अपने ईमेल में कहा,
हम कम एक को आप देखना चाहिए थे के बारे में बात की है.
हम पुनः निर्देशित कर और पाइपों और इन तीनों सवालों है.
>> जो धारा की तरह कार्य करता printf डिफ़ॉल्ट रूप से लिखने के लिए?
धारा तो. एक धारा क्या है?
धारा मूल रूप से है जैसे कि यह सिर्फ कुछ -
यह भी नहीं 1s और 0s का एक स्रोत है.
स्ट्रीम में यह यहाँ के लिए पूछ रहा है, मानक बाहर है.
और मानक बाहर एक धारा है कि जब आप इसे लिखने के लिए,
यह स्क्रीन पर प्रकट होता है.
मानक बाहर, धारा, यह मतलब है कि आप सिर्फ यह करने के लिए 1s और 0s लिखने,
और मानक बाहर के दूसरे छोर सिर्फ उस धारा से पढ़ता है.
यह सिर्फ 1s और 0s के एक स्ट्रिंग है.
आप धाराओं लिखने के लिए या आप धाराओं से पढ़ सकते हैं
धारा वास्तव में क्या है पर निर्भर करता है.
अन्य दो डिफ़ॉल्ट धाराओं और मानक त्रुटि में मानक हैं.
में मानक है जब भी आप GetString, यह आप के लिए इनपुट सामान के लिए इंतजार कर रहा है.
तो यह आप के लिए इंतज़ार कर रही है, यह वास्तव में मानक पर इंतजार कर रहा है,
जो वास्तव में तुम्हें क्या मिलता है जब आप कीबोर्ड पर टाइप.
आप अंदर मानक में टाइप कर रहे हैं
मानक त्रुटि मूल रूप से मानक बाहर करने के लिए बराबर है,
लेकिन यह है कि में विशेष है जब आप मानक त्रुटि करने के लिए प्रिंट,
आप केवल कि त्रुटि संदेश मुद्रित करने के लिए चाहिए रहे हैं
तो आप नियमित रूप से स्क्रीन करने के लिए मुद्रित संदेश के बीच अंतर कर सकते हैं
बनाम त्रुटि संदेश चाहे वे मानक बाहर या मानक त्रुटि के लिए गया था पर निर्भर करता है.
भी फ़ाइलें.
मानक बाहर में मानक और मानक त्रुटि बस विशेष धाराओं,
लेकिन वास्तव में किसी भी फाइल, जब आप एक फ़ाइल खोलने, यह बाइट्स की एक धारा बन जाता है
आप बस, जहां कि धारा से पढ़ सकते हैं.
तुम्हें पता है, सबसे अधिक भाग के लिए, बस बाइट्स की एक धारा के रूप में एक फ़ाइल के बारे में सोच सकते हैं.
तो क्या धाराओं वे डिफ़ॉल्ट रूप से करने के लिए लिखने के लिए? मानक बाहर.
>> > और >> के बीच क्या अंतर है?
क्या किसी ने वीडियो पहले से देखते हो? ठीक है.
> कैसे आप फ़ाइलों में पुनर्निर्देशित जा रहा है,
और >> भी फाइलों में उत्पादन अनुप्रेषित करने के लिए जा रहा है,
लेकिन यह बजाय फ़ाइल को संलग्न करने के लिए जा रहा है.
उदाहरण के लिए, हम कहते हैं मैं dict यहीं है होता,
और dict के अंदर ही सामान बिल्ली, बिल्ली, कुत्ता, कुत्ते, मछली है.
एक आदेश है कि आप कमांड लाइन पर बिल्ली है,
जो सिर्फ करने के लिए प्रिंट क्या एक फाइल में जा रहा है.
तो जब मैं बिल्ली dict कहते हैं, यह बिल्ली, बिल्ली, कुत्ता, कुत्ते, मछली मुद्रित करने के लिए जा रहा है. यही कारण है कि सभी बिल्ली करता है.
इसका मतलब है कि यह बिल्ली, बिल्ली, कुत्ता, कुत्ते, मछली बाहर मानक के लिए मुद्रित.
अगर मैं बजाय एक फाइल करने के लिए पुनर्निर्देशित करना चाहते हैं कि, मैं> का उपयोग करें और यह जो भी फाइल है अनुप्रेषित कर सकते हैं.
मैं फ़ाइल को बुलाता हूँ.
तो अब अगर मैं रास, मैं देख रहा हूँ कि मैं एक नई फ़ाइल बुलाया फ़ाइल है.
और अगर मैं इसे खोलने के लिए, यह है कि क्या वास्तव में बिल्ली कमांड लाइन पर डाल दिया जा रहा है.
तो अब अगर मुझे लगता है कि फिर से करते हैं, तो यह फ़ाइल में उत्पादन अनुप्रेषित करने के लिए जा रहा है,
और मैं एक ही सटीक बात करने के लिए जा रहा हूँ.
तो तकनीकी तौर पर, यह पूरी तरह से overrode हम क्या था.
और हम अगर मैं dict परिवर्तन देखेंगे, मैं बाहर कुत्ते को ले लिया.
अब अगर हम बिल्ली फिर फ़ाइल में dict, हम कुत्ते हटा दिया साथ नए संस्करण के लिए जा रहे हैं.
तो यह पूरी तरह से ओवरराइड करता है.
इसके बजाय, अगर हम >> का उपयोग करें, यह फाइल परिशिष्ट के रूप में लगाना जा रहा है.
अब, फ़ाइल खोलने, हम देखते हैं कि हम सिर्फ एक ही बात दो बार मुद्रित
क्योंकि यह एक बार गया था, तो हम मूल करने के लिए संलग्न है.
तो है कि क्या> >> और करते हैं.
अगले एक से पूछते हैं - यह इस बारे में पूछ नहीं है.
>> अन्य एक है कि हम <, जो अगर> मानक बाहर रीडायरेक्ट है,
<मानक अनुप्रेषित अंदर जा रहा है
चलो देखते हैं अगर हम एक उदाहरण है.
मैं एक असली जल्दी लिख सकते हैं.
चलो किसी भी फाइल, hello.c ले.
अपेक्षाकृत सरल फ़ाइल.
मैं सिर्फ एक स्ट्रिंग हो रही है और फिर "नमस्ते" जो भी जांच स्ट्रिंग मैं बस में प्रवेश किया था मुद्रण.
तो हैलो और फिर / हैलो.
अब यह मेरे उत्साह कुछ दर्ज है,
जिसका मतलब है कि यह चीजों पर इंतजार कर रहा है अंदर मानक में दर्ज किया
तो दर्ज करें जो कुछ भी मैं मानक में चाहते हैं अंदर हम सिर्फ नमस्ते, रोब कहने जा रहे हैं!
तो यह हैलो बाहर मानक मुद्रण, रोब!
अगर मैं / नमस्ते और फिर अनुप्रेषित करते हैं,
अब के लिए आप केवल एक फ़ाइल से अनुप्रेषित कर सकते हैं.
तो अगर मैं कुछ फ़ाइल, txt में डाल दिया, और मैं रोब डाल दिया,
अगर मैं हैलो रूप से चलाने के लिए और बाद में फ़ाइल txt का समर्थन करता है अनुप्रेषित / हैलो, नमस्ते कहने, रोब जा रहा है! तुरंत.
जब वह पहली बार GetString करने के लिए हो जाता है और यह मानक पर में इंतजार कर रहा है,
में मानक नहीं रह गया है करने के लिए प्रवेश करने के लिए डेटा के लिए कीबोर्ड पर इंतज़ार कर रहे हैं.
इसके बजाय, हम मानक फ़ाइल txt का समर्थन करता है से पढ़ने में पुनः निर्देशित किया है.
और इसलिए यह फ़ाइल txt का समर्थन करता है, जो सिर्फ लाइन रोब से पढ़ने के लिए जा रहा है,
और फिर इसे नमस्कार रोब, प्रिंट जा रहा है!
और अगर मैं चाहता था, मैं भी कर / हैलो txt <सकता है
और फिर बाहर है कि यह मानक मुद्रण, जो रोब नमस्ते है!
मैं अपनी फ़ाइल में है कि अनुप्रेषित कर सकते हैं.
मैं सिर्फ फ़ाइल कॉल हैलो हूँ - नहीं, मैं नहीं होगा, क्योंकि है कि निष्पादन योग्य है - txt2.
अब, txt2 / हैलो <txt का समर्थन करता है, जो नमस्ते करने के लिए होने जा रहा है रोब के उत्पादन में किया जा रहा है!
>> प्रश्न?
>> ठीक है. तो फिर यहाँ हम पाइपलाइन है.
पाइपों पुनर्निर्देशन के पिछले इकाई हैं.
>> ओह. मुझे लगता है कि एक पुनर्निर्देशन के अधिक यूनिट के बजाय अगर है> आप करते हैं 2>
कि मानक त्रुटि redirecting है.
तो अगर कुछ मानक त्रुटि के लिए गया था, यह txt2 में पाने के लिए नहीं डाल दिया होगा.
लेकिन नोटिस अगर मैं 2> करते हैं, तो यह अभी भी नमस्ते मुद्रण, रोब! कमांड लाइन
क्योंकि मैं केवल मानक त्रुटि पुनः निर्देशित कर रहा हूँ, मैं मानक पुनर्निर्देशित नहीं बाहर रहा हूँ.
मानक त्रुटि और मानक बाहर अलग हैं.
यदि आप वास्तव में मानक त्रुटि के लिए लिखना चाहता था,
तो मैं इस बदलने के लिए stderr के लिए fprintf हो सकता है.
तो printf, डिफ़ॉल्ट रूप से, मानक बाहर प्रिंट.
अगर मैं मानक त्रुटि के लिए मैन्युअल रूप से मुद्रित करना चाहते हैं, तो मैं fprintf का उपयोग करने के लिए है
निर्दिष्ट और क्या मैं मुद्रित करने के लिए करना चाहते हैं.
यदि बजाय मैं fprintf stdout किया है, तो यह है कि मूल रूप से printf के बराबर है.
लेकिन fprintf मानक त्रुटि.
तो अब, अगर मैं txt2 में इस रीडायरेक्ट, नमस्कार, रोब! अभी भी कमांड लाइन पर मुद्रित हो रही है
क्योंकि यह मानक त्रुटि हो रही छपा है और मैं केवल मानक पुनः निर्देशित कर रहा हूँ.
अगर मैं अब मानक त्रुटि अनुप्रेषित, अब यह, नहीं मिलता मुद्रित किया था और txt2 नमस्ते करने के लिए हो सकता है, रोब जा रहा है!
तो अब, तुम अपने वास्तविक त्रुटियों मानक त्रुटि मुद्रित कर सकते हैं
और मानक बाहर करने के लिए नियमित रूप से अपने संदेश मुद्रित.
और इसलिए जब आप अपने कार्यक्रम चलाते हैं, तो आप इसे के रूप में चलाने के / कर सकते हैं. नमस्ते 2 के साथ इस प्रकार>
इतना है कि अपने कार्यक्रम के लिए सामान्य रूप से चला जा रहा है,
लेकिन किसी भी त्रुटि संदेश है कि आप के बाद अपने त्रुटि लॉग में जाँच कर सकते हैं,
त्रुटियों, और फिर बाद में देखने के लिए और अपनी त्रुटियों फ़ाइल में किसी भी त्रुटि है कि क्या हुआ होगा.
>> प्रश्न?
>> पिछले एक पाइप, जो मानक एक आदेश से बाहर लेने के रूप में आप के बारे में सोच सकते हैं
और यह अगले आदेश के मानक बना रही है.
यहाँ एक उदाहरण गूंज एक कमांड लाइन बात है
कि बस गूंज मैं जो कुछ भी अपने तर्क के रूप में डाल दिया जा रहा है. मैं उद्धरण नहीं रखा जाएगा.
इको ब्ला, ब्ला, ब्ला ब्ला ब्ला ब्ला, प्रिंट जा रहा है.
इससे पहले, जब मैंने कहा कि मैं एक txt फ़ाइल में रोब डाल दिया था
क्योंकि मैं केवल txt फ़ाइलें अनुप्रेषित कर सकते हैं, बजाय / मैं रोब गूंज
और फिर इसे में पाइप / हैलो, कि यह भी बात की इसी प्रकार करना होगा.
यह इस आदेश के उत्पादन, गूंज रोब ले जा रहा है,
और यह के लिए निवेश के रूप में उपयोग करते हुए / हैलो.
आप यह सोचने के रूप में पहली बार एक फ़ाइल में गूंज रोब अनुप्रेषित कर सकते हैं
और फिर / हैलो कि फ़ाइल में इनपुट कि सिर्फ outputted किया गया था.
लेकिन यह तस्वीर का अस्थायी फ़ाइल बाहर ले जाता है.
>> उस पर सवाल?
>> अगला सवाल यह शामिल हो रहा है.
पाइपलाइन क्या आप एक names.txt नामक एक फाइल में अद्वितीय नामों की संख्या को खोजने के लिए इस्तेमाल कर सकते हैं?
आदेशों हम करने के लिए यहाँ का उपयोग करना चाहते हैं के लिए जा रहे हैं अद्वितीय, तो uniq, और फिर wc हैं.
आप आदमी uniq करने के लिए वास्तव में है कि वह क्या करता है पर देख सकते हैं,
और यह सिर्फ इनपुट से आसन्न मिलान लाइनों को फिल्टर करने के लिए जा रहा है.
और आदमी wc newline, शब्द, और प्रत्येक फ़ाइल के लिए बाइट गिनती प्रिंट जा रहा है.
और हम करने के लिए उपयोग करना चाहते हैं के लिए जा रहे हैं पिछले एक प्रकार है,
जो सिर्फ txt फ़ाइल की तर्ज तरह जा रहा है.
अगर मैं कुछ txt फ़ाइल, names.txt, बनाने और इसे रोब, टॉमी, यूसुफ, टॉमी, यूसुफ, आरजे, रोब है,
क्या मैं यहाँ क्या करना चाहते है कि इस फाइल में अद्वितीय नामों की संख्या मिल.
तो जवाब क्या होना चाहिए? >> [छात्र] 4. >> हाँ.
यह 4 रोब, टॉमी, यूसुफ के बाद होना चाहिए, आरजे इस फाइल में ही अनूठा नाम हैं.
इस दिशा में पहला कदम है, अगर मैं सिर्फ names.txt पर शब्द गणना करते हैं,
यह वास्तव में मुझे सब कुछ कह रही है.
यह वास्तव में छपाई - चलो देखते हैं, आदमी wc newlines, शब्द, और बाइट गिनती.
अगर मैं केवल लाइनों के बारे में परवाह है, तो मैं सिर्फ wc-l names.txt कर सकते हैं.
तो यह है कि एक कदम है.
लेकिन मैं wc-l names.txt नहीं करना चाहते क्योंकि names.txt सिर्फ सभी नाम शामिल हैं,
और मैं किसी भी गैर - अद्वितीय लोगों को फिल्टर करना चाहते हैं.
तो अगर मैं uniq names.txt करते, कि मुझे काफी नहीं दे कि मैं क्या चाहता हूँ
क्योंकि दोहराया नाम अभी भी वहाँ हैं.
ऐसा क्यों है? Uniq क्यों नहीं कर रहा है कि मैं क्या करना चाहते हैं?
[छात्र] नहीं कर रहे हैं डुप्लिकेट [अश्राव्य] >> हाँ.
Uniq के लिए आदमी पृष्ठ याद रखें फिल्टर आसन्न मिलान लाइनों कहते हैं.
वे आसन्न नहीं कर रहे हैं, तो यह उन्हें फ़िल्टर नहीं होगा.
यदि मैं उन्हें पहले सॉर्ट करने के लिए, सॉर्ट names.txt सभी डुप्लिकेट लाइनों को एक साथ रखा जा रहा है.
तो अब तरह names.txt कि है.
Uniq | मैं uniq है, जो करने के लिए निवेश के रूप में उपयोग करना चाहते हैं कि करने के लिए जा रहा हूँ.
यह मुझे यूसुफ, आरजे, रोब, टॉमी देता है,
और मैं WC-एल इनपुट के रूप में उपयोग करना चाहते हैं कि,
जो मुझे 4 दे रहा है.
जैसे कि यह यहाँ का कहना है, पाइप लाइन क्या आप इस्तेमाल कर सकते हैं?
आप आदेशों की एक श्रृंखला का उपयोग कर की तरह चीजों की एक बहुत कुछ कर सकते हैं
जहां आप एक आदेश से अगले आदेश के लिए इनपुट के रूप में उत्पादन का उपयोग करें.
आप चीजों की एक बहुत चालाक चीजों में से एक बहुत कुछ कर सकते हैं.
>> प्रश्न?
ठीक है.
कि यह पाइप और redirection के लिए है.
>> अब हम वास्तविक सामान, कोडिंग सामान को पर चलते हैं.
इस पीडीएफ के अंदर, आप इस कमांड देखेंगे,
और आप अपने उपकरण में इस आदेश को चलाने के लिए चाहता हूँ.
wget समादेश सिर्फ इंटरनेट से कुछ प्राप्त करने के लिए मूल रूप से,
इतना wget और इस URL.
यदि आप अपने ब्राउज़र में इस URL के लिए चला गया है, यह है कि फाइल डाउनलोड करेगा.
मैं सिर्फ इस पर क्लिक किया है, तो यह मेरे लिए फाइल डाउनलोड.
लेकिन टर्मिनल के अंदर उस चीज़ के wget लेखन
सिर्फ यह अपने टर्मिनल में डाउनलोड करने के लिए जा रहा है.
मैं section5.zip है, और आप section5.zip खोलना चाहता हूँ,
जो आप एक section5 फ़ोल्डर बुलाया जा रहा है,
है जो फ़ाइलों हम आज के अंदर का उपयोग करने के लिए होने जा रहे हैं के सभी किया जा रहा है.
के रूप में इन कार्यक्रमों फ़ाइल नाम का सुझाव है, वे एक बिट छोटी गाड़ी हो,
तो अपने मिशन के लिए बाहर आंकड़ा क्यों GDB का उपयोग है.
क्या हर कोई उन्हें / डाउनलोड किया है और पता है कि कैसे प्राप्त करने के लिए उन्हें डाउनलोड
उनके उपकरण में? ठीक है.
>> ./buggy1 चल रहा है, यह विभाजन गलती (कोर फेंक दिया) कहेंगे,
जो किसी भी समय आप एक segfault, यह एक बुरी बात है.
क्या परिस्थितियों के तहत आप एक segfault मिलता है?
[छात्र] एक शून्य सूचक dereferencing. >> हाँ. तो यह है कि एक उदाहरण है.
आप एक segfault पाने के लिए जा रहे हैं एक शून्य सूचक dereferencing.
एक का मतलब है segfault क्या है आप स्मृति छू रहे हैं आप को छू नहीं होना चाहिए.
तो एक शून्य सूचक dereferencing 0 पते को छू रहा है,
और मूल रूप से, सभी कंप्यूटरों आजकल का कहना है कि पता 0 स्मृति आप को छू नहीं किया जाना चाहिए है.
तो यही कारण है कि एक segfault में एक शून्य सूचक परिणाम अपसंदर्भन.
जब आप एक सूचक को प्रारंभ करने के लिए नहीं होता है, तो यह एक कचरा मूल्य है,
और इसलिए जब आप भिन्नता के लिए कोशिश, सभी संभावना में आप स्मृति छू रहे हैं
कि कहीं नहीं के बीच में है.
यदि आप भाग्यशाली और कचरा मूल्य प्राप्त होता है
करने के लिए कहीं ढेर या कुछ पर बात करने के लिए हुआ है,
तो जब आप भिन्नता है कि सूचक है जो आप प्रारंभ नहीं किया है,
कुछ भी गलत नहीं जाना होगा.
लेकिन अगर यह इशारा कर रहा है, कहते हैं, ढेर और ढेर के बीच कहीं न कहीं,
या यह सिर्फ कहीं है कि अपने कार्यक्रम के द्वारा करने के लिए नहीं इस्तेमाल किया गया है अभी तक इशारा कर रहा है,
तो आप स्मृति छू रहे हैं और आप को छू नहीं किया जाना चाहिए और आप segfault.
जब आप एक पुनरावर्ती समारोह लिखने और यह भी कई बार recurses
और अपने ढेर बातों में बहुत बड़ी है और ढेर टकराया बढ़ता
है कि इसके साथ टकराने नहीं चाहिए, आप स्मृति छू रहे हैं आप को छू नहीं होना चाहिए,
ताकि आप segfault.
यही कारण है कि segfault एक क्या है.
>> यह भी एक ही कारण है कि अगर आप की तरह एक स्ट्रिंग है -
चलो वापस पिछले कार्यक्रम के लिए जाना है.
में hello.c - मैं अभी कुछ और करने के लिए जा रहा है.
चार * = "हैलो दुनिया!"
, अगर मैं * = कुछ या एस [0] = 'एक्स' का उपयोग करें
इतना करना है हैलो, / हैलो, क्यों कि segfault था?
ऐसा क्यों segfault था?
आप क्या उम्मीद करने के लिए क्या होगा?
अगर मैं printf ("% s \ n", एस), तुम क्या करने के लिए मुद्रित किया जा उम्मीद करेंगे?
[छात्र] एक्स हैलो. >> हाँ.
समस्या यह है कि जब आप इस तरह एक स्ट्रिंग की घोषणा,
एक सूचक है कि ढेर पर जाने के लिए जा रहा है है,
और एस के लिए इशारा कर रहा है कि क्या इस स्ट्रिंग है जो केवल पढ़ने के लिए स्मृति में निहित है.
तो बस नाम, स्मृति केवल पढ़ने के द्वारा, आप विचार कर लेना चाहिए
कि अगर आप बदलना क्या केवल पढ़ने के लिए स्मृति में करने की कोशिश,
आप कुछ आप स्मृति के साथ नहीं होना चाहिए कर कर रहे हैं और आप segfault.
यह वास्तव में * चार और चार [] के बीच एक बड़ा अंतर है.
तो एस चार [], अब इस स्ट्रिंग के ढेर पर डाल दिया जा रहा है,
और ढेर केवल पढ़ने के लिए नहीं है, जिसका अर्थ है कि यह पूरी तरह से ठीक काम करना चाहिए.
और यह है.
याद रखें कि जब मैं चार * = "हैलो! दुनिया", एस ही ढेर पर है
लेकिन कहीं और अंक, और है कि कहीं और करने के लिए केवल पढ़ने के लिए होता है.
लेकिन चार] [सिर्फ ढेर पर कुछ है.
तो यह है कि एक segfault होने का एक और उदाहरण है.
>> हमने देखा कि ./buggy1 एक segfault परिणामस्वरूप.
सिद्धांत रूप में, आप buggy1.c पर तुरंत नहीं दिखना चाहिए.
इसके बजाय, हम gdb के माध्यम से इसे देख लेंगे.
कि सूचना जब आप विभाजन गलती (कोर फेंक दिया) मिलता है,
आप यहाँ बुलाया कोर पर इस फाइल को मिलता है.
यदि हम ls-l, हम देखेंगे कि कोर आम तौर पर एक बहुत बड़ी फाइल है.
इस फ़ाइल के बाइट्स की संख्या है, तो ऐसा लगता है जैसे यह 250-कुछ किलोबाइट है.
इसका कारण यह है कि कोर डंप वास्तव में क्या है
है जब आपके प्रोग्राम दुर्घटनाओं, स्मृति के अपने कार्यक्रम के राज्य
बस कॉपी और इस फाइल में चिपकाया जाता है.
ऐसा लगता है कि फ़ाइल में फेंक दिया जाता है.
इस कार्यक्रम है, जबकि यह चल रहा था, लगभग 250 किलोबाइट का एक स्मृति उपयोग हुआ है,
और इतना है कि क्या इस फाइल में फेंक दिया गया.
अब आपको लगता है कि फ़ाइल में देखो, अगर हम gdb buggy1 कोर कर सकते हैं.
हम सिर्फ buggy1 gdb करते हैं, कर सकते हैं और है कि अभी तक gdb शुरू कर देंगे नियमित रूप से,
अपने इनपुट फ़ाइल के रूप में buggy1 का उपयोग.
लेकिन अगर आप gdb buggy1 कोर, तो यह विशेष रूप से करने के लिए gdb शुरू करने जा रहा है
कि कोर फाइल देख.
और आप buggy1 का मतलब है gdb कह जानता है कि कि कोर फ़ाइल buggy1 कार्यक्रम से आता है.
तो gdb buggy1 कोर करने के लिए हमें तुरंत लाने जा रही है
जहां कार्यक्रम समाप्त करने के लिए हुआ है.
हम यहाँ कार्यक्रम संकेत 11, विभाजन गलती के साथ समाप्त किया.
हम विधानसभा की एक पंक्ति है, जो शायद बहुत मददगार नहीं है देखना होगा.
लेकिन अगर आप बीटी या बैकट्रैस लिखें, जो करने के लिए समारोह होने जा रहा है
कि हमें हमारे वर्तमान ढेर फ्रेम की सूची देता है.
तो बैकट्रैस. ऐसा लग रहा है जैसे हम केवल दो ढेर फ्रेम है.
पहले हमारे मुख्य ढेर फ्रेम है,
और दूसरा इस समारोह में कहा कि हम में होने के लिए ढेर फ्रेम है,
जो दिखता है जैसे हम केवल के लिए विधानसभा कोड है.
तो चलो हमारे मुख्य समारोह में वापस जाने के लिए,
करने के लिए और क्या करना है कि हम 1 फ्रेम कर सकते हैं, और मुझे लगता है कि हम भी कर सकते हैं,
लेकिन मैं लगभग कभी नीचे - ऊपर या. हाँ.
ऊपर और नीचे. ऊपर तुम लाता है एक स्टैक फ्रेम, नीचे आप नीचे लाता है एक स्टैक फ्रेम.
मैं उस का उपयोग कभी नहीं करते हैं.
मैं बस विशेष रूप से एक फ्रेम, जो 1 लेबल फ्रेम करने के लिए जाना जाता है का कहना है.
1 फ्रेम करने के लिए हमें लाने के लिए मुख्य ढेर फ्रेम में जा रहा है,
और यह सही यहाँ हम में होना होता है कोड की लाइन कहते हैं.
यदि हम कोड के एक जोड़े को और अधिक लाइनों चाहते थे, हम सूची कह सकते हैं,
और कहा कि हमें इसके चारों ओर सभी कोड की लाइनों देने के लिए जा रहा है.
हम लाइन में segfaulted 6 थी:
अगर (strcmp ("CS50 चट्टानों", argv [1]) == 0).
यदि यह अभी तक स्पष्ट नहीं है, आप इसे सीधे बस सोच क्यों यह segfaulted द्वारा प्राप्त कर सकते हैं यहाँ से.
लेकिन हम इसे एक कदम आगे ले सकते हैं और कहते हैं, "क्यों argv [1] segfault होगा?"
चलो प्रिंट argv [1], और यह 0x0 है, जो शून्य सूचक है की तरह लग रहा है.
हम CS50 चट्टानों और अशक्त strcmping रहे हैं, और इसलिए कि segfault करने के लिए जा रहा है.
और क्यों है argv [1] अशक्त?
[छात्र] क्योंकि हम इसे किसी भी कमांड लाइन तर्क देना नहीं था.
हाँ. हम इसे किसी भी कमांड लाइन तर्क देना नहीं था.
तो ./buggy1 केवल argv [0] ./buggy1 हो जा रहा है.
यह एक argv [1] नहीं जा रहा है इतना, कि segfault के लिए जा रहा है.
लेकिन अगर, बजाय, मैं सिर्फ CS50 करते हैं, यह कहना है कि आप एक डी मिलता जा रहा है
क्योंकि है कि क्या यह करना चाहिए है.
Buggy1.c में देख रहे हैं, यह करने के लिए प्रिंट करने के लिए माना जाता है "तुम एक डी मिलता है"
यदि argv [1] "CS50 चट्टानों" नहीं है, "आप एक डी मिलता है", और "आप एक हो जाओ!"
तो अगर हम एक एक करना चाहते हैं, हम इस सच के रूप में तुलना की जरूरत है,
जिसका अर्थ है कि यह 0 से तुलना.
तो argv [1] "CS50 चट्टानों" होने की जरूरत है.
यदि आप कमांड लाइन पर जो करना चाहते हैं, आप \ उपयोग के लिए अंतरिक्ष से बचने की जरूरत है.
तो CS50 \ चट्टानों तुम और एक एक हो जाओ!
यदि आप बैकस्लैश नहीं करते हैं, यह काम क्यों नहीं करता है?
[छात्र] यह दो अलग अलग तर्क है. >> हाँ.
Argv [1] CS50 होने जा रहा है, और argv [2] की चट्टानों को होने जा रहा है. ठीक है.
>> अब ./buggy2 फिर segfault जा रहा है.
यह अपने कोर फाइल के साथ खोलने के बजाय, हम सिर्फ buggy2 सीधे खोल देंगे,
gdb इतना buggy2.
अब अगर हम सिर्फ हमारे कार्यक्रम चलाने, तो यह कहना है कि कार्यक्रम संकेत SIGSEGV प्राप्त करने जा रहा है,
जो segfault संकेत है, और यह है, जहां यह होने के लिए हुआ है.
हमारे बैकट्रैस को देखते हुए, हम देखते हैं कि हम समारोह oh_no में थे,
है जो समारोह छोटे आकार का है, जो समारोह binky द्वारा बुलाया गया था द्वारा बुलाया गया था,
जो मुख्य द्वारा बुलाया गया था.
हम भी इन कार्यों के लिए तर्क भी देख सकते हैं.
सुवेश और binky के लिए तर्क था 1.
यदि हम oh_no समारोह को सूचीबद्ध करने के लिए, हम देखते हैं कि oh_no सिर्फ char ** = रिक्त कर रही है;
* = "बूम";
कि असफल क्यों चाहते हैं?
[छात्र] आप अशक्त संकेतक भिन्नता नहीं कर सकते? >> हाँ.
यह सिर्फ इतना कह रहा है नल है, चाहे तो वह एक char ** होता है,
जो, आप कैसे यह व्याख्या पर निर्भर करता है, यह एक स्ट्रिंग के लिए एक संकेतक के लिए एक सूचक हो सकता है
या तारों की एक सरणी.
यह एस रिक्त है, तो * एक शून्य सूचक dereferencing है,
और इसलिए इस दुर्घटना ही जा रहा है.
यह एक तेज तरीके आप संभवतः segfault सकते है.
यह सिर्फ एक शून्य सूचक की घोषणा है और तुरंत segfaulting.
है oh_no क्या कर रहा है.
अगर हम एक फ्रेम जाना है, तो हम समारोह है कि oh_no बुलाया में शामिल होने के लिए जा रहे हैं.
मैं कि नीचे से करने की जरूरत है.
यदि आप एक आदेश में प्रवेश नहीं करते हैं और आप बस फिर से मारा,
यह सिर्फ पिछले आदेश है कि तुम भाग दोहराना होगा.
हम 1 फ्रेम में हैं.
इस फ्रेम लिस्टिंग, हम देखते हैं हमारे यहाँ समारोह है.
आप सूची फिर से मारा, कर सकते हैं, या आप 20 की सूची कर सकते हैं और इसे और अधिक सूची जाएगा.
समारोह सुवेश का कहना है कि अगर मैं 1 है, तो oh_no कार्य करने के लिए जाना है,
slinky कार्य करने के लिए जाना.
और हम जानते हैं कि मैं एक है, क्योंकि हम यहाँ देखना होगा
कि सुवेश 1 तर्क के साथ बुलाया गया था.
या आप बस मैं प्रिंट कर सकते हैं और यह कहना होगा कि मैं 1 है.
हम सुवेश में वर्तमान में कर रहे हैं, और अगर हम एक फ्रेम जाना है, हम जानते हैं कि हम binky में समाप्त होगा.
ऊपर. अब हम binky में हैं.
इस समारोह सूची से पहले आधे मुझे काट - लिस्ट -
यह बंद करना शुरू कर के रूप में अगर मैं 0 है, तो हम के लिए यह oh_no कॉल करने के लिए जा रहे हैं, और छोटे आकार का फोन है.
हम जानते हैं कि मैं 1 वर्ष के थे, तो यह छोटे आकार का कहा जाता है.
और अब हम मुख्य में वापस आ गए हैं, और मुख्य बस int i = रैंड () 3% होने जा रहा है;
कि सिर्फ तुम एक यादृच्छिक संख्या है कि या तो 0, 1, या 2 देने जा रहा है.
यह उस नंबर के साथ binky कॉल करने के लिए जा रहा है, और यह 0 वापस आ जाएगी.
इस पर देख रहे हैं,
कार्यक्रम के माध्यम से स्वयं चलने के यह तुरंत बिना चल रहे,
आप मुख्य में एक ब्रेक अंक निर्धारित होता है, जिसका अर्थ है कि जब हम इस कार्यक्रम को चलाने
अपने कार्यक्रम चलाता है जब तक यह एक को तोड़ने बिंदु हिट.
कार्यक्रम चल रहा है तो, इसे चलाते हैं और फिर यह मुख्य समारोह मारा और चलना बंद कर देंगे.
अब हम मुख्य के अंदर कर रहे हैं, और कदम या अगले हमें कोड की अगली पंक्ति में लाने जा रही है.
आप कदम या अगले कर सकते हैं.
अगले निशाना साधते हुए अब मैं रैंड () 3%, तो हम मैं के मूल्य मुद्रित कर सकते हैं के लिए किया गया है की स्थापना की है,
और यह कहना होगा कि मैं 1 है.
अब यह बात नहीं है कि हम अगले कदम का उपयोग करता है.
मुझे लगता है कि यह पिछले एक में मायने रखता है, लेकिन हम अगले उपयोग करना चाहते हैं.
यदि हम कदम का उपयोग करें, हम समारोह में कदम, जो वास्तविक बात को देखने का मतलब है
binky के अंदर हो रहा है.
यदि हम अगले का उपयोग करते हैं, तो इसका मतलब है कि समारोह पर जाना
और सिर्फ हमारी मुख्य समारोह में कोड की अगली पंक्ति के लिए जाना.
सही यहाँ इस लाइन पर, मैं जहां यह (रैंड) 3% ने कहा था;
अगर मैं कदम था, यह रैंड के कार्यान्वयन में जाना होगा
और वहाँ क्या हो रहा है पर देखो, और मैं रैंड समारोह के माध्यम से कदम सकता है.
लेकिन मैं रैंड समारोह के बारे में परवाह नहीं है.
मैं सिर्फ मुख्य में कोड की अगली पंक्ति के लिए जाना चाहते हैं, तो मैं अगले का उपयोग करें.
लेकिन अब मैं binky समारोह के बारे में परवाह नहीं है, तो मैं उस में कदम चाहते हैं.
अब मैं binky में हूँ.
कोड की पहली पंक्ति कहते हैं कि अगर (i == 0), मैं एक कदम उठाने जा रहा है,
हम देखते हैं हम सुवेश में खत्म.
अगर हम सूची बातें, हम देखते हैं कि यह जाँच मैं = 0.
मैं 0 के बराबर नहीं है, तो यह किसी और हालत के लिए चला गया,
जो छोटे आकार का (i) कॉल करने के लिए जा रहा है.
आप भ्रमित हो सकता है.
यदि आप इन लाइनों पर सीधे देखो, आपको लगता है कि हो सकता है अगर (मैं == 0)
ठीक है, तो मैं एक कदम उठाया है और अब मैं सुवेश (i) में हूँ,
आपको लगता है कि हो सकता है इसका मतलब यह होगा मैं = 0 या कुछ और.
नहीं, यह सिर्फ मतलब है कि वह जानता है कि यह सीधे लाइन सुवेश (i) के लिए छड़ी कर सकते हैं.
क्योंकि मैं 0 नहीं है, अगले कदम के लिए किसी और पर समाप्त करने के लिए नहीं जा रहा है.
वरना यह पर रोक के लिए जा रहा है एक लाइन नहीं है.
यह सिर्फ अगली पंक्ति यह वास्तव में निष्पादित, जो छोटे आकार का है (i) के लिए जाना जा रहा है.
सुवेश (i) में कदम, हम देखते हैं अगर (i == 1).
हम i = 1 पता नहीं है, इसलिए जब हम कदम है, हम जानते हैं कि हम oh_no में खत्म हो जा रहे
क्योंकि मैं = 1 समारोह oh_no, जो आप में कदम कर सकते हैं कॉल,
जो स्थापित करने जा रहा है चार ** = अशक्त और तुरंत "बूम".
और फिर वास्तव में buggy2 के कार्यान्वयन में देख रहे हैं,
0, 1, 2 या - बुला binky, यह है, मैं सिर्फ एक यादृच्छिक संख्या हो रही है
जो अगर मैं 0 है यह oh_no कहता है, और यह छोटे आकार का कहता है, जो यहाँ आता है.
अगर मैं 1, कॉल oh_no, और slinky कॉल, जो यहाँ आ रहा है,
अगर मैं 2 है, oh_no कहते हैं.
मैं यह भी नहीं लगता कि वहाँ एक रास्ता है -
क्या किसी को एक प्रोग्राम है कि नहीं segfault जाएगा बनाने का एक तरह से देखते हैं?
क्योंकि जब तक मैं कुछ याद आ रही है, अगर मैं 0 है, तो आप तुरंत segfault हूँ,
और आप एक समारोह जो अगर मैं 1 आप segfault जाना,
और आप एक समारोह है जहां अगर मैं 2 आप segfault जाना.
तो कोई फर्क नहीं पड़ता कि तुम क्या करते हो, आप segfault.
>> मैं यह char ** = रिक्त करने के बजाय होगा फिक्सिंग के एक तरीका लगता है,
आपको लगता है कि स्ट्रिंग के लिए अंतरिक्ष malloc सकता है.
Sizeof क्या हम malloc (sizeof) कर सकता है?
[छात्र] (चार) 5 *? >> यह सही लगता है?
मैं मान रहा हूँ अगर मैं वास्तव में यह भागा काम करेंगे, लेकिन यह नहीं है कि मैं क्या देख रहा हूँ.
एस के प्रकार को देखो. चलो int * जोड़ने के लिए, तो int * x.
मैं malloc (sizeof (int)).
या अगर मैं 5 की एक सरणी चाहता था, मैं (sizeof (int) * 5) करना होगा;
क्या होगा यदि मैं एक int ** है?
मैं क्या होगा malloc?
[छात्र] सूचक का आकार. >> हाँ. (Sizeof (int *));
यहाँ नीचे एक ही बात.
मैं चाहता हूँ (sizeof (चार) *);
यह सूचक है कि 'बूम' अंक के लिए जगह आवंटित करने के लिए जा रहा है.
मैं "बूम" खुद के लिए जगह आवंटित करने की जरूरत नहीं है
क्योंकि यह मूल रूप से मैं पहले क्या कहा बराबर है
चार * x = "बूम".
"बूम" पहले से मौजूद है. यह केवल पढ़ने के लिए स्मृति के क्षेत्र में करने के लिए मौजूद होता है.
लेकिन यह पहले से ही मौजूद है, जो कोड की इस पंक्ति का अर्थ है, अगर एस एक char ** है,
फिर * एक चार * है और आप इस चार * स्थापित कर रहे हैं "बूम" को इंगित.
अगर मैं s में 'बूम' की नकल करना चाहता था, तो मैं एस के लिए जगह आवंटित की आवश्यकता होगी.
मैं करूँगा * = malloc (sizeof (चार) 5 *);
क्यों 5?
क्यों नहीं 4? ऐसा लगता है कि "बूम" 4 अक्षर. >> [छात्र] अशक्त चरित्र.
हाँ. अपने तार के सभी अशक्त चरित्र की जरूरत के लिए जा रहे हैं.
अब मैं strcat की तरह कुछ कर सकते हैं - एक स्ट्रिंग नकल के लिए कार्य क्या है?
[छात्र] cpy? >> Strcpy.
आदमी strcpy.
तो strcpy या strncpy.
strncpy एक बिट सुरक्षित है क्योंकि आप निर्दिष्ट कर सकते हैं कि वास्तव में कितने वर्ण,
लेकिन यहाँ यह कोई फर्क नहीं पड़ता है क्योंकि हम जानते हैं.
तो strcpy और बहस में देखो.
पहला तर्क अपने गंतव्य है.
दूसरा तर्क हमारे स्रोत है.
हम अपने गंतव्य * में कॉपी करने के लिए जा रहे हैं "बूम" सूचक है.
आप के बजाय सिर्फ हम क्या था एक strcpy के साथ इस से पहले ऐसा क्यों करना चाहते हो सकता है
* s = "बूम"?
वहाँ एक कारण है कि आप ऐसा करना चाहते हैं हो सकता है, लेकिन है कि क्या कारण है?
[छात्र] यदि आप "बूम" में कुछ बदलना चाहते हैं. >> हाँ.
अब मैं एस की तरह कुछ कर सकते हैं [0] = 'एक्स';
वजह अंक ढेर और ढेर पर है कि अंतरिक्ष के लिए है कि के लिए इशारा कर रहा है
ढेर है, जो "बूम" भंडारण है पर और अधिक स्थान के लिए एक सूचक है.
तो 'बूम' की इस प्रति के ढेर में संग्रहित किया जा रहा है.
तकनीकी रूप से हमारे कार्यक्रम में 'बूम' की दो प्रतियां हैं.
पहली एक है कि सिर्फ इस "बूम" स्ट्रिंग स्थिरांक द्वारा दिए गए है,
और 'बूम' की दूसरी प्रति, strcpy 'बूम' की प्रतिलिपि बनाया.
लेकिन 'बूम' के प्रति ढेर पर संग्रहित किया जा रहा है, और ढेर आप को बदलने के लिए स्वतंत्र हैं.
ढेर केवल पढ़ने के लिए नहीं है, तो इसका मतलब है कि [0]
आप "बूम" के मूल्य बदल रहा है.
यह करने के लिए आपको उन पात्रों को बदलने जा रहा है.
>> प्रश्न?
ठीक है.
>> Buggy3 पर चल रहा है, चलो gdb buggy3.
हम बस इसे चलाते हैं और हम देखते हैं कि हम एक segfault हो.
बैकट्रैस हम अगर, वहाँ केवल दो कार्य कर रहे हैं.
यदि हम हमारे मुख्य समारोह में जाना है, तो हम देखते हैं कि हम इस लाइन पर segfaulted.
तो बस इस लाइन पर देख रहे हैं, के लिए (int लाइन = 0; fgets इस सामान बराबर नहीं रिक्त करता है;
लाइन + +).
हमारे पिछले फ्रेम _IO_fgets बुलाया गया था.
आप देखेंगे कि सी में निर्मित कार्यों के साथ एक बहुत कुछ है,
कि जब आप segfault हो, वहाँ वास्तव में गुप्त समारोह के नाम हो जाएगा
इस _IO_fgets की तरह.
लेकिन यह है कि इस fgets कॉल करने के लिए संबंधित के लिए जा रहा है.
यहाँ के अंदर कहीं न कहीं, हम segfaulting कर रहे हैं.
अगर हम तर्क fgets के लिए तत्पर हैं, हम बफर मुद्रित कर सकते हैं.
चलो मुद्रित करने के लिए एक के रूप में - ओह, नहीं.
प्रिंट बिल्कुल के रूप में मैं यह चाहता हूँ काम करने के लिए नहीं जा रहा है.
चलो वास्तविक कार्यक्रम में देखो.
बफर एक चरित्र सरणी है. यह 128 वर्णों की एक चरित्र सरणी है.
तो जब मैं प्रिंट बफर कहते हैं, यह उन 128 वर्ण मुद्रित करने के लिए जा रहा है,
मुझे लगता है कि जो है, जो उम्मीद है.
मैं देख रहा था क्या है बफर के पते प्रिंट,
लेकिन सच है कि मुझे नहीं बता ज्यादा करता है.
तो जब मैं यहाँ x बफर कहना होगा, यह मुझे 0xbffff090 से पता चलता है,
जो, अगर आप पहले से याद है या कुछ बिंदु, Oxbffff एक ढेर ish क्षेत्र हो जाता है.
ढेर 0xc000 बस के नीचे कहीं शुरू करने के लिए जाता है.
बस इस पते देखकर, मुझे पता है कि बफर ढेर पर हो रहा है.
मेरे कार्यक्रम शुरु, भागो, ऊपर, बफर हमने देखा था वर्णों के इस अनुक्रम
कि बहुत ज्यादा व्यर्थ कर रहे हैं.
तब फ़ाइल मुद्रण, फ़ाइल की तरह दिखता है?
[छात्र] अशक्त. >> हाँ.
फ़ाइल एक फ़ाइल * प्रकार की है, तो यह एक सूचक है,
और कि सूचक के मूल्य शून्य है.
तो fgets करने के लिए एक अप्रत्यक्ष तरीके से कि सूचक से पढ़ने की कोशिश की जा रही है,
लेकिन क्रम में सूचक का उपयोग करने के लिए, यह भिन्नता है.
या, में आदेश का उपयोग करने के लिए यह क्या, यह dereferences इशारा किया जाना चाहिए.
तो यह एक शून्य सूचक और यह segfaults dereferencing है.
मैं इसे वहाँ पुनर्प्रारंभ सकता है.
यदि हम हमारे मुख्य बिंदु पर तोड़ने के लिए और चलाने के लिए,
कोड की पहली पंक्ति चार * = "nonexistent.txt" फ़ाइल नाम है,
वह क्यों इस कार्यक्रम में विफल रहता है के रूप में एक बहुत बड़ा संकेत देना चाहिए.
अगले टंकण मुझे अगली पंक्ति के लिए लाता है, जहाँ मैं इस फाइल को खोलने,
और फिर मैं तुरंत हमारी लाइन है, जहां एक बार मैं अगले मारा में मिलता है, यह segfault जा रहा है.
किसी को भी एक कारण है कि हम segfaulting किया जा सकता है बाहर फेंक देना चाहते हैं?
[छात्र] फ़ाइल मौजूद नहीं है. >> हाँ.
यह एक संकेत माना जाता है
कि जब भी आप एक फ़ाइल खोलने की कर रहे हैं आप की जाँच करने के लिए कि फ़ाइल वास्तव में मौजूद है की जरूरत है.
तो यहाँ, "nonexistent.txt";
जब हम पढ़ने के लिए fopen फ़ाइल नाम, हम तो कहने की ज़रूरत
और अगर (फ़ाइल == रिक्त) का कहना है कि printf ("फ़ाइल मौजूद नहीं है!"
या अभी तक बेहतर filename), 1 वापसी;
तो अब हम देखने के लिए अगर यह रिक्त है
इससे पहले कि वास्तव में जारी रखने और उस फ़ाइल से पढ़ने की कोशिश कर रहा है.
हम यह रीमेक सिर्फ इतना है कि वह काम करता है को देखने के लिए कर सकते हैं.
मैं एक नई लाइन को शामिल करना.
तो अब nonexistent.txt मौजूद नहीं है.
आप हमेशा इस तरह की बात के लिए जांच होनी चाहिए.
तुम हमेशा के लिए देखने के लिए अगर fopen रिक्त रिटर्न की जाँच करनी चाहिए.
आप हमेशा के लिए सुनिश्चित करें कि malloc रिक्त वापस नहीं करता है की जाँच करनी चाहिए,
या फिर आप segfault.
>> अब buggy4.c.
चल रहा है. मैं यह अनुमान लगा रहा हूँ इनपुट या संभवतः अनंत पाशन के लिए इंतज़ार कर रही है.
हाँ, यह अनंत पाशन है.
Buggy4 तो. ऐसा लगता है जैसे हम अनंत पाशन कर रहे हैं.
हम मुख्य में तोड़ सकते हैं, हमारे कार्यक्रम चलाते हैं.
GDB में, के रूप में लंबे समय के रूप में संक्षिप्त नाम आप का उपयोग स्पष्ट है
या विशेष संक्षिप्ताक्षर है कि वे आप के लिए प्रदान करते हैं,
तो आप n का उपयोग के बाहर अगले सभी तरह टाइप करने के बजाय अगले उपयोग कर सकते हैं.
और अब जब कि मैं मारा n है एक बार, मैं सिर्फ हिट दर्ज अगले जा रहा रखने के कर सकते हैं
हिट करने के लिए n दर्ज करें, n दर्ज करें, n दर्ज होने के बजाय.
ऐसा लग रहा है जैसे मैं पाश है कि सरणी [मैं] 0 से सेटिंग के लिए के कुछ प्रकार में हूँ.
ऐसा लग रहा है जैसे मैं पाश के लिए कभी नहीं तोड़ रहा हूँ इस के.
अगर मैं मुद्रित करते हैं, तो मैं 2 है, तो मैं अगले जाना होगा.
मुझे लगता है मैं मुद्रित मैं 3 है, तो मैं आगे जाना होगा.
मुझे लगता है मैं प्रिंट और मैं 3 है. अगले, मैं मुद्रित करने के लिए, मैं 4 है.
दरअसल, प्रिंट sizeof (सरणी), तो सरणी के आकार 20 है.
लेकिन ऐसा लगता है जैसे वहाँ जा रहा जब तक कुछ होता है के लिए कुछ विशेष gdb आदेश है.
यह चर के मूल्य पर एक शर्त की स्थापना की तरह है. लेकिन मुझे याद नहीं कि यह क्या है.
तो अगर हम जा रख -
तुम क्या कह रहे थे? तुम क्या लाए हो?
>> हाँ - [छात्र] प्रदर्शित करने के लिए मैं करता. तो प्रदर्शित मैं मदद कर सकता है.
अगर हम सिर्फ मैं प्रदर्शित करने के लिए, यह यहाँ डाल मैं के मूल्य क्या है
इसलिए मैं इसे बाहर प्रिंट हर बार नहीं है.
अगर हम सिर्फ अगले जा रहा रखने के लिए, हम देखते हैं 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5.
कुछ बहुत गलत हो रहा है, और मैं 0 करने के लिए किया जा रहा है फिर से कायम है.
Buggy4.c में देख रहे हैं, हम देखते हैं कि सब होता int सरणी [5];
(, मैं <= sizeof (सरणी), मैं + + मैं = 0) के लिए
सरणी [i] = 0;
हम क्या देख रहे हो कि यहाँ गलत है?
एक संकेत के रूप में, जब मैं buggy4 gdb कर रहा था - चलो मुख्य रन, तोड़ -
मैं प्रिंट sizeof (सरणी) बस देखने के लिए क्या हालत है, जहां मैं अंत में बाहर तोड़ देना चाहिए.
मैं कहाँ हूँ? क्या मैं चला?
मैं अभी तक घोषणा नहीं की थी.
तो sizeof (सरणी) प्रिंट और है कि 20 है,
जिसके बाद से मेरी सरणी 5 आकार के होने की उम्मीद है और यह 5 पूर्णांकों की,
तो पूरी बात 5 * sizeof (int) बाइट्स, जहां sizeof (int) 4 हो जाता है होना चाहिए.
तो sizeof (सरणी) 20 है.
यह क्या होना चाहिए?
Sizeof (int) [छात्र] विभाजित किया. >> हाँ, / sizeof (int).
ऐसा लगता है कि वहाँ अभी भी एक समस्या है यहाँ. मुझे लगता है कि यह सिर्फ होना चाहिए <
के बाद से यह बहुत ज्यादा हमेशा <और = <कभी नहीं.
अब चलो क्यों यह वास्तव में टूट गया था के बारे में सोचते हैं.
क्या किसी को अनुमान क्यों किया गया है मैं लूप के प्रत्येक चलना के माध्यम से 0 से रीसेट?
यहाँ है कि क्या हो रहा है के अंदर ही बात है कि सरणी [i] 0 करने के लिए स्थापित किया जा रहा है.
तो किसी भी तरह, कोड की इस पंक्ति हमारे int मैं 0 से स्थापित करने के लिए पैदा कर रहा है.
[छात्र] यह हो सकता क्योंकि यह मैं के इस हिस्से की स्मृति अधिभावी
जब यह सोचता है कि यह सरणी के अगले तत्व है? >> [Bowden] हाँ.
जब हम हमारे सरणी के अंत से परे जा रहे हैं
किसी भी तरह कि अंतरिक्ष कि हम अधिभावी कर रहे हैं मैं के मूल्य अधिभावी है.
और अगर ऐसा है हम buggy4 में देखो, मुख्य भाग को तोड़ने,
चलो मैं का पता मुद्रित.
ऐसा लगता है जैसे कि यह bffff124 है.
अब चलो सरणी का पता मुद्रित [0]. 110.
क्या [1] के बारे में क्या? 114.
[2], 118.
11c, 120. [5] सरणी bfff124 है.
तो सरणी [5] के रूप में मैं, जिसका अर्थ है कि सरणी [5] मैं एक ही पते है.
यदि वे एक ही पता है, वे एक ही बात कर रहे हैं.
तो जब हम [5] सरणी सेट 0 करने के लिए, हम मैं 0 करने के लिए स्थापित कर रहे हैं.
और अगर आप stack के मामले में लगता है कि इस बारे में,
int मैं पहली बार घोषित किया जाता है, जिसका मतलब है कि मैं ढेर पर कुछ जगह हो जाता है.
फिर [5] सरणी आवंटित है, यदि ऐसा है तो फिर 20 बाइट्स ढेर पर आवंटित कर रहे हैं.
तो मैं पहले आवंटित हो जाता है, तो इन 20 बाइट्स आवंटित हो.
तो मैं सरणी से पहले सही होता है,
और जिस तरह की वजह से पिछले सप्ताह की तरह मैं ने कहा, जहां तकनीकी ढेर नीचे बढ़ता है,
जब आप एक सरणी में सूचकांक, हम गारंटी है कि सरणी में 0 स्थिति
हमेशा सरणी में पहले की स्थिति से पहले होता है.
यह कैसे मैं पिछले हफ्ते यह आकर्षित की तरह है.
सूचना है कि नीचे हम 0 पता है और हम शीर्ष पर पता अधिकतम है.
ढेर हमेशा नीचे से बढ़ रहा है.
चलो कहते हैं कि हम मैं आवंटित.
हम पूर्णांक आवंटित मैं, जिसका अर्थ है हम अभी तक पूर्णांक यहाँ मैं आवंटित हो जाता है कहना.
तो फिर हम 5 integers के हमारे सरणी, जो कि नीचे इसका मतलब है कि आवंटित
के बाद से ढेर के नीचे से बढ़ रहा है, उन 5 integers आवंटित हो.
लेकिन कैसे arrays काम की वजह से, हम गारंटी रहे हैं कि सरणी में प्रथम स्थान
हमेशा एक सरणी में दूसरी बात कम से कम पता है.
तो सरणी स्थिति 0 हमेशा के लिए स्मृति में पहली बार होता है,
जबकि सरणी 1 स्थिति के लिए उस के बाद होता है
और सरणी 2 की स्थिति के लिए उस के बाद होता है,
जिसका अर्थ है कि सरणी स्थिति 0 कहीं नीचे यहाँ क्या होगा,
सरणी 1 स्थिति यह है कि ऊपर से क्या होगा
क्योंकि बढ़ उच्च पते का मतलब है के बाद से अधिकतम पते यहाँ है.
तो [0] नीचे यहाँ सरणी, सरणी [1] ऊपर यहाँ, सरणी [2] ऊपर यहाँ, [3] सरणी यहाँ.
सूचना से पहले कैसे हम पूर्णांक मैं सभी तरह यहाँ आवंटित,
के रूप में हम हमारे सरणी में आगे और आगे ले जाते हैं, तो हम करीब और मैं हमारे पूर्णांक के करीब हो रही है.
यह सिर्फ इतना है कि सरणी होता [5], जो हमारे सरणी परे एक स्थिति है,
वास्तव में मैं पूर्णांक जहां के लिए आवंटित किया हुआ है.
तो यह है कि बिंदु जहाँ हम ढेर पर अंतरिक्ष मार हो होता है
कि मैं पूर्णांक के लिए आवंटित किया गया था, और हम है कि 0 से स्थापित कर रहे हैं.
>> यही कारण है कि यह कैसे काम करता है. प्रश्न? हाँ.
[छात्र] कोई बात नहीं. ठीक है.
[छात्र] आप त्रुटियों के इन प्रकार से बचने हो?
त्रुटियों के इन प्रकार के? अपने प्रोग्रामिंग भाषा के रूप में उपयोग नहीं सी.
एक भाषा है कि सरणी की जाँच सीमा का उपयोग करें.
के रूप में लंबे समय के रूप में आप सावधान हो, तुम सिर्फ अपने सरणी की सीमा पिछले जाने से बचने की जरूरत है.
[छात्र] तो यहाँ जब हम अपने सरणी की सीमा पिछले चला गया -
[Bowden] यही कारण है कि जहां चीजें गलत हो रहा शुरू. >> [छात्र] ओह, ठीक है.
के रूप में लंबे समय के रूप में आप अपने सरणी के लिए आबंटित की स्मृति के भीतर रहना, तुम ठीक हो.
लेकिन सी कोई त्रुटि की जाँच करता है. यदि मैं सरणी [1000], यह ख़ुशी से सिर्फ संशोधित जो कुछ भी होता होगा -
यह सरणी की शुरुआत करने के लिए जाता है, तो यह 1000 पदों के बाद चला जाता है और यह सेट करने के लिए 0.
यह किसी की जाँच है कि ओह, यह वास्तव में यह 1000 बातें नहीं है नहीं करता है.
1000 मैं क्या बदल किया जाना चाहिए परे एक रास्ता है,
जबकि जावा या कुछ और आप सरणी सीमा सूचकांक के बाहर मिल जाएगा
या सीमा से बाहर अपवाद सूचकांक.
यही कारण है कि उच्च स्तर भाषाओं का एक बहुत इन बातों
जहां अगर आप सरणी की सीमा से परे जाना है, तो आप असफल
इतनी है कि आप चीजों को आप नीचे से नहीं बदल सकते हैं
और फिर बातें सिर्फ एक अपवाद हो रही है की तुलना में बहुत बुरा जाना
कह रही है कि आप सरणी के अंत से परे चला गया.
[छात्र] और इसलिए हम सिर्फ परिवर्तित किया जाना चाहिए <= बस के लिए <? >> [Bowden] हाँ.
यह <sizeof (सरणी) / sizeof (int) होना चाहिए;
से sizeof (सरणी) 20 है, लेकिन हम केवल 5 चाहते. >> [छात्र] ठीक है.
और सवाल? ठीक है.
>> [छात्र] मैं एक सवाल है. >> हाँ.
[छात्र] वास्तविक सरणी चर क्या है?
[Bowden] की तरह क्या सरणी है?
ऐरे ही एक प्रतीक है.
यह 20 बाइट्स संदर्भित कर रहे हैं कि हम शुरू में पता है.
आप इसे एक संकेत के रूप में कर सकते हैं, लेकिन यह एक निरंतर सूचक है.
के रूप में जल्द ही के रूप में चीजों को संकलित हो, चर सरणी अब मौजूद नहीं है.
[छात्र] तो यह कैसे सरणी के आकार करता है लगता है?
सरणी के आकार की है कि कि प्रतीक को संदर्भित करता है कि ब्लॉक के आकार को संदर्भित करता है.
जब मैं printf ("% p \ n", सरणी) की तरह कुछ करना;
चलो इसे चलाने के लिए.
क्या मैं सिर्फ गलत है?
ऐरे सरणी 'की घोषणा की.
ओह, यहाँ.
बजना चालाक है, और यह सूचना है कि मैं 5 तत्वों सरणी के रूप में घोषित करने के लिए होता है
लेकिन मैं 1000 की स्थिति में अनुक्रमण रहा हूँ.
ऐसा लगता है कि क्योंकि इन बस स्थिरांक हैं कर सकते हैं.
यह केवल देख रही है कि मैं सरणी की सीमा से परे जा रहा हूँ में अब तक जा सकते हैं.
लेकिन जब हम था कि मैं गलत हो सकता है पहले नोटिस,
यह संभवतः मैं कितने मूल्यों पर ले सकता है नहीं निर्धारित कर सकते हैं,
तो यह निर्धारित नहीं कर सकता कि मैं सरणी के अंत से परे जा रहा था.
वह सिर्फ बजना चतुर जा रहा है.
>> लेकिन अब buggy4 बनाते हैं. तो मैं और क्या गलत कर रहा हूँ?
परोक्ष पुस्तकालय समारोह 'printf' की घोषणा की.
मैं # शामिल करना चाहते करने के लिए जा रहा हूँ.
ठीक है. अब buggy4 चल रहा है.
मुद्रण सरणी के मूल्य की तरह मैं यहाँ क्या किया था, यह एक संकेत के रूप में मुद्रण
प्रिंट कुछ है कि इस तरह दिखता है - bfb8805c - जो कुछ पता है
कि ढेर ish क्षेत्र में है.
ऐरे ही एक सूचक की तरह है, लेकिन यह एक वास्तविक सूचक नहीं है,
हम एक नियमित सूचक के बाद से बदल सकते हैं.
बस कुछ निरंतर सरणी है. स्मृति के 20 ब्लॉकों पते 0xbfb8805c में शुरू.
+20- तो इस पते के माध्यम से bfb8805c या मैं -20 लगता है -
इस सरणी के लिए आबंटित की स्मृति है.
सरणी, चर ही कहीं भी संग्रहीत नहीं है.
जब आप संकलन कर रहे हैं, संकलक - इसे हाथ लहर -
लेकिन संकलक बस जहां यह सरणी जानता का प्रयोग करेंगे.
यह जानता है, जहां कि सरणी शुरू होता है,
और इसलिए यह हमेशा सिर्फ offsets के संदर्भ में बातें कर सकते हैं कि शुरू से ही करते हैं.
यह एक चर में ही करने के लिए सरणी का प्रतिनिधित्व करने की जरूरत नहीं है.
लेकिन जब मैं int * p = सरणी की तरह कुछ करते हैं, अब पी एक सूचक जो कि सरणी अंक है,
और अब पी वास्तव में ढेर पर मौजूद नहीं है.
मैं पी बदलने के लिए स्वतंत्र हूँ. मैं p = malloc कर सकते हैं.
तो यह मूल रूप से सरणी की ओर इशारा किया, अब यह ढेर पर कुछ जगह अंक.
मैं सरणी = malloc नहीं कर सकते हैं.
यदि बजना चालाक है, यह मुझ पर सही बल्ले से चिल्लाना होगा.
वास्तव में, मैं बहुत यकीन है कि जीसीसी यह भी करना होगा हूँ.
तो 'int [5] सरणी प्रकार आबंटित नहीं है.
आप एक सरणी प्रकार कुछ नहीं असाइन कर सकते हैं
क्योंकि सिर्फ एक निरंतर सरणी है.
यह संदर्भ जो उन 20 बाइट्स एक प्रतीक है. मैं इसे बदल नहीं सकते.
>> [छात्र] और जहां सरणी के आकार संग्रहीत किया जाता है?
[Bowden] यह कहीं नहीं जमा है. ऐसा नहीं है जब यह संकलन है.
तो जहां सरणी के आकार में संग्रहीत किया जाता है?
आप केवल समारोह में कहा कि सरणी ही घोषित किया जाता है के अंदर sizeof (सरणी) का उपयोग कर सकते हैं.
तो अगर मैं कुछ समारोह, foo, करते हैं और मैं (int सरणी [])
printf ("% d \ n", sizeof (सरणी));
और फिर नीचे यहाँ मैं foo (सरणी) कहते हैं;
इस समारोह के अंदर - चलो इसे चलाने के.
यह चालाक बजना फिर से किया जा रहा है.
यह मुझे बता रहा है कि सरणी समारोह पैरामीटर पर sizeof
'int *' के आकार में वापस आ जाएगी.
यह एक त्रुटि हो सकता है अगर यह नहीं होगा कि मैं क्या करने के लिए ऐसा करना चाहता था.
चलो वास्तव में बंद Werror बारी.
चेतावनी. चेतावनियां ठीक हैं.
यह अभी भी रूप में लंबे समय के संकलन के रूप में यह एक चेतावनी है.
/. A.out 4 प्रिंट करने के लिए जा रहा है.
चेतावनी है कि उत्पन्न किया गया है क्या गलत हो गया था का एक स्पष्ट संकेत है.
इस int सरणी सिर्फ sizeof (* int) प्रिंट के लिए जा रहा है.
यहां तक ​​कि अगर मैं यहाँ में [5] सरणी डाल दिया है, यह अभी भी सिर्फ sizeof (* int) प्रिंट जा रहा है.
इसलिए जैसे ही आप इसे एक समारोह में पारित, arrays और संकेत के बीच भेद
nonexistent है.
यह एक सरणी कि ढेर पर घोषित किया गया था होना होता है,
लेकिन जैसे ही हम उस मूल्य से गुजारें, कि 0xbf ब्ला ब्ला,, इस समारोह में ब्ला,
तो इस सूचक ढेर पर है कि सरणी अंक.
, तो इसका मतलब है कि sizeof केवल समारोह में लागू होता है कि सरणी में घोषित किया गया था
जिसका अर्थ है कि जब आप इस समारोह का संकलन कर रहे हैं,
जब बजना इस समारोह के माध्यम से चला जाता है, यह देखता है सरणी 5 आकार के एक int सरणी है.
तो फिर यह sizeof (सरणी) को देखता है. खैर, यह 20 है.
यह वास्तव में कैसे sizeof मूल रूप से लगभग सभी मामलों के लिए काम करता है.
Sizeof एक समारोह नहीं है, यह एक ऑपरेटर है.
आप sizeof समारोह फोन नहीं है.
Sizeof (int), संकलक सिर्फ इतना है कि 4 से अनुवाद करेंगे.
समझे? ठीक है.
>> [छात्र] तो मुख्य और foo में sizeof (सरणी) के बीच क्या फर्क है?
यह इसलिए है क्योंकि हम sizeof (सरणी) है, जो int * प्रकार की कह रहे हैं,
जबकि सरणी नीचे यहाँ int * प्रकार की नहीं है, यह एक int सरणी है.
>> [छात्र] तो, अगर आप पैरामीटर [] के बजाय int * सरणी में था
मतलब यह है कि आप अभी भी सरणी बदल सकता है किया जाएगा, क्योंकि अब यह एक सूचक है?
[Bowden] इस तरह? >> [छात्र] हाँ. समारोह के भीतर सरणी अब बदल?
[Bowden] आप दोनों ही मामलों में सरणी बदल सकता है.
इन दोनों मामलों में आप कहने के लिए [4] सरणी = 0 के लिए स्वतंत्र हैं.
[छात्र] लेकिन आप कुछ और करने के लिए सरणी बात कर सकते हैं?
[Bowden] ओह. हाँ. या तो मामले में - >> [छात्र] हाँ.
[Bowden] [] और एक int * सरणी सरणी के बीच अंतर है, वहाँ कोई नहीं है.
तुम भी यहाँ में कुछ बहुआयामी सरणी मिल सकती है
कुछ सुविधाजनक वाक्यविन्यास के लिए, लेकिन यह अभी भी एक सूचक है.
इसका मतलब यह है कि मैं सरणी करने के लिए स्वतंत्र हूँ = malloc (sizeof (int)), और अब कहीं और बात.
लेकिन सिर्फ यह हमेशा के लिए कैसे काम करता है और हमेशा की तरह,
इसे बनाने के द्वारा इस सरणी बदलने कुछ और करने के लिए इंगित
करता है को बदलने के नीचे इस सरणी यहाँ नहीं है क्योंकि यह तर्क की एक प्रति है,
यह है कि तर्क के लिए एक सूचक नहीं है.
और वास्तव में, बस के रूप में संकेत है कि यह ठीक है कि एक ही -
हम पहले से ही क्या मुद्रण सरणी प्रिंट देखा -
क्या होगा अगर हम सरणी का पता या सरणी का पता का पता मुद्रित
उन दोनों?
चलो यह एक की अनदेखी.
ठीक है. यह ठीक है. अब यह a.out / चल रहा है.
प्रिंटिंग सरणी, तो सरणी का पता मुद्रण, एक ही बात कर रहे हैं.
ऐरे बस मौजूद नहीं है.
यह जानता है कि जब आप सरणी मुद्रण कर रहे हैं, आप प्रतीक है कि उन 20 बाइट्स के लिए संदर्भित करता है मुद्रण कर रहे हैं.
मुद्रण सरणी का पता, अच्छी तरह से, सरणी नहीं मौजूद नहीं है.
यह पता नहीं है, तो यह सिर्फ उन 20 बाइट्स के पते प्रिंट है.
जैसे ही आप नीचे संकलन, अपने संकलित buggy4 में करना चाहते हैं / a.out,
सरणी nonexistent है.
सूचक मौजूद हैं. Arrays करना नहीं.
सरणी का प्रतिनिधित्व स्मृति के ब्लॉक अभी भी मौजूद हैं,
लेकिन चर सरणी और उस प्रकार के चर मौजूद नहीं है.
उन arrays और संकेत के बीच मुख्य अंतर की तरह कर रहे हैं
जैसे ही आप समारोह कॉल, वहाँ कोई अंतर नहीं है.
लेकिन समारोह में कहा कि सरणी ही घोषित किया जाता है के अंदर, sizeof अलग ढंग से काम करता है
जब से तुम प्रकार के आकार के बजाय ब्लॉक के आकार के मुद्रण कर रहे हैं,
और आप इसे बदल नहीं कर सकते हैं क्योंकि यह एक प्रतीक है.
मुद्रण और बात का पता बात एक ही बात प्रिंट.
और कहा कि यह बहुत सुंदर है.
[छात्र] आपको लगता है कि एक अधिक समय कह सकते हैं?
मैं कुछ याद किया हो सकता है.
मुद्रण और सरणी के सरणी पते एक ही बात प्रिंट,
जबकि अगर आप बनाम सूचक के पते एक सूचक प्रिंट,
एक बात आप क्या इशारा कर रहे हैं के पते प्रिंट,
अन्य ढेर पर सूचक के पते प्रिंट.
आप एक सूचक बदल सकते हैं, आप एक सरणी प्रतीक नहीं बदल सकते हैं.
और sizeof सूचक कि सूचक प्रकार के आकार को मुद्रित करने के लिए जा रहा है.
तो int * p sizeof (पी) 4 मुद्रित करने के लिए जा रहा है,
लेकिन int [5] सरणी प्रिंट sizeof (सरणी) 20 मुद्रित करने के लिए जा रहा है.
[छात्र] int [5] सरणी 20 मुद्रित करेगा? हाँ. >>
यह buggy4 के अंदर क्यों है जब यह sizeof (सरणी) के लिए इस्तेमाल किया जा
यह मैं <20 कर रहा था, जो नहीं है जो हम चाहते थे.
हम मैं <5 चाहते हैं. >> [छात्र] ठीक है.
[Bowden] और फिर जैसे ही आप कार्यों में गुजर शुरू,
अगर हमने किया int * p = सरणी;
इस समारोह के अंदर, हम मूल रूप से वास्तव में एक ही तरीके में पी और सरणी का उपयोग कर सकते हैं,
sizeof समस्या और बदलने में समस्या के लिए छोड़कर.
लेकिन p = 1 [0], [0] सरणी = 1 कह के रूप में एक ही है;
और जैसे ही हम (सरणी) foo कहते हैं, या foo (पी);
foo समारोह के अंदर, यह एक ही फोन में दो बार है.
इन दो कॉल के बीच कोई अंतर नहीं है.
>> उस पर हर कोई अच्छा? ठीक है.
हम 10 मिनट है.
>> हम इस हैकर टाइपकर्ता कार्यक्रम के माध्यम से प्राप्त करने की कोशिश करेंगे,
इस वेबसाइट है, जो पिछले साल या कुछ और बाहर आया.
यह सिर्फ होना चाहिए आप की तरह बेतरतीब ढंग से लिखें और इसे बाहर प्रिंट -
फ़ाइल जो कुछ भी यह करने के लिए भरी हुई है होता है कि यह क्या लगता है जैसे आप टाइप कर रहे हैं.
यह ऑपरेटिंग सिस्टम कोड के कुछ प्रकार की तरह लग रहा है.
यही कारण है कि हम क्या करने के लिए लागू करना चाहते हैं.
आप एक द्विआधारी hacker_typer नाम निष्पादन योग्य होना चाहिए
कि एक एकल तर्क में लेता है, फ़ाइल "हैकर प्रकार है."
निष्पादन योग्य रनिंग स्क्रीन स्पष्ट करना चाहिए
और फिर बाहर पारित में फाइल हर बार जब उपयोगकर्ता प्रेस एक कुंजी से एक चरित्र प्रिंट.
कुंजी जो आप प्रेस तो, इसे दूर फेंक और बजाय फ़ाइल से एक चरित्र प्रिंट चाहिए
कि तर्क है.
मैं बहुत ज्यादा बता बातें हम करने के लिए पता करने की आवश्यकता के लिए जा रहे हैं क्या कर रहे हैं.
लेकिन हम बाहर termios पुस्तकालय की जांच करना चाहते हैं.
मैं अपने पूरे जीवन में इस पुस्तकालय इस्तेमाल कभी नहीं किया है, तो यह बहुत कम उद्देश्य है.
लेकिन इस पुस्तकालय हम दूर फेंक करने के लिए उपयोग कर सकते हैं चरित्र तुम्हें मारा जा रहा है
जब आप अंदर मानक में टाइप कर रहे हैं
तो hacker_typer.c, और हम # शामिल करना चाहते करने के लिए जा रहे हैं.
Termios के लिए आदमी पृष्ठ पर देख रहे हैं - मैं यह टर्मिनल ओएस या कुछ अनुमान लगा -
मैं नहीं जानता कि यह कैसे पढ़ने के लिए.
इस पर देख रहे हैं, यह करने के लिए इन 2 फाइलें शामिल करने के लिए कहते हैं, तो हम ऐसा करेंगे.
>> पहली बात सबसे पहले, हम एक ही तर्क है, जो हम खोलने चाहिए फ़ाइल में ले जाना चाहता हूँ.
तो मैं क्या करना चाहते हैं? मैं देखना है कि मैं एक ही तर्क है जांच कैसे करूं?
[छात्र] यदि argc के बराबर होती है. >> [Bowden] हाँ.
तो अगर (= argc 2!) Printf ("उपयोग% [फ़ाइल खोलने के लिए] s").
तो अब अगर मैं एक दूसरा तर्क उपलब्ध कराने के बिना इस दौड़ - ओह, मैं नई लाइन की जरूरत है -
आप इसे उपयोग कहते हैं देखेंगे: / hacker_typer
और फिर दूसरा तर्क मैं फ़ाइल को खोलने के लिए करना चाहते हैं होना चाहिए.
अब मैं क्या करूँ?
मैं इस फ़ाइल से पढ़ने के लिए करना चाहते हैं. मैं कैसे एक फ़ाइल से पढ़ा है?
[छात्र] पहले आप इसे खोलने के लिए. >> हाँ.
तो fopen. Fopen कैसी दिखती है?
[छात्र] फ़ाइलनाम. >> [Bowden] फ़ाइलनाम argv [1] होने जा रहा है.
[छात्र] और फिर क्या आप इसके साथ क्या करना चाहते हैं, तो - >> [Bowden] हाँ.
तो अगर आप याद नहीं था, आप आदमी fopen सिर्फ कर सकता है,
, जहां यह एक const चार * पथ, जहां पथ फ़ाइल नाम है होने जा रहा है
const चार * मोड.
यदि आप मोड क्या है याद नहीं होगा, तो आप मोड के लिए देख सकते हैं.
आदमी पृष्ठों के अंदर, स्लैश चरित्र है क्या आप चीजों के लिए खोज करने के लिए उपयोग कर सकते हैं.
तो मैं / मोड मोड के लिए खोज करने के लिए लिखें.
n और एन कर रहे हैं कि तुम क्या खोज मेल के माध्यम से चक्र करने के लिए उपयोग कर सकते हैं.
यहाँ यह एक स्ट्रिंग तर्क मोड अंक कहते हैं
निम्न दृश्यों के साथ शुरू.
R तो, पढ़ने के लिए पाठ फ़ाइल खोलें. यही कारण है कि हम क्या करना चाहते हैं.
के लिए, पढ़ने, और मुझे लगता है कि संग्रहीत करना चाहते हैं.
बात करने के लिए एक फ़ाइल * होने जा रहा है. अब मैं क्या करना चाहते हैं?
मुझे एक दूसरी दे.
ठीक है. अब मैं क्या करना चाहते हैं?
[छात्र] जाँच करें अगर यह रिक्त है. >> [Bowden] हाँ.
किसी भी समय आप फ़ाइल खोलते हैं, तो सुनिश्चित करें कि आप को सफलतापूर्वक इसे खोलने में सक्षम हो.
>> अब मैं कि termios सामान करना चाहते हैं, जहां मैं पहले मेरे वर्तमान सेटिंग्स को पढ़ने के लिए चाहते हैं
और कुछ में उन लोगों को बचाने के लिए है, तो मैं अपनी सेटिंग्स बदलना चाहते हैं
दूर किसी भी चरित्र है कि मैं प्रकार फेंक,
और फिर मैं उन सेटिंग्स को अद्यतन करने के लिए करना चाहते हैं.
और फिर कार्यक्रम के अंत में, मैं अपने मूल सेटिंग्स को वापस बदलना चाहते हैं.
तो struct प्रकार termios जा रहा है, और मैं उन दोनों के जा रहा हूँ.
1 एक मेरे current_settings होने जा रहा है,
और फिर वे मेरे hacker_settings हो जा रहे हैं.
सबसे पहले, मैं करने के लिए मेरे वर्तमान सेटिंग्स को बचाने के लिए जा रहा हूँ,
तो मैं करने के लिए hacker_settings अद्यतन करना चाहते हैं के लिए जा रहा हूँ,
और फिर जिस तरह से अपने कार्यक्रम के अंत में, मैं वर्तमान सेटिंग्स वापस चाहते हैं.
तो वर्तमान सेटिंग्स को बचाने, तरीका है कि काम करता है, हम आदमी termios.
हम देखते हैं कि हम इस int tcsetattr, tcgetattr int है.
मैं अपने सूचक द्वारा termios struct में पारित.
जिस तरह से यह दिखेगा है - 've पहले से ही भूल समारोह में बुलाया गया था.
कॉपी और पेस्ट.
Tcgetattr तो, तो मैं struct में पारित करने के लिए है कि मैं जानकारी बचत कर रहा हूँ चाहते हैं,
जो current_settings होने जा रहा है,
और पहली बात मैं की विशेषताओं को बचाने के लिए फ़ाइल डिस्क्रिप्टर तर्क है.
फ़ाइल विवरणकर्ता क्या है किसी भी समय आप एक फ़ाइल खोलने की तरह है, यह एक फ़ाइल डिस्क्रिप्टर हो जाता है.
Fopen जब मैं argv [1], यह एक फ़ाइल डिस्क्रिप्टर जो आप संदर्भित कर रहे हो जाता है
जब भी आप पढ़ने के लिए या इसे लिखने के लिए करना चाहते हैं.
यह फ़ाइल डिस्क्रिप्टर मैं यहाँ का उपयोग करना चाहते हैं नहीं है.
वहाँ तीन फ़ाइल descriptors आप डिफ़ॉल्ट रूप से कर रहे हैं,
जो मानक में हैं, मानक बाहर, और मानक त्रुटि.
डिफ़ॉल्ट रूप से, मुझे लगता है कि यह है में मानक है 0, मानक बाहर 1 है, और मानक त्रुटि 2 है.
तो मैं क्या करने की सेटिंग में बदलाव करना चाहते हैं?
मैं जब भी मैं एक चरित्र हिट की सेटिंग को बदलना चाहते हैं,
मैं यह है कि चरित्र फेंक करने के लिए यह स्क्रीन करने के लिए मुद्रण के बजाय दूर करना चाहते हैं.
क्या मानक में मानक बाहर, या मानक त्रुटि धारा -
बातें करने के लिए जवाब है जब मैं कीबोर्ड पर लिखते हैं? >> [छात्र] >> हाँ अंदर मानक.
तो मैं या तो 0 करते हैं या कर सकते हैं मैं stdin कर सकते हैं.
मैं मानक के current_settings अंदर हो रही है
>> अब मैं उन सेटिंग्स को अद्यतन करने के लिए करना चाहते हैं,
तो पहले मैं hacker_settings मेरे current_settings क्या कर रहे हैं में कॉपी कर देंगे.
और कैसे structs काम है यह सिर्फ कॉपी जाएगा.
इस क्षेत्र के सभी प्रतियां, जैसा कि आप उम्मीद करेंगे.
>> अब मैं क्षेत्रों में से कुछ अद्यतन करने के लिए करना चाहते हैं.
Termios में देख रहे हैं, तो आप इस का एक बहुत माध्यम से पढ़ा होगा
बस देखने के लिए क्या आप के लिए देखना चाहता हूँ जाएगा,
लेकिन आप को देखने के लिए चाहते करने के लिए जा रहे हैं झंडे गूंज रहे हैं,
तो इको इनपुट वर्ण इको.
पहले मैं सेट करना चाहते हैं - 've पहले से ही भूल क्षेत्रों क्या कर रहे हैं.
यह है क्या struct की तरह लग रहा है.
इनपुट मोड तो मुझे लगता है कि हम बदलना चाहते हैं.
हम समाधान पर देखने के लिए यकीन है कि हम क्या करने के लिए बदलना चाहते हैं.
हम lflag बदलने के क्रम में इन सभी के माध्यम से देखने की जरूरत को रोकने के लिए करना चाहते हैं.
हम स्थानीय मोड बदलना चाहते हैं.
आप इस पूरे काम के माध्यम से पढ़ा है सब कुछ समझने के लिए जहां अंतर्गत आता है
कि हम बदलना चाहते हैं.
लेकिन यह स्थानीय मोड जहाँ हम करने के लिए बदलना चाहते हैं कि करने के लिए जा रहे हैं के अंदर है.
तो hacker_settings.cc_lmode है क्या यह कहा जाता है.
c_lflag.
यह वह जगह है जहाँ हम बिटवाइस ऑपरेटरों में मिलता है.
हम समय से बाहर की तरह कर रहे हैं, लेकिन हम यह असली जल्दी के माध्यम से जाना जाएगा.
यह वह जगह है जहां हम बिटवाइस ऑपरेटरों में मिलता है,
जहां मुझे लगता है कि मैं एक लंबे समय पहले कहा था कि, जब भी आप झंडे के साथ काम शुरू
आप एक बहुत bitwise ऑपरेटर का उपयोग करने के लिए होने जा रहे हैं.
झंडा में हर बिट व्यवहार के कुछ तरह से मेल खाती है.
तो यहाँ ध्वज, इस पर अलग अलग चीजें हैं, जहां उन सभी को कुछ अलग मतलब का एक गुच्छा है.
लेकिन मैं क्या करना चाहते हैं बस बंद सा है जो गूंज मेल खाती बारी.
तो बारी करने के लिए है कि बंद मैं & = ¬ गूंज.
दरअसल, मुझे लगता है कि यह techo या कुछ की तरह है. मैं सिर्फ फिर से जाँच करने के लिए जा रहा हूँ.
मैं इसे termios कर सकते हैं. यह सिर्फ गूंज है.
इको एक सा होने जा रहा है.
¬ इको मतलब है कि सभी बिट्स 1 पर सेट कर रहे हैं, जिसका अर्थ है सभी झंडे को सच करने के लिए सेट कर रहे हैं जा रहा है
ECHO बिट के लिए छोड़कर.
इस के साथ अपने स्थानीय झंडे को समाप्त करके, यह सभी झंडे का अर्थ है कि वर्तमान में सच करने के लिए सेट कर रहे हैं
अभी भी सच करने के लिए निर्धारित किया जाएगा.
अगर मेरे ECHO ध्वज को सही करने के लिए सेट कर दिया जाता है, तो यह जरूरी इको झंडे पर गलत है.
तो कोड की इस पंक्ति सिर्फ ECHO झंडा बदल जाता है.
कोड के अन्य लाइनों, मैं सिर्फ उन्हें समय के हित में नकल करेंगे और फिर उन्हें समझाने.
समाधान में, उन्होंने कहा 0.
यह शायद बेहतर करने के लिए स्पष्ट रूप से stdin कहना.
>> सूचना है कि मैं भी इको रहा हूँ कर रही है | ICANON यहाँ.
ICANON अलग कुछ, जो विहित मोड का मतलब है को संदर्भित करता है.
विहित मोड मतलब क्या आम तौर पर होता है जब आप कमांड लाइन टाइप कर रहे हैं,
में मानक कुछ नहीं प्रक्रिया है जब तक आप newline मारा.
तो जब आप GetString, आप चीजों की एक गुच्छा लिखते हैं, तो आप newline मारा.
कि जब यह अंदर मानक के लिए भेजा है
यह डिफ़ॉल्ट है.
जब मैं विहित मोड बारी, अब हर एक चरित्र आप प्रेस
है क्या संसाधित हो जाता है, जो आम तौर पर खराब की तरह है, क्योंकि यह इन बातों की प्रक्रिया धीमी है,
जो कारण है कि यह अच्छा है कि यह पूरे लाइनों में बफर.
लेकिन मैं प्रत्येक वर्ण संसाधित किया जा करने के लिए करना चाहते हैं
के बाद मैं यह मेरे लिए newline हिट करने के लिए प्रतीक्षा करने के लिए नहीं करना चाहती
पहले यह सभी वर्ण प्रक्रियाओं मैं टाइप किया गया है.
यह विहित मोड बदल जाता है.
यह सामान बस का अर्थ है जब यह वास्तव में वर्ण प्रक्रियाओं.
इसका मतलब यह है कि उन्हें तुरंत प्रक्रिया, जैसे ही मैं उन्हें टाइप कर रहा हूँ, उन्हें प्रक्रिया.
और इस समारोह में जो मानक के लिए मेरी सेटिंग्स में अद्यतन कर रहा है,
और TCSA का मतलब है इसे अभी.
अन्य विकल्पों जब तक सब कुछ है कि धारा पर वर्तमान है संसाधित है इंतज़ार कर रहे हैं.
यह वास्तव में कोई फर्क नहीं पड़ता.
अभी अभी मेरा सेटिंग होने के लिए जो कुछ भी वर्तमान hacker_typer_settings में बदल जाते हैं.
मुझे लगता है कि मैं यह hacker_settings कहा जाता है, तो हम है कि बदलने.
Hacker_settings के लिए सब कुछ बदलें.
>> अब हमारे कार्यक्रम के अंत में हम करने के लिए वापस जाना चाहते हैं के लिए जा रहे हैं
क्या वर्तमान में normal_settings के अंदर है,
जो सिर्फ normal_settings और की तरह लग रहा है.
सूचना मैं मेरे normal_settings के किसी भी मूल रूप से यह हो रही के बाद से नहीं बदला है.
तो सिर्फ उन्हें वापस बदलने के लिए, मैं उन्हें अंत में वापस गुजरती हैं.
यह अद्यतन किया गया था. ठीक है.
>> अब अंदर यहाँ मैं सिर्फ समय के हित में कोड समझाता हूँ.
ऐसा लगता है कि ज्यादा कोड नहीं है.
हम देखते हैं कि हम फ़ाइल से एक चरित्र को पढ़ने. हम इसे च बुलाया.
अब आप आदमी fgetc कर सकते हैं, लेकिन कैसे fgetc काम चल रहा है
सिर्फ यह चरित्र है कि तुम सिर्फ पढ़ा या EOF वापस जा रहा है,
जो फ़ाइल या कुछ त्रुटि हो रहा है के अंत से मेल खाती है.
हम पाशन, फ़ाइल से एक ही चरित्र को पढ़ने के लिए जारी कर रहे हैं,
जब तक हम बाहर वर्ण का भाग है पढ़ा है.
और जब तक हम कर रहे हैं कि, हम अंदर मानक से एक ही चरित्र पर इंतजार
हर बार जब आप कमांड लाइन पर कुछ लिखते हैं,
कि एक चरित्र में मानक से अंदर पढ़ रहा है
फिर putchar सिर्फ चार हम पढ़ा फ़ाइल से मानक बाहर करने के लिए यहाँ रखा जा रहा है.
आप आदमी putchar कर सकते हैं, लेकिन यह सिर्फ मानक के लिए बाहर रख रहा है, यह है कि चरित्र मुद्रण है.
आप भी सिर्फ printf कर सकता है ("% c", ग), समान विचार.
यह हमारे काम के थोक करने जा रहा है.
>> आखिरी बात हम करने के लिए करना चाहते हैं के लिए जा रहे हैं यह है सिर्फ हमारे फ़ाइल fclose.
यदि आप नहीं fclose, कि एक स्मृति रिसाव है.
हम हम मूल रूप से खोला फ़ाइल fclose चाहते हैं, और मुझे लगता है कि यह है.
अगर हम ऐसा करते हैं, मैं पहले से ही समस्याओं को मिला.
चलो देखते हैं.
यह क्या बारे में शिकायत नहीं की?
प्रकार 'struct _IO_FILE *' उम्मीद 'int' लेकिन तर्क है.
हम देखेंगे है कि अगर काम करता है.
केवल C99 में अनुमति दी. Augh. ठीक है, hacker_typer.
अब हम और अधिक उपयोगी वर्णन मिलता है.
तो अघोषित पहचानकर्ता 'normal_settings' के उपयोग करें.
मैं यह normal_settings फोन नहीं किया. मैं यह current_settings बुलाया.
तो चलो है कि सभी के बदलने के.
अब तर्क गुजर रहा है.
मैं अब के लिए इस 0 कर दूँगा.
ठीक है. /. Hacker_typer cp.c.
मैं भी शुरुआत में स्क्रीन स्पष्ट नहीं था.
लेकिन तुम वापस समस्या सेट देखने के लिए देखने के लिए कैसे आप स्क्रीन को साफ कर सकते हैं.
यह सिर्फ कुछ वर्ण मुद्रण
जबकि यह कर रहा है कि मैं क्या करना चाहते हैं.
ठीक है.
और क्यों इस 0 stdin के बजाय जरूरत के बारे में सोच रही है,
जो # 0 परिभाषित करना चाहिए,
यह शिकायत है कि -
पहले, जब मैंने कहा कि वहाँ फ़ाइल descriptors लेकिन फिर आप भी अपनी फ़ाइल *
एक फ़ाइल डिस्क्रिप्टर सिर्फ एक पूर्णांक है,
जबकि एक फ़ाइल * इसके साथ जुड़े सामान की एक पूरी गुच्छा है.
कारण है कि हम stdin के बजाय 0 कहने की ज़रूरत
है कि stdin एक फ़ाइल * जो बात यह है कि फ़ाइल 0 विवरणक संदर्भित है अंक है.
तो भी जब मैं fopen (argv [1], मैं एक फ़ाइल * वापस हो रही है.
लेकिन उस फ़ाइल * में कहीं उस फ़ाइल के लिए फ़ाइल डिस्क्रिप्टर करने के लिए इसी बात है.
यदि आप खोलने के लिए आदमी पृष्ठ पर देखो, इसलिए मुझे लगता है कि आप के आदमी 3 खुला करना होगा - नहीं -
2 आदमी खुला - हाँ.
यदि आप के लिए खुला पृष्ठ पर देखो, एक निचले स्तर के fopen की तरह खुला है,
और यह वास्तविक फ़ाइल डिस्क्रिप्टर लौट रहा है.
fopen खुला के शीर्ष पर सामान की एक गुच्छा करता है,
जो लौटने के बजाय सिर्फ इतना है कि संचिका विवरणक एक पूरी फ़ाइल * सूचक देता
अंदर जो हमारे छोटे फ़ाइल डिस्क्रिप्टर है.
तो मानक फ़ाइल * बात करने के लिए संदर्भित करता है,
जबकि 0 सिर्फ अपने आप में फ़ाइल डिस्क्रिप्टर मानक को संदर्भित करता है.
>> प्रश्न?
[हंसते हुए] के माध्यम से है कि विस्फोट से उड़ा दिया.
सही सभी. हम कर रहे हैं. [हंसते हुए]
>> [CS50.TV]