[Powered by Google Translate] [CS50 लाइब्रेरी]
[नैट Hardison] [हार्वर्ड विश्वविद्यालय]
[यह CS50 है. CS50.TV]
CS50 पुस्तकालय एक उपयोगी उपकरण है कि हम उपकरण पर स्थापित किया है
आपके लिए आसान कार्यक्रमों को लिखने के लिए करना है कि निवेश के लिए शीघ्र उपयोगकर्ताओं.
इस वीडियो में, हम वापस पर्दा खींच करेंगे और वास्तव में क्या CS50 पुस्तकालय में है देखो.
>> सी पुस्तकालयों पर वीडियो में, हम कैसे आप # हेडर फ़ाइलों में शामिल के बारे में बात करते हैं
अपने स्रोत कोड में पुस्तकालय की,
और फिर आप जोड़ने चरण के दौरान एक द्विआधारी पुस्तकालय फ़ाइल के साथ लिंक
संकलन की प्रक्रिया.
हेडर फाइल पुस्तकालय के इंटरफेस निर्दिष्ट.
यही है, वे संसाधनों के सभी कि पुस्तकालय उपलब्ध है आप का उपयोग करने के लिए विस्तार,
समारोह घोषणाओं, स्थिरांक, और डेटा प्रकार की तरह.
बाइनरी पुस्तकालय फ़ाइल पुस्तकालय के कार्यान्वयन शामिल है,
जो पुस्तकालय हेडर फाइल और पुस्तकालय ग स्रोत कोड फ़ाइलों से संकलित किया गया है.
>> द्विआधारी पुस्तकालय फ़ाइल को देखने के लिए के बाद से यह है, अच्छी तरह बाइनरी में बहुत दिलचस्प नहीं है.
तो चलो, लायब्रेरी के लिए शीर्ष बजाय फ़ाइलों पर एक नज़र रखना.
इस मामले में, वहाँ केवल एक हैडर cs50.h. नामक एक फाइल है
हम यह उपयोगकर्ता में स्थापित किया है निर्देशिका शामिल
साथ अन्य प्रणाली 'पुस्तकालयों हेडर फाइल के साथ.
>> पहली बातें तुम नोटिस हूँ कि cs50.h # अन्य पुस्तकालयों से हेडर फाइल शामिल हैं -
नाव, सीमा, मानक, bool, और मानक उदारीकरण.
फिर, पहिया बदलते नहीं के सिद्धांत के बाद,
हम CS0 उपकरण है कि हमारे लिए अन्य प्रदान का उपयोग पुस्तकालय का निर्माण किया है.
>> अगली बात तुम पुस्तकालय में देखेंगे यह है कि हम एक नए प्रकार को परिभाषित बुलाया "स्ट्रिंग"
इस लाइन वास्तव में सिर्फ चार * प्रकार के लिए एक उर्फ ​​बनाता है,
तो यह जादुई विशेषताओं के साथ नए स्ट्रिंग प्रकार रंगना नहीं करता
आमतौर पर अन्य भाषाओं में स्ट्रिंग वस्तुओं के साथ जुड़े,
ऐसे लंबाई के रूप में.
कारण है कि हम इस किया है के लिए रक्त का विवरण से नया प्रोग्रामर ढाल
संकेत की जब तक वे तैयार कर रहे हैं.
>> हेडर फाइल के अगले भाग के कार्यों की घोषणा
कि CS50 पुस्तकालय प्रलेखन के साथ प्रदान करता है.
यहाँ टिप्पणी में विस्तार के स्तर पर ध्यान दें.
इतना है कि लोगों को पता है कि कैसे इन कार्यों का उपयोग करने के लिए यह महत्वपूर्ण सुपर है.
हम बदले में घोषित, उपयोगकर्ता और वापसी chars, डबल्स, मंगाई, ints शीघ्र करने के लिए काम करता है,
लंबे समय चाहता है, और तार, हमारे अपने स्ट्रिंग प्रकार का उपयोग.
जानकारी छुपा के सिद्धांत के बाद,
हम एक अलग ग कार्यान्वयन फ़ाइल में डाल दिया है हमारी परिभाषा है - cs50.c -
उपयोगकर्ता स्रोत निर्देशिका में स्थित है.
हम जानते हैं कि फ़ाइल प्रदान की जाती है ताकि आप इसे पर एक नज़र ले जा सकते हैं,
इसे से सीखते हैं, और यदि आप चाहें तो इसे विभिन्न मशीनों पर recompile,
भले ही हमें लगता है कि यह इस वर्ग के लिए उपकरण पर काम करने के लिए बेहतर है.
वैसे भी, चलो इस पर एक नज़र अब ले.
>> getchar, GetDouble, GetFloat, GetInt, कार्यों और GetLongLong
सभी GetString समारोह के शीर्ष पर बनाया जाता है.
यह पता चला है कि वे सभी अनिवार्य रूप से एक ही पैटर्न का पालन करें.
वे एक समय पाश का उपयोग करने के लिए निवेश की एक लाइन के लिए उपयोगकर्ता prompt.
वे उपयोगकर्ता एक खाली पंक्ति आदानों अगर एक विशेष मूल्य वापसी.
वे उचित प्रकार के रूप में उपयोगकर्ता इनपुट पार्स करने का प्रयास है,
यह एक चार, एक डबल, एक नाव, आदि
और फिर वे या तो परिणाम वापस अगर इनपुट सफलतापूर्वक पार्स
या वे उपयोगकर्ता reprompt.
>> एक उच्च स्तर पर है, वहाँ वास्तव में मुश्किल नहीं है.
आप इसी तरह संरचित कोड लिखा है हो सकता है अपने आप को अतीत में.
शायद सबसे गुप्त दिखने हिस्सा sscanf कॉल कि उपयोगकर्ता इनपुट parses है.
Sscanf इनपुट प्रारूप रूपांतरण परिवार का हिस्सा है.
यह मानक io.h में रहता है, और अपने काम करने के लिए एक सी स्ट्रिंग को पार्स है,
एक विशेष प्रारूप के अनुसार, चर में पार्स परिणाम भंडारण
कॉल करने वाले व्यक्ति द्वारा प्रदान की गई है.
इनपुट प्रारूप रूपांतरण कार्यों के बाद से बहुत उपयोगी है, व्यापक रूप से इस्तेमाल किया कार्य कर रहे हैं
कि सहज सुपर पहली बार में नहीं कर रहे हैं,
हम पर जाने कैसे sscanf काम करता हूँ.
>> sscanf पहला तर्क एक चार * एक चरित्र के लिए एक सूचक है.
समारोह में ठीक से काम करने के लिए,
कि चरित्र एक सी स्ट्रिंग का पहला वर्ण होना चाहिए,
अशक्त \ 0 चरित्र के साथ समाप्त.
इस स्ट्रिंग को पार्स है
sscanf के लिए दूसरा तर्क एक प्रारूप स्ट्रिंग है,
आम तौर पर एक स्ट्रिंग निरंतर रूप में पारित कर दिया है,
और आप जब printf का उपयोग करने से पहले इस तरह से एक स्ट्रिंग देखा होगा.
प्रारूप स्ट्रिंग में एक प्रतिशत के संकेत रूपांतरण विनिर्देशक इंगित करता है.
चरित्र तुरंत एक प्रतिशत चिह्न के बाद,
सी प्रकार है कि हम चाहते हैं कि करने के लिए बदलने की sscanf इंगित करता है.
GetInt में, आप देख सकते हैं कि वहाँ एक% d और% ग है.
इसका मतलब यह है sscanf एक दशमलव int कि कोशिश करेंगे -% d और एक चार -% ग.
प्रारूप स्ट्रिंग में प्रत्येक रूपांतरण विनिर्देशक के लिए,
sscanf अपने तर्क सूची में एक इसी तर्क के बाद उम्मीद है.
तर्क है कि एक उचित टाइप स्थान पर बिंदु होगा
जिसमें रूपांतरण के परिणाम को स्टोर करने के लिए.
>> ऐसा करने का विशिष्ट तरीका sscanf फोन से पहले ढेर पर एक चर बनाने के लिए है
प्रत्येक आइटम के लिए कि आप स्ट्रिंग से पार्स चाहते हैं
एम्परसेंड - और तब पता ऑपरेटर का उपयोग करने के लिए संकेत पारित
sscanf कॉल करने के लिए उन चर.
आप देख सकते हैं कि GetInt में हम वास्तव में यह नहीं है.
Sscanf फोन से पहले ठीक है, हम एक n नामक int और ढेर पर एक चार कॉल ग की घोषणा
और हम sscanf कॉल में उन्हें करने के लिए संकेत गुजरती हैं.
ढेर पर इन चर लाना आवंटित अंतरिक्ष का उपयोग अधिक पसंद है
malloc साथ ढेर, क्योंकि आप malloc कॉल की भूमि के ऊपर से बचने पर,
और तुम स्मृति लीक के बारे में चिंता करने की ज़रूरत नहीं है.
एक प्रतिशत हस्ताक्षर नहीं prefixed वर्ण रूपांतरण प्रांप्ट नहीं.
बल्कि वे सिर्फ प्रारूप विनिर्देशन के लिए जोड़.
>> उदाहरण के लिए, अगर GetInt में प्रारूप स्ट्रिंग एक% d बजाय थे
sscanf पत्र एक के बाद एक int के लिए लग रही होगी,
जबकि यह int परिवर्तित करने का प्रयास करेंगे, यह एक के साथ कुछ नहीं करना होगा.
इस के लिए एकमात्र अपवाद रहितसफेद है.
प्रारूप स्ट्रिंग में सफेद स्थान अक्षर खाली स्थान के किसी भी राशि के मैच
सब पर भी कोई नहीं.
तो, यही कारण है कि टिप्पणी अग्रणी और / या रहितसफेद अनुगामी संभवतः के साथ उल्लेख है.
तो, इस बिंदु यह हमारे sscanf कॉल की तरह लग रहा है पर उपयोगकर्ता इनपुट स्ट्रिंग को पार्स की कोशिश करेंगे
संभव अग्रणी रहितसफेद के लिए जाँच करके,
एक int है कि परिवर्तित हो जाएगा और int चर n में संग्रहीत द्वारा पीछा
खाली स्थान के कुछ राशि के द्वारा पीछा किया, और एक चरित्र के बाद
चार चर ग में संग्रहीत.
>> वापसी मूल्य के बारे में क्या?
Sscanf शुरू से इनपुट रेखा पार्स करने के लिए खत्म हो जाएगा,
जब यह अंत तक पहुँच रोक या जब इनपुट में एक चरित्र
मेल नहीं खाता है या नहीं एक प्रारूप चरित्र जब यह एक रूपांतरण नहीं कर सकते हैं.
यह वापसी मान एकल जब इसे बंद कर दिया करने के लिए प्रयोग किया जाता है.
यदि इसे बंद कर दिया है, क्योंकि यह इनपुट स्ट्रिंग के अंत तक पहुँच
कोई भी परिवर्तन करने से पहले और प्रारूप स्ट्रिंग का हिस्सा मैच में नाकाम रहने से पहले,
तो विशेष लगातार EOF वापस आ रहा है.
अन्यथा, यह सफल रूपांतरणों की संख्या देता है,
जो 0, 1, 2 या होगा, क्योंकि हम दो रूपांतरण के लिए कहा है.
हमारे मामले में, हम सुनिश्चित करें कि उपयोगकर्ता एक int और केवल एक int में टाइप करना चाहते हैं.
>> तो, हम sscanf 1 वापस जाने के लिए करना चाहते हैं. क्यों देखें?
यदि sscanf 0 लौटे, तो कोई रूपांतरण बना रहे थे,
तो उपयोगकर्ता इनपुट के शुरुआत में एक int के अलावा अन्य कुछ टाइप.
यदि sscanf 2 देता है, तो उपयोगकर्ता इसे ठीक लिखें इनपुट के शुरुआत में में,
लेकिन वे तो बाद में कुछ गैर रहितसफेद चरित्र में टाइप
% ग के बाद रूपांतरण सफल रहा.
वाह, कि एक समारोह कॉल के लिए एक काफी लंबा विवरण है.
वैसे भी, अगर आप sscanf और उसके भाई बहन के बारे में अधिक जानकारी चाहते हैं,
आदमी पृष्ठों, गूगल, या दोनों की जाँच करें.
प्रारूप स्ट्रिंग विकल्पों में से बहुत सारे हैं,
और ये आप शारीरिक श्रम का एक बहुत बचाने के लिए जब सी. में तार व्याकरण के नियमों के अनुसार या व्याकरण सम्मत (शब्द की) व्याख्या करना करने की कोशिश कर रहा है कर सकते हैं
>> पुस्तकालय में समापन समारोह को देखने के GetString है.
यह पता चला है कि GetString एक मुश्किल कार्य ठीक तरह से लिखना है,
भले ही यह एक ऐसी सरल, आम काम की तरह लगता है.
ऐसा क्यों मामला है?
ठीक है, हम करने के लिए लाइन की दुकान कैसे जा रहे हैं के बारे में सोचते हैं कि अंदर उपयोगकर्ता प्रकार
चूंकि एक स्ट्रिंग chars के एक दृश्य है,
हम ढेर पर एक सरणी में संग्रहीत करने के लिए चाहते हो सकता है,
लेकिन हम जानते हैं कितनी देर तक सरणी के लिए होने जा रहा है जब हम यह घोषणा की आवश्यकता होगी.
इसी तरह, अगर हम यह ढेर पर डाल करना चाहते हैं,
हम malloc बाइट्स की संख्या हम आरक्षित करने के लिए चाहते हैं पारित करने की आवश्यकता है,
लेकिन यह असंभव है.
हमें पता नहीं कितने chars उपयोगकर्ता में टाइप करेंगे
पहले उपयोगकर्ता वास्तव में उन्हें टाइप करता है.
>> इस समस्या के लिए एक सरल समाधान के लिए अंतरिक्ष का एक बड़ा हिस्सा सुरक्षित रखते हैं, कहते हैं,
उपयोगकर्ता इनपुट के लिए 1000 वर्ण की एक ब्लॉक,
यह सोचते हैं कि उपयोगकर्ता एक स्ट्रिंग में लंबे समय तक कभी नहीं टाइप करेंगे.
यह दो कारणों के लिए एक बुरा विचार है.
पहले यह सोचते हैं, कि उपयोगकर्ताओं को आम तौर पर तार में है कि लंबे समय से नहीं लिखें,
आप स्मृति का एक बहुत बर्बाद कर सकता है.
आधुनिक मशीनों पर, यह एक मुद्दा नहीं हो सकता है अगर तुम यह कर सकता है
एक या दो अलग मामलों में,
लेकिन अगर आप एक पाश में उपयोगकर्ता इनपुट ले जा रहे हैं और बाद में उपयोग के लिए भंडारण,
आप जल्दी से स्मृति की एक टन सोख सकता है.
इसके अलावा, अगर कार्यक्रम आप लिख रहे हैं एक छोटे से कंप्यूटर के लिए है -
एक smartphone या सीमित स्मृति के साथ कुछ और तरह से एक डिवाइस -
इस समाधान समस्या बहुत तेजी से हो जाएगा.
दूसरा, और अधिक गंभीर कारण यह नहीं करना है कि यह अपने कार्यक्रम पत्ते कमजोर
क्या एक बफर अतिप्रवाह हमले करने के लिए कहा जाता है.
प्रोग्रामिंग में, एक बफर स्मृति के लिए अस्थायी रूप से इनपुट या आउटपुट डेटा स्टोर करने के लिए इस्तेमाल किया है,
जो इस मामले में हमारे 1000-चार ब्लॉक है.
एक बफर अतिप्रवाह तब होता है जब डेटा ब्लॉक के अंत अतीत लिखा है.
>> उदाहरण के लिए, यदि कोई उपयोगकर्ता वास्तव में 1000 से अधिक वर्ण में टाइप करता है.
आप इस अनुभव हो सकता है गलती से जब arrays के साथ प्रोग्रामिंग.
यदि आप 10 ints की एक सरणी है, तुम्हें कुछ पढ़ने या लिखने की कोशिश कर रहा से रोकता है
15 int.
वहाँ कोई संकलक चेतावनियाँ या त्रुटियाँ हैं.
कार्यक्रम बस सीधे आगे भूलों और स्मृति accesses
जहां यह सोचता है कि 15 int हो सकता है, और यह अपने अन्य चर अधिलेखित कर सकते हैं.
सबसे खराब स्थिति में, आप आंतरिक अपने कार्यक्रम के कुछ अधिलेखित कर सकते हैं
नियंत्रण तंत्र, अपने कार्यक्रम के कारण वास्तव में अलग अलग निर्देशों पर अमल करने के लिए
की तुलना में आप का इरादा.
>> अब, यह इस गलती करने के लिए आम नहीं है,
लेकिन यह एक काफी आम तकनीक है कि बुरे लोगों के लिए कार्यक्रमों को तोड़ने उपयोग
और अन्य लोगों के कंप्यूटरों पर दुर्भावनापूर्ण कोड डाल दिया.
इसलिए, हम सिर्फ हमारे अनुभवहीन समाधान का उपयोग नहीं कर सकते हैं.
हम कमजोर होने से हमारे कार्यक्रम को रोकने के लिए एक तरह की जरूरत है
एक बफर अतिप्रवाह हमले.
ऐसा करने के लिए, हम यह सुनिश्चित करें कि हमारे बफर के रूप में हम पढ़ विकसित कर सकते हैं बनाने की जरूरत है
उपयोगकर्ता से अधिक इनपुट.
हल क्या है? हम एक ढेर आवंटित बफर का उपयोग करें.
चूंकि हम आकार परिवर्तन कर सकते हैं यह का आकार परिवर्तन realloc समारोह का उपयोग कर,
और हम दो संख्याओं का ट्रैक रखने के बफर में अगले खाली स्लॉट के सूचकांक
और लंबाई या बफर की क्षमता.
हम एक fgetc समारोह का उपयोग कर समय पर एक उपयोगकर्ता से अक्षरों में पढ़ा.
तर्क fgetc समारोह लेता है - stdin मानक इनपुट स्ट्रिंग के लिए एक संदर्भ है,
है है जो एक preconnected इनपुट चैनल कि उपयोगकर्ता इनपुट के हस्तांतरण करने के लिए प्रयोग किया जाता है
टर्मिनल से कार्यक्रम के लिए.
>> जब भी एक नए चरित्र में उपयोगकर्ता प्रकार, हम देखने के लिए जाँच अगर सूचकांक
अगले मुक्त स्लॉट के प्लस 1 बफर की क्षमता से अधिक है.
एक है क्योंकि अगर अगले मुक्त सूचकांक 5 में आता है,
तो हमारे बफर लंबाई 6 0 अनुक्रमण के लिए धन्यवाद किया जाना चाहिए.
अगर हम अंतरिक्ष के बाहर बफर में भाग लिया है, तो हम इसे आकार करने का प्रयास करते हैं,
यह इतना है कि हम बार की संख्या पर नीचे कट है कि हम का आकार बदलने के दोहरीकरण
यदि उपयोगकर्ता एक बहुत लंबी स्ट्रिंग में टाइप है.
यदि स्ट्रिंग बहुत लंबा हो गया है या अगर हम ढेर स्मृति से बाहर चलाने के,
हम हमारी बफर और वापसी अशक्त मुक्त.
>> अंत में, हम बफर करने के लिए चार संलग्न.
एक बार जब उपयोगकर्ता हिट दर्ज करें या लौटने के लिए, एक नई लाइन संकेत
या विशेष चार - नियंत्रण घ - जो इनपुट के अंत का संकेत है,
हम देखने के लिए अगर उपयोगकर्ता वास्तव में सब पर कुछ भी टाइप करने के लिए जांच करते हैं.
यदि नहीं, तो हम अशक्त लौट आते हैं.
अन्यथा, क्योंकि हमारे बफर है शायद बड़ा की तुलना में हम की जरूरत है,
सबसे खराब स्थिति में यह लगभग दो बार के रूप में बड़े रूप में हम की जरूरत है
क्योंकि हम हर बार हम का आकार बदलने के डबल,
हम सिर्फ अंतरिक्ष की राशि की जरूरत है कि हम का उपयोग स्ट्रिंग की एक नई प्रतिलिपि बनाते हैं.
हम malloc कॉल करने के लिए एक अतिरिक्त 1 जोड़ने के लिए,
\ 0, इतना है कि वहाँ विशेष अशक्त टर्मिनेटर चरित्र के लिए जगह है
जो हम स्ट्रिंग संलग्न करने के लिए एक बार हम पात्रों के बाकी हिस्सों में कॉपी,
strcpy के बजाय strncpy का उपयोग
इतना है कि हम निर्दिष्ट कर सकते हैं कि हम वास्तव में कितने घर का काम करने के लिए प्रतिलिपि बनाना चाहते हैं.
Strcpy प्रतियां जब तक यह एक \ 0 हिट.
तो फिर हम अपने बफर मुक्त और फोन करने के लिए प्रतिलिपि वापसी.
>> कौन जानता था कि इस तरह के एक सरल प्रतीयमान समारोह इतना जटिल हो सकता है?
अब तुम्हें पता है क्या CS50 पुस्तकालय में चला जाता है.
>> मेरा नाम नैट Hardison है, और इस CS50 है.
[CS50.TV]