[Powered by Google Translate] [القسم 5 - أكثر راحة] [روب بودين - جامعة هارفارد] [هذا CS50. - CS50.TV] كما قلت في البريد الإلكتروني الخاص بي، وهناك الكثير من الأشياء التي يمكنك استخدام غير الأجهزة للقيام في الواقع مجموعات المشكلة. ننصحك القيام بذلك في الجهاز لمجرد ثم يمكننا بسهولة أكبر مساعدتك ونحن نعرف كيف أن كل شيء هو الذهاب إلى العمل. ولكن وعلى سبيل المثال من حيث يمكنك أن تفعل أشياء إذا، مثلا، لم يكن لديك الوصول إلى الأجهزة أو كنت ترغب في العمل في الطابق السفلي مركز العلوم - التي في الواقع لديهم الجهاز أيضا - إذا كنت ترغب في العمل في أي مكان. ولقد مثال واحد هل رأيت / سمعت من SSH؟ SSH هو في الأساس مثل الاتصال شيئا. في الواقع، الآن أنا SSHed I في الجهاز. أنا لا يعملون مباشرة في الجهاز. هنا هو الأجهزة، وإذا نظرتم إلى هنا ترى هذا العنوان IP. أنا لا تعمل في الأجهزة نفسها؛ I تأتي دائما على لنافذة / محطة iTerm2. يمكنك SSH إلى ذلك العنوان IP، سه jharvard@192.168.129.128. أتذكر هذا العدد بسهولة جدا لأنه مثل هذا النمط لطيفة. ولكن ذلك تسألني عن كلمة السر الخاصة بي، والآن أنا في الجهاز. في الأساس، وعند هذه النقطة، إذا فتحت لك حتى محطة داخل الجهاز نفسه، هذه الواجهة، ولكن كنت استخدامها، هو بالضبط نفس واجهة أنا باستخدام أكثر من هنا ولكن الآن كنت SSHed لك. لم يكن لديك لSSH إلى الجهاز. مثال واحد من مكان آخر هل يمكن لSSH هو أنا متأكد من أن يكون لديك افتراضيا - اه. أكبر. يجب أن يكون لديك كل من حسابات FAS الافتراضية على خوادم FAS. بالنسبة لي، وأود أن SSH لrbowden@nice.fas.harvard.edu. انها سوف أطلب منكم أن أول مرة، وكنت أقول نعم. كلمة السر هو مجرد الذهاب الى تكون كلمة المرور الخاصة بي FAS. وحتى الآن، وأنا SSHed الأول للخوادم لطيفة، وأستطيع أن أفعل ما أريد هنا. وهناك الكثير من الفئات التي قد تتخذ، مثل 124، ستكون لدينا لتقوم بتحميل الاشياء هنا أن يقدم في الواقع مجموعات مشكلتك. ولكنهم يقولون لم يكن لديك الوصول إلى الأجهزة الخاصة بك. ثم يمكنك أن تفعل أشياء، مثل أن يقول هنا سوف - هذا هو مجرد قسم من الأسئلة. سوف يطلب منك القيام بذلك في الجهاز. بدلا من ذلك سأفعل فقط على الملقم. انا ذاهب الى بفك ذلك. المشكلة ستكون ان كنت تستخدم لاستخدام شيء من هذا القبيل gedit أو أيا كان داخل الجهاز. كنت لن يكون هذا على الخادم FAS. كل شيء يحدث لمجرد أن يكون واجهة هذا النصية. لذلك يمكن أن أي واحد، في محاولة لمعرفة محرر النص الذي لديهم. لديهم نانو. نانو عادة ما يكون من السهل جدا للاستخدام. يمكنك استخدام الأسهم الخاصة بك واكتب عادة. ولهذا ليس من الصعب. إذا كنت ترغب في الحصول على يتوهم حقا يمكنك استخدام إيماكس، وأنا ربما لا ينبغي وقد فتحت لأنني لا أعرف حتى كيفية إغلاق ايماكس. السيطرة X، C التحكم؟ نعم. أو يمكنك استخدام فيم، وهو ما يمكنني استخدام. وهكذا تلك هي الخيارات المتاحة أمامك. إذا كنت لا تريد أن تفعل ذلك، يمكنك أيضا، إذا نظرتم manual.cs50.net-- اه. على جهاز كمبيوتر، يمكنك استخدام المعجون SSH، الذي أنت ذاهب لدينا لتحميل بشكل منفصل. في نظام التشغيل Mac، يمكنك فقط عن طريق استخدام الطرفية الافتراضية أو يمكنك تحميل iTerm2، الذي هو مثل المحطة الطرفية، لطيفة الهوى. إذا ذهبت إلى manual.cs50.net سترى تصل إلى المفكرة + +، وهو ما يمكنك استخدامها على جهاز الكمبيوتر. فإنه يتيح لك SFTP من المفكرة + +، والذي هو في الأساس SSH. ما هذا سيتيح لك القيام به هو تحرير الملفات محليا، ثم كلما كنت ترغب في حفظها، سيوفر لnice.fas، حيث يمكنك تشغيل بعد ذلك. وتعادل على ماك سيكون TextWrangler. ذلك أنه يتيح لك أن تفعل الشيء نفسه. فإنه يتيح لك تحرير ملفات محليا وحفظها على nice.fas، حيث يمكنك تشغيل بعد ذلك. لذلك إذا كنت عالقة دون أي وقت مضى كنت الأجهزة، لديك هذه الخيارات لا يزال لقيام مجموعات مشكلتك. مشكلة واحدة ستكون أنك لن يكون لها مكتبة CS50 لأن nice.fas لا يكون هذا افتراضيا. يمكنك تحميل أي مكتبة CS50 - أنا لا أعتقد أنني بحاجة أن في هذه المرحلة. يمكنك تحميل أي مكتبة CS50 ونسخه لأكثر من nice.fas، أو أعتقد في هذه المرحلة أننا لا تستخدم بعد الآن على أي حال. أو إذا فعلنا ذلك، يمكنك في الوقت الراهن استبدالها وتطبيقات وظائف في مكتبة CS50 على أي حال. لذلك ينبغي أن لا يكون ذلك الكثير من القيود. وهذا هو ذلك. سوف أعود إلى الأجهزة الآن، ونحن سوف نبذل كل ما في الجهاز. أبحث في قسم من الأسئلة، في البداية، كما قلت في البريد الإلكتروني الخاص بي، علينا أن نتحدث عن واحدة قصيرة وكان من المفترض لك مشاهدة. لدينا إعادة توجيه وأنابيب وهذه الأسئلة الثلاثة. التي لا وظائف مثل تيار الكتابة printf بشكل افتراضي؟ لذلك الدفق. ما هو تيار؟ وهناك تيار هو في الأساس مثل انها مجرد بعض - انها ليست حتى مصدرا لل1s و 0s. تيار انها تطلب من هنا القياسية. وخارج ذلك المعيار هو تيار أنه عند الكتابة إليه، يظهر على الشاشة. من معيار، عن طريق تيار، فهذا يعني أنك مجرد كتابة 1s و 0s إليها، وعلى الطرف الآخر من خارج للتو من قراءة القياسية التي تيار. انها مجرد سلسلة من 1s و 0s. يمكنك الكتابة إلى تيارات أو يمكنك قراءتها من تيارات اعتمادا على ما هو في الواقع تيار. تيارات أخرى الافتراضي هما المعيار في والخطأ المعياري. هو المعيار في GetString كلما كان ذلك، فإنه في انتظاركم لإدخال الاشياء. لذلك في انتظاركم، انها تنتظر في الواقع على مستوى في، الذي هو في الحقيقة ما تحصل عليه عند كتابة على لوحة المفاتيح. كنت تكتب في مستوى الدخول. الخطأ هو معيار يعادل أساسا إلى خارج القياسية، ولكن هذا المتخصصة في أنه عند الطباعة إلى الخطأ المعياري، كنت من المفترض أن طباعة رسائل الخطأ فقط لأنه حتى تتمكن من التمييز بين الرسائل العادية المطبوعة إلى الشاشة مقابل رسائل الخطأ اعتمادا على ما إذا ذهبوا إلى خارج القياسية أو الخطأ المعياري. الملفات أيضا. من معيار، ومعيار في، والخطأ المعياري هي تيارات خاص فقط، ولكن في الحقيقة أي ملف، عند فتح الملف، فإنه يصبح من تيار بايت حيث يمكنك قراءة فقط من ان تيار. لك، بالنسبة للجزء الأكبر، يمكن مجرد التفكير في ملف باسم دفق من وحدات البايت. حتى تيارات ماذا يكتبون بشكل افتراضي ل؟ من معيار. ما هو الفرق بين> و >>؟ لم أي شخص مشاهدة الفيديو مسبقا؟ حسنا. > ستكون كيفية إعادة توجيه إلى ملفات، ويجري أيضا >> لإعادة توجيه الإخراج إلى ملف، لكنه سيحتاج بدلا من ذلك إلى إلحاق الملف. على سبيل المثال، دعونا نقول I يحدث لديها ديكت هنا، والاشياء فقط داخل ديكت هو القط، والقط، والكلب، والأسماك، والكلب. أمر واحد أن لديك في سطر الأوامر هو القط، الذي هو مجرد الذهاب لطباعة ما في ملف. لذلك عندما أقول ديكت القط، انه سيكون لطباعة القط، والقط، والكلب، والأسماك، والكلب. هذا كل ما يفعل القط. وهذا يعني أنه طبع في التمتع بها، والقط القط، والكلب، والكلب، والأسماك. إذا كنت أريد أن بدلا من ذلك لإعادة توجيه إلى ملف، يمكن استخدام> وتوجيهها إلى ما هو الملف. سأتصل الملف الملف. حتى الآن إذا كنت ليرة سورية، سوف أرى ولدي ملف جديد يسمى الملف. وإذا كنت فتحه، انها ستكون لدينا بالضبط ما وضع القط في سطر الأوامر. حتى الآن إذا فعلت ذلك مرة أخرى، ثم انه سيكون لإعادة توجيه الإخراج إلى ملف، وانا ذاهب لنفس الشيء بالضبط. من الناحية الفنية كان الأمر كذلك، فإنه تجاهلت تماما ما كان لدينا. وأخذت سنرى إذا قمت بتغيير DICT، من كلب. الآن إذا كنا القط ديكت إلى الملف مرة أخرى، ونحن ستكون لدينا النسخة الجديدة مع الكلب إزالتها. لذلك يتجاوز تماما. بدلا من ذلك، إذا كان لنا أن استخدام >>، انه سيكون لإلحاق الملف. الآن، وفتح ملف، ونحن نرى لدينا فقط الشيء نفسه طبع مرتين لأنه كان هناك مرة واحدة، فإننا إلحاق الأصلي. بحيث هو ما> و>> تفعل. لا تسأل واحد القادم - لا تسأل عن ذلك. الآخر هو أن لدينا <، والتي إذا> الموجهات خارج القياسية، <سوف يتم إعادة توجيه القياسية فيها. دعونا نرى ما اذا كان لدينا مثال على ذلك. لا أستطيع كتابة واحدة سريعة الحقيقي. دعونا نلقي أي ملف، hello.c. ملف بسيط نسبيا. أنا مجرد الحصول على سلسلة ثم طباعة "مرحبا" مهما كانت سلسلة دخلت فقط كان. لذلك ومن ثم مرحبا / مرحبا. الآن انها دفع لي لدخول شيء، وهو ما يعني انها تنتظر على الأشياء التى يمكن إدخالها في مستوى الدخول. أدخل ذلك كل ما أريد في معيار. ونحن ذاهبون فقط أن أقول مرحبا، روب! ثم انها الطباعة إلى مستوى من مرحبا، روب! إذا كنت تفعل / مرحبا ثم إعادة توجيه، في الوقت الحالي يمكنك إعادة توجيه فقط من ملف. إذا كان الأمر كذلك وضعت في بعض الملفات، النص، وأضع روب، إذا قمت بتشغيل مرحبا ثم إعادة توجيه الملف إلى TXT / مرحبا، انه سيكون ليقول مرحبا، روب! على الفور. عندما يحصل أول من GetString وانها في انتظار القياسية في، القياسية في انتظار لم يعد على لوحة المفاتيح للحصول على بيانات عن دخل. بدلا من ذلك، لقد كنا توجيه القياسية في القراءة من ملف TXT. وذلك انه سيكون لقراءة النص من ملف، الذي هو مجرد روب الخط، ثم انه سيكون لطباعة مرحبا، روب! وإذا أردت، يمكن أن أفعل أيضا. / مرحبا لديك 2>، هذا ما إعادة توجيه الخطأ القياسي. إذا كان الأمر كذلك ما ذهب إلى الخطأ المعياري، لن تحصل على موضع txt2. ولكن لاحظ إذا كنت تفعل 2>، ثم انها لا تزال تطبع مرحبا، روب! إلى سطر الأوامر لأنني فقط إعادة توجيه الخطأ القياسي، وأنا لا إعادة توجيه القياسية بها. الخطأ المعياري وخارج معيار مختلفة. إذا أردت الكتابة فعلا إلى الخطأ المعياري، ثم أنا يمكن أن تغيير هذا أن يكون fprintf إلى stderr. printf ذلك، افتراضيا، يطبع لمن معيار. إذا كنت ترغب في الطباعة إلى الخطأ المعياري يدويا، ثم لا بد لي من استخدام fprintf وتحديد ما أريد لطباعة ل. إذا فعلت بدلا STDOUT fprintf، ثم وهذا ما يعادل في الأساس إلى printf. لكن fprintf إلى الخطأ المعياري. حتى الآن، إذا كنت إعادة توجيه ذلك في txt2، مرحبا، روب! لا يزال الحصول على المطبوعة في سطر الأوامر منذ أن الحصول على طباعته إلى الخطأ المعياري وأنا فقط إعادة توجيه القياسية بها. إذا كنت إعادة توجيه الخطأ القياسي الآن، والآن لم يحصل ذلك المطبوعة، وtxt2 سيكون مرحبا، روب! حتى الآن، يمكنك طباعة الأخطاء الفعلية الخاصة بك إلى الخطأ المعياري وطباعة الرسائل العادية لمن معيار. وذلك عندما قمت بتشغيل البرنامج، يمكنك تشغيله كما. / مرحبا هذا النوع مع 2> بحيث البرنامج هو الذهاب الى تشغيل عادة، ولكن يمكن لأي رسائل الخطأ التي تحصل تحقق لاحقا في سجل خطأ الخاص بك، حتى الأخطاء، وبعد ذلك ننظر في وقت لاحق والخاص أخطاء سيكون لها أي ملف الأخطاء التي حدث. الأسئلة؟ آخر واحد هو الأنابيب، التي يمكن ان يخطر لك عن اتخاذ معيار الخروج من أمر واحد وجعله في مستوى من الأمر التالي. مثال هنا هو صدى لأمر سطر الأوامر أن مجرد الذهاب إلى صدى مهما وضعت وحجتها. وأنا لن تضع علامات الاقتباس. صدى بلاه، بلاه، بلاه هو مجرد الذهاب لطباعة بلاه، بلاه، بلاه. من قبل، أنا عندما قلت أن نضع روب في ملف TXT لأنني لا يمكن إعادة توجيه ملفات TXT فقط، بدلا من ذلك، / لو كنت أردد روب ومن ثم فإنه في الأنابيب. / مرحبا، من شأنها أن تفعل أيضا نفس النوع من الشيء. هذا مع الأخذ في إخراج هذا الأمر، صدى روب، واستخدامه كمدخل ل/ مرحبا. يمكنك التفكير في الأمر على النحو توجيه 1 صدى روب في ملف ومن ثم الإسهام في / مرحبا هذا الملف الذي أنتج فقط. لكنه يأخذ الملف المؤقت خارج الصورة. الأسئلة على ذلك؟ والسؤال التالي هو الذهاب إلى إشراك هذه. يمكن استخدام خط أنابيب ما للعثور على عدد من أسماء فريدة في ملف يسمى names.txt؟ الأوامر ونحن في طريقنا إلى هنا تريد استخدام فريدة من نوعها، UNIQ بذلك، ومن ثم مرحاض. يمكنك القيام UNIQ الرجل للنظر فعلا في ما أن يفعل، وانه سيكون فقط لتصفية المجاورة خطوط مطابقة من المدخلات. والإنسان هو الذهاب الى الحمام طباعة السطر الجديد، وورد، وعدد وحدات بايت لكل ملف. وآخر ونحن في طريقنا إلى الرغبة في استخدام هو نوع، الذي هو الذهاب الى مجرد نوع من خطوط ملف TXT. إذا قمت بعمل بعض الملفات TXT، names.txt، وانها روب، تومي، جوزيف، تومي، جوزيف، RJ، روب، ما أريد أن أفعله هنا هو العثور على عدد من أسماء فريدة في هذا الملف. ذلك ما ينبغي أن يكون الجواب؟ >> [طالب] (4). نعم >>. يجب أن يكون 4 منذ روب، تومي، جوزيف، RJ هي أسماء فريدة من نوعها فقط في هذا الملف. الخطوة الأولى، إذا كنت تفعل فقط على عدد الكلمات names.txt، هذا في الواقع هو قول لي كل شيء. هذا هو في الواقع الطباعة - دعونا نرى، رجل حمامات - الأسطر الجديدة، والكلمات، وعدد البايت. إذا كنت لا يهتمون إلا خطوط، ثم يمكنني أن أفعل فقط WC-L names.txt. ذلك أن الخطوة 1. لكنني لا أريد أن WC-L names.txt لأن names.txt يحتوي على جميع الأسماء فقط، وأريد أن تصفية أي منها غير فريد. حتى لو كنت تفعل UNIQ names.txt، التى لا تعطى لي تماما ما أريد لأن أسماء مكررة لا تزال هناك. لماذا؟ لماذا لا تفعل UNIQ ما أريد؟ [طالب] التكرارات ليست (غير مسموع) >> نعم. تذكر الصفحة الرجل ليقول UNIQ تصفية خطوط مطابقة المجاورة. انهم ليسوا المجاورة، لذلك لن تصفية لهم. إذا كنت فرزها الأولى، names.txt نوع هو الذهاب الى وضع جميع خطوط مكررة معا. حتى الآن هو أن names.txt نوع. انا ذاهب الى أن ترغب في استخدام كإدخال لUNIQ، وهو | UNIQ. أن يعطيني جوزيف، RJ، روب، تومي، وأريد أن استخدام هذا كمدخل لWC-L، التي سوف تعطيني 4. مثل ذلك يقول هنا، يمكن استخدام خط أنابيب ما؟ يمكنك أن تفعل الكثير من الأشياء مثل استخدام سلسلة من الأوامر حيث يمكنك استخدام الإخراج من أمر واحد كإدخال إلى الأمر التالي. يمكنك أن تفعل الكثير من الأشياء، والكثير من الأشياء ذكية. الأسئلة؟ حسنا. هذا كل شيء للأنابيب وإعادة التوجيه. الآن نذهب إلى الأشياء الفعلية، والاشياء الترميز. داخل هذا PDF، سترى هذا الأمر، وسوف تحتاج إلى تشغيل هذا الأمر في الأجهزة الخاصة بك. مجلد مشترك هو الأمر لمجرد الحصول على شيء من الإنترنت، في الأساس، وحتى مجلد مشترك URL هذا. إذا ذهبت إلى هذا URL في المستعرض الخاص بك، فإنه تحميل هذا الملف. أنا النقر عليه فقط، لذلك تحميل الملف بالنسبة لي. ولكن كتابة مجلد مشترك من هذا الشيء داخل المحطة هو مجرد الذهاب الى تحميل البرنامج إلى محطة الخاص بك. لدي section5.zip، وسترغب في بفك section5.zip، والتي سوف تعطيك مجلد يسمى section5، التي ستكون لدينا كافة الملفات ونحن في طريقنا إلى استخدام اليوم داخل منه. كما أسماء الملفات هذه البرامج 'تشير، انهم عربات التي تجرها الدواب قليلا، حتى مهمتكم هي لمعرفة لماذا استخدام جدب. لا يكون لهم الجميع تحميل / معرفة كيفية الحصول عليها تحميل في الأجهزة الخاصة بهم؟ حسنا. تشغيل ./buggy1، فإنه يقول خطأ الإنقسام (الأساسية ملقاة)، أي وقت التي تحصل على سوف segfault، انه شيء سيء. تحت أي ظرف من الظروف لا تحصل على سوف segfault؟ [طالب] يعتبر إلغاء مرجعية مؤشر فارغة. نعم >>. بحيث هو مثال واحد. يعتبر إلغاء مرجعية مؤشر فارغة وأنت تسير في الحصول على سوف segfault. ما سوف segfault يعني كنت لمس الذاكرة يجب أن لا يتم لمس. يعتبر إلغاء مرجعية ذلك مؤشر فارغة لمس عنوان 0، وأساسا، كافة أجهزة الكمبيوتر في الوقت الحاضر أن نقول 0 العنوان هو الذاكرة التي لا ينبغي أن تمس. ولهذا السبب يعتبر إلغاء مرجعية لنتائج مؤشر فارغة في سوف segfault. عندما كنت يحدث لتتم تهيئة مؤشر، ثم أنه يحتوي على قيمة القمامة، وذلك عند محاولة إلغاء مرجعية لها، في جميع الاحتمالات كنت لمس الذاكرة هذا في وسط اللا مكان. إذا كنت يحدث للحصول على الحظ وقيمة القمامة للإشارة إلى حدث في مكان ما على كومة أو شيء، ثم عند إلغاء مرجعية هذا المؤشر الذي لديك لم يتم تهيئة، لا شيء على غير ما يرام. ولكن اذا كان لافتا، ويقول، في مكان ما بين كومة كومة ولل، أو انها مجرد لافتا إلى مكان ما لم يتم استخدامه من قبل برنامج الخاص بك حتى الآن، ثم كنت لمس الذاكرة التي لا ينبغي أن لمس وسوف segfault لك. عند كتابة دالة العودية وrecurses مرات كثيرة جدا والكدسة ينمو كبيرة جدا ويصطدم في كومة الأشياء أنه لا ينبغي أن تصطدم معها، كنت لمس الذاكرة يجب أن لا يتم لمس، لذلك أنت سوف segfault. وهذا هو ما سوف segfault هو. كما انها نفس السبب أنه إذا كان لديك مثل سلسلة - دعونا نعود إلى البرنامج السابق. في hello.c--I صباحا مجرد الذهاب الى تقديم شيء آخر. تشار * S = "أهلا بالعالم!"؛ * إذا كنت تستخدم ق = ق أو شيء [0] = 'X'؛ لذلك مرحبا، / مرحبا، لماذا سوف segfault أن؟ لماذا هذا سوف segfault؟ ماذا تتوقع أن يحدث؟ إذا فعلت printf ("٪ S \ N"، ق)؛ فماذا تتوقع أن تكون مطبوعة؟ [طالب] X مرحبا. نعم >>. المشكلة هي أنه عندما تقوم بتعريف سلسلة من هذا القبيل، ق هو المؤشر الذي سيذهب على المكدس، وماذا ق يشير إلى هذه السلسلة هو الذي يرد في ذاكرة القراءة فقط. ذلك فقط من خلال الذاكرة اسم للقراءة فقط،، يجب أن تحصل على هذه الفكرة أنه إذا حاولت تغيير ما في ذاكرة القراءة فقط، كنت تفعل شيئا لا يجب أن تفعله مع الذاكرة وسوف segfault لك. هذا هو في الواقع فرق كبير بين شار * S شار وق []. حتى شار ق []، الآن هذه السلسلة سوف يتم وضعه على كومة، والمكدس ليست للقراءة فقط، وهو ما يعني أن ذلك يجب أن تعمل بشكل جيد تماما. ويفعل. تذكر أنه عندما أفعل شار * S = "أهلا بالعالم!"، ق نفسه هو على المكدس ولكنها تشير ليالي لمكان آخر، وأنه في مكان آخر يحدث أن تكون للقراءة فقط. ولكن ليالي شار [] هو مجرد شيء على المكدس. ولهذا مثال آخر على سوف segfault يحدث. رأينا أن ./buggy1 أدى إلى سوف segfault. من الناحية النظرية، يجب أن لا ننظر إلى buggy1.c على الفور. بدلا من ذلك، سوف نبحث في ذلك من خلال جدب. لاحظ أنه عند الحصول على خطأ تجزئة (الأساسية ملقاة)، تحصل على هذا الملف الأساسية يسمى هنا. إذا كنا LS-L، وسنرى ان جوهر وعادة ما يكون الملف كبير جدا. هذا هو عدد وحدات البايت من الملف، لذلك يبدو انها شيء 250-كيلو بايت. والسبب في ذلك هو أن ما هو في الواقع تفريغ الأساسية عندما تعطل البرنامج، وحالة الذاكرة من البرنامج فقط يحصل على نسخ ولصق في هذا الملف. يحصل ملقاة عليه في هذا الملف. هذا البرنامج، حدث بينما كان قيد التشغيل، أن يكون لها استخدام الذاكرة من حوالي 250 كيلو بايت، وهكذا وهذا ما حصل تصب في هذا الملف. الآن يمكنك أن تبحث في هذا الملف اذا لم نفعل GDB buggy1 الأساسية. يمكننا أن نفعل فقط GDB buggy1، والتي ستبدأ للتو GDB بانتظام، باستخدام buggy1 في ملف مدخلاته. لكن اذا كنت تفعل GDB buggy1 الأساسية، ثم انه سيكون خصيصا لبدء GDB من خلال النظر في هذا الملف الأساسية. وأنت تقول buggy1 GDB سائل يعلم أن هذا الملف يأتي الأساسية من البرنامج buggy1. حتى جدب buggy1 الأساسية سوف تجلب لنا على الفور إلى حيث حصل البرنامج لإنهاء. نرى هنا برنامج إنهاء إشارة 11، خطأ الإنقسام. يحدث لأننا نرى خط التجميع، والتي ربما تكون غير مفيدة جدا. ولكن إذا قمت بكتابة BT أو التتبع المعاكس، التي ستكون وظيفة أن يعطينا قائمة إطارات المكدس الحالي لدينا. حتى التتبع المعاكس. يبدو ليس لدينا سوى إطارات المكدس اثنين. الأول هو الإطار الرئيسي لدينا مكدس، والثاني هو الإطار المكدس للحصول على هذه الوظيفة أننا يحدث ليكون في، الذي يبدو وكأنه ليس لدينا سوى رمز التجميع ل. لذلك دعونا نعود إلى وظيفتنا الرئيسية، وعلى ذلك يمكننا القيام به الإطار 1، وأعتقد أننا يمكن أن تفعل أيضا إلى أسفل، ولكن أنا تقريبا لم تفعل أسفل - أو ما يصل. نعم. صعودا وهبوطا. إحضار لكم كومة إطار واحد، بانخفاض يجلب لك إطار المكدس. أنا أميل إلى أن تستخدم أبدا. أنا فقط أقول تحديدا الإطار 1، الذي يذهب إلى الإطار المسمى 1. الإطار 1 سوف تجلب لنا في إطار مكدس الرئيسي، وتقول هنا سطر التعليمات البرمجية نحن يحدث ليكون في. إذا أردنا خطوط زوجين أكثر من التعليمات البرمجية، يمكن القول القائمة، وهذا ما سيعطينا جميع الأسطر من التعليمات البرمجية حوله. وكان خط segfaulted نحن في 6: إذا كان (strcmp ("CS50 الصخور"، argv [1]) == 0). إذا لم يكن واضحا حتى الآن، يمكنك الحصول عليه مباشرة من هنا فقط عن طريق التفكير لماذا segfaulted. ولكن يمكن أن نأخذ خطوة واحدة أخرى ويقول: "لماذا argv [1] سوف segfault؟" طباعة دعونا argv [1]، ويبدو انها 0x0، وهو مؤشر فارغة. نحن strcmping CS50 الصخور وفارغة، وبحيث سيكون لسوف segfault. والسبب هو argv [1] فارغة؟ [طالب] لأننا لم تقدم له أية وسائط سطر الأوامر. نعم. نحن لم تقدم له أية وسائط سطر الأوامر. حتى ./buggy1 لن يؤدي الا الى أن argv [0] يكون ./buggy1. انها لن يكون لها argv [1]، لذلك أن يحدث لسوف segfault. ولكن إذا، بدلا من ذلك، فقط أفعل CS50، انها سوف تحصل على القول D لأن هذا هو ما يفترض أن تفعله. أبحث في buggy1.c، أنه من المفترض أن طباعة "تحصل على D" - إذا argv [1] لا "CS50 الصخور"، "أنت تحصل على D"، وإلا "تحصل على A!" إذا كان الأمر كذلك فإننا نريد A، نحن بحاجة لمقارنة هذه على النحو الصحيح، مما يعني أنه يقارن إلى 0. حتى argv [1] يجب أن يكون "CS50 الصخور". إذا كنت ترغب في القيام بذلك على سطر الأوامر، تحتاج إلى استخدام \ هربا من الفضاء. حتى CS50 \ الصخور وتحصل على A! إذا كنت لا تفعل مائل، لماذا لا تعمل هذه؟ [طالب] انها حجتين مختلفة. نعم >>. Argv [1] ستكون CS50، وargv [2] ستكون الصخور. حسنا. الآن هو الذهاب الى ./buggy2 سوف segfault مرة أخرى. بدلا من فتح الملف مع جوهرها، وسوف نفتح للتو buggy2 مباشرة، حتى جدب buggy2. الآن إذا كنا مجرد تشغيل برنامجنا، ثم انها سوف تلقى إشارة ويقول برنامج SIGSEGV، وهو سوف segfault إشارة، وهذا هو المكان الذي حدث ليحدث. أبحث في التتبع المعاكس لنا، ونحن نرى أن كنا في oh_no وظيفة، التي كانت تسمى من قبل أنيق وظيفة، والتي كانت تسمى من قبل binky وظيفة، كان يسمى من قبل والتي الرئيسي. يمكننا أن نرى أيضا الحجج لهذه الوظائف. وكانت الحجة لدينكي وbinky 1. إذا كان لنا أن قائمة oh_no وظيفة، ونحن نرى أن oh_no يقوم به فقط شار ** S = NULL؛ * S = "BOOM"؛ لماذا التي لا؟ [طالب] لا يمكنك dereference المؤشر فارغة؟ نعم >>. هذا هو فقط أقول هذا هو NULL، بغض النظر إذا كان هذا يحدث ليكون ** شار، التي، اعتمادا على كيفية تفسير ذلك، يمكن أن يكون مؤشر إلى مؤشر إلى سلسلة أو مجموعة من السلاسل. انها ليالي هو NULL، لذلك يعتبر إلغاء مرجعية * S هو مؤشر فارغة، وحتى هذا هو الذهاب الى تحطم الطائرة. هذه هي واحدة من أسرع الطرق التي يمكنك سوف segfault ربما. انها مجرد إعلان مؤشر فارغة وsegfaulting على الفور. هذا ما تقوم به oh_no. إذا كان لنا أن ترتفع إطار واحد، ثم ونحن في طريقنا للوصول الى الدالة التي تسمى oh_no. ولست بحاجة للقيام بذلك أسفل. إذا لم تقم بإدخال أمر وكنت مجرد ضرب أدخل مرة أخرى، فإنه مجرد تكرار الأمر السابق أن تشغيلك. نحن في الإطار 1. إدراج هذا الإطار، ونحن نرى هنا وظيفتنا. يمكنك ضرب القائمة مرة أخرى، أو يمكنك القيام قائمة 20 و سوف قائمة أكثر. ويقول أنيق وظيفة إذا كنت 1، ثم انتقل إلى وظيفة oh_no، انتقل إلى وظيفة أخرى فاتنة. ونحن نعلم أنا هو 1 لأننا نرى يحدث هنا كان يسمى هذا أنيق مع حجة 1. أو يمكنك فقط لا ط طباعة، وسوف أقول أنا هو 1. نحن حاليا في أنيق، وإذا كنا ترتفع إطار آخر، نحن نعلم أننا سوف ينتهي في binky. حتى. الآن نحن في binky. إدراج هذه الوظيفة - لائحة من قبل نصف قطع قبالة لي - بدأت قبالة كما لو كنت 0، ثم ونحن في طريقنا أن نسميها oh_no، استدعاء آخر أنيق. ونحن نعلم أنا كان 1، لذلك دعا أنيق. والآن نعود في الرئيسي، والرئيسي هو الذهاب لمجرد أن يكون الباحث ط = RAND ()٪ 3؛ ما يحدث فقط لإعطائك رقم عشوائي وهذا هو إما 0 أو 1 أو 2. انه سيكون لدعوة binky مع هذا العدد، وأنه سيعود 0. بالنظر إلى هذا، مجرد المشي من خلال برنامج يدويا دون تشغيل على الفور، كنت تعيين نقطة فاصل في الرئيسية، وهو ما يعني أننا عندما تشغيل برنامج البرنامج يعمل حتى كان يضرب نقطة فاصل. حتى تشغيل البرنامج، فإنه سيتم تشغيل وبعد ذلك سوف تصل الى الوظيفة الرئيسية وإيقاف تشغيل. نحن الآن داخل الرئيسية، وخطوة أو القادمة سوف تجلب لنا إلى السطر التالي من التعليمات البرمجية. يمكنك أن تفعل أو خطوة التالية. ضرب المقبل، والآن تم تعيين الأول لراند ()٪ 3، حتى نتمكن من طباعة قيمة ط، وسوف أقول أنا هو 1. الآن لا يهم ما إذا كنا استخدام التالية أو خطوة. وأنا أعتقد أنه يهم في السابق، ولكن كنا نريد لاستخدام المقبل. إذا كان لنا أن استخدام الخطوة، نحن نخطو إلى وظيفة، وهو ما يعني نظرة على الشيء الفعلي أن يحدث داخل binky. إذا كان لنا أن استخدام المقبل، فإن ذلك يعني يذهب أكثر من وظيفة واذهبوا إلى السطر التالي من التعليمات البرمجية في وظيفة الرئيسية لدينا. الحق هنا على هذا الخط، وكنت في حيث قال راند ()٪ 3؛ إذا فعلت الخطوة، فإنه يذهب في تنفيذ راند وإلقاء نظرة على ما يحدث هناك، وأنا لا يمكن الخطوة من خلال وظيفة راند. ولكن أنا لا يهمني الدالة RAND. أريد فقط أن تذهب إلى السطر التالي من التعليمات البرمجية في الرئيسي، ولذا فإنني استخدام المقبل. ولكن الآن أنا لا يهتمون وظيفة binky، لذلك أريد أن الخطوة إلى ذلك. الآن أنا في binky. السطر الأول من التعليمات البرمجية هو الذهاب الى القول ما اذا كان (ط == 0)، I اتخاذ خطوة، نرى نحن في نهاية المطاف في أنيق. اذا كانت الامور قائمة ونحن نرى أنه هو فحص ط = 0. أنا لا يساوي 0، لذلك ذهبت إلى حالة أخرى، الذي هو الذهاب الى استدعاء أنيق (ط). قد خلط بين لك. إذا كنت مجرد إلقاء نظرة على هذه الخطوط مباشرة، قد تعتقد اذا كان (ط == 0)، حسنا، ثم أخذت خطوة والآن أنا في دينكي (ط)، قد تعتقد أنه يجب يعني ط = 0 أو شيء. رقم بل يعني فقط ان كان يعرف أنه يمكن أن تلتصق مباشرة إلى خط أنيق (ط). لأنني غير 0، فإن الخطوة التالية لن تنتهي عند آخر. هو آخر خط لا انها سوف تتوقف عند. انه سيكون فقط للذهاب إلى السطر التالي أنه يمكن تنفيذ في الواقع، والذي هو أنيق (ط). يخطو إلى أنيق (ط)، ونحن نرى ما اذا كان (ط == 1). نعرفه ط = 1، لذلك عندما كنا خطوة، ونحن نعلم أننا ذاهبون الى نهاية المطاف في oh_no لأنني = 1 يستدعي oh_no ظيفة، والتي يمكنك الخطوة إلى، التي سيتم وضع حرف S = ** لاغية وعلى الفور "BOOM". ثم يبحث فعلا في تنفيذ buggy2، هذا، وأنا هو مجرد الحصول على رقم عشوائي - 0 أو 1 أو 2 - دعوة binky، التي لو كنت تصفه هو 0 oh_no، وإلا فإنه يدعو أنيق، والتي تأتي إلى هنا. إذا كنت 1، دعوة oh_no، استدعاء آخر فاتنة، والتي تأتي إلى هنا، إذا كنت 2، دعوة oh_no. لا أعتقد حتى أن هناك طريقة - لا أحد يرى وسيلة لجعل هذا البرنامج الذي سوف segfault لن؟ لأنه ما لم أنا في عداد المفقودين شيء، إذا كنت هي 0، فسوف سوف segfault على الفور، آخر تذهب إلى وظيفة التي لو كنت أنت هو 1 سوف segfault، آخر تذهب إلى وظيفة حيث إذا كنت أنا هو 2 سوف segfault. لذلك لا يهم ما تفعله، وأنت سوف segfault. أعتقد طريقة واحدة لتحديد ذلك سيكون بدلا من القيام شار ** S = NULL، هل يمكن لهذا الفضاء malloc السلسلة. يمكن أن نفعل malloc (sizeof) - sizeof ماذا؟ [طالب] (شار) * 5؟ هل هذا يبدو >> أليس كذلك؟ أنا افترض ان هذا سوف يعمل إذا ركضت فعلا، ولكنها ليست ما كنت أبحث عنه. ننظر إلى نوع من ليالي. دعونا نضيف * الباحث، لذلك الباحث * س. وأود أن تفعل malloc (sizeof (الباحث)). أو إذا أردت مجموعة من 5، أود أن تفعل (sizeof (الباحث) * 5)؛ ماذا لو لدي ** الباحث؟ ما أود malloc؟ [طالب] حجم المؤشر. نعم >>. (sizeof (كثافة العمليات *))؛ نفس الشيء الى هنا. أريد (sizeof (تشار *))؛ هذا هو الذهاب الى تخصيص مساحة لمؤشر يشير إلى أن "BOOM". ولست بحاجة إلى تخصيص مساحة ل"BOOM" في حد ذاته لأن هذا هو ما يعادل في الأساس إلى ما قلته من قبل من شار * X = "BOOM". "BOOM" موجود مسبقا. يحدث في الوجود في المنطقة للقراءة فقط من الذاكرة. ولكن كان موجودا بالفعل، وهو ما يعني هذا السطر من التعليمات البرمجية، إذا ق هو ** شار، ثم * S * هو حرف وكنت تعيين هذه شار * للإشارة إلى "BOOM". إذا أردت أن نسخ "BOOM" في ثانية، ثم أود أن تحتاج إلى تخصيص مساحة ليالي. سأفعل * S = malloc (sizeof (تشار) * 5)؛ لماذا 5؟ لماذا لا 4؟ يبدو "BOOM" هو 4 أحرف. >> [طالب] الحرف فارغة. نعم. جميع سلاسل الخاص بك سوف تحتاج إلى حرف فارغة. الآن أستطيع أن أفعل شيئا مثل strcat - ما هي وظيفة لنسخ سلسلة؟ [طالب] CPY؟ strcpy >>. رجل strcpy. strcpy ذلك أو strncpy. strncpy قليلا أكثر أمنا منذ يمكنك تحديد بالضبط عدد الأحرف، ولكن هنا لا يهم لأننا نعرف. strcpy ذلك والبحث في الحجج. الوسيطة الأولى هي وجهتنا. الوسيطة الثانية هي مصدرنا. ونحن في طريقنا لنسخ إلى وجهتنا ليالي * مؤشر "BOOM". لماذا قد تريد أن تفعل هذا مع strcpy بدلا من مجرد ما كان لدينا قبل * S = من "BOOM"؟ هناك سبب قد ترغب في القيام بذلك، ولكن ما هو هذا السبب؟ [طالب] إذا كنت ترغب في تغيير شيء ما في "BOOM". نعم >>. الآن أستطيع أن تفعل شيئا مثل هذا [0] = 'X'؛ لأن ليالي نقطة إلى كومة والمساحة التي على كومة أن يتم الإشارة إلى ليالي هو مؤشر إلى المزيد من المساحة على كومة، والتي يتم تخزين "BOOM". لذلك يتم تخزين هذه النسخة من "BOOM" في كومة. هناك نسختين من الناحية الفنية "BOOM" في برنامجنا. هناك أول واحد بالنظر الى أن هذا الثابت فقط من خلال "BOOM" سلسلة، والنسخة الثانية من "BOOM"، التي أنشئت strcpy على نسخة من "BOOM". ولكن يجري تخزين نسخة من "BOOM" على كومة، كومة وأنت حر في التغيير. كومة ليست للقراءة فقط، بحيث يعني أن ليالي [0] سوف تسمح لك بتغيير قيمة "BOOM". انه سيكون لتمكنك من تغيير تلك الأحرف. الأسئلة؟ حسنا. الانتقال إلى buggy3، دعونا GDB buggy3. نحن فقط تشغيله، ونحن نرى أن نحصل على سوف segfault. إذا كنا التتبع المعاكس، لا يوجد سوى اثنين من وظائف. إذا كان لنا أن ترتفع إلى وظيفتنا الرئيسية، ونحن نرى أننا في segfaulted هذا الخط. حتى مجرد النظر في هذا الخط، ل(الباحث خط = 0؛ fgets هذه الاشياء لا NULL لا على قدم المساواة؛ خط + +). كان يسمى إطارنا السابقة _IO_fgets. سترى أن كثيرا مع وظائف C المدمج في، أنه عندما تحصل على سوف segfault، سيكون هناك أسماء دالة خفي حقا مثل هذا _IO_fgets. ولكن هذا سيكون لهذه الدعوة تتصل fgets. في مكان ما داخل هنا، ونحن segfaulting. إذا نظرنا إلى حجج لfgets، يمكننا طباعة العازلة. دعونا طباعة وأ - أوه، لا. الطباعة لن تعمل تماما كما أريد أن. دعونا ننظر في البرنامج الفعلي. العازلة هو صفيف حرف. انها صفيف حرف من 128 حرفا. لذلك عندما أقول العازلة الطباعة، انه سيكون لطباعة تلك الأحرف 128، الذي أعتقد هو ما هو متوقع. ما كنت تبحث عن طباعة عنوان العازلة، ولكن هذا لا اقول حقا لي الكثير. لذلك عندما يحدث لي أن أقول هنا X العازلة، فإنه يظهر لي 0xbffff090، التي، إذا كنت تتذكر في وقت سابق من بعض أو نقطة، Oxbffff يميل إلى أن يكون منطقة مكدس العش. المكدس يميل إلى نبدأ من مكان ما يقل قليلا عن 0xc000. فقط من خلال رؤية هذا العنوان، وأنا أعلم أن العازلة يجري على المكدس. إعادة تشغيل برنامجي، تشغيل، إلى أعلى، العازلة رأينا كان هذا التسلسل من الحروف التي هي جميلة معنى ذلك بكثير. ثم طباعة الملف، ملف ماذا تبدو وكأنها؟ [طالب] خالية. نعم >>. الملف هو من نوع FILE *، لذلك هو المؤشر، وقيمة هذا المؤشر فارغة. حتى fgets سوف أحاول أن أقرأ من هذا المؤشر بطريقة غير مباشرة، ولكن من أجل الوصول إلى هذا المؤشر، فقد لإلغاء مرجعية ذلك. أو، من أجل الوصول إلى ما ينبغي أن يكون لافتا إلى أنه dereferences ذلك. لذلك يعتبر إلغاء مرجعية انها مؤشر فارغة وsegfaults ذلك. يمكن أن يكون إعادة تشغيل I هناك. إذا ما تم كسر نقطة في هدفنا الرئيسي وتشغيل، السطر الأول من التعليمات البرمجية تشار * اسم الملف = "nonexistent.txt"؛ وينبغي أن تعطي إشارة كبيرة جدا لماذا فشل هذا البرنامج. كتابة المقبل يقودني إلى السطر التالي، حيث أقوم بفتح هذا الملف، ومن ثم أحصل على الفور الى لدينا خط، حيث بمجرد أن يصل المقبل، انه سيكون لسوف segfault. لا أحد يريد التخلص من سبب لماذا نحن قد segfaulting؟ [طالب] الملف غير موجود. نعم >>. ومن المفترض أن يكون هذا تلميحا أنه كلما كنت فتح ملف تحتاج إلى التحقق من وجود الملف بالفعل. حتى هنا، "nonexistent.txt"؛ عندما كنا الدالة fopen اسم الملف للقراءة، ونحن بحاجة بعد ذلك إلى القول إذا كان (ملف == NULL) printf ويقول ("الملف غير موجود!" أو - والأفضل من ذلك - اسم الملف)؛ عودة 1؛ حتى الآن نحن تحقق لمعرفة ما اذا كان NULL في الواقع استمرار وقبل محاولة قراءة من هذا الملف. يمكننا إعادة صنع ذلك لمجرد أن نرى أن يعمل. كنت أنوي أن تدرج سطر جديد. حتى الآن nonexistent.txt غير موجود. يجب عليك دائما التحقق لهذا النوع من الاشياء. يجب عليك دائما التحقق لمعرفة ما إذا الدالة fopen ترجع NULL. يجب عليك دائما التحقق للتأكد من أن malloc لا يرجع NULL، أو أنك سوف segfault. الآن buggy4.c. على التوالي. انا التخمين هذا هو انتظار إدخال أو حلقات لانهائية ربما. نعم، انها حلقات لانهائية. حتى buggy4. يبدو أننا حلقات لانهائية. يمكننا كسر في الرئيسية، تشغيل برنامجنا. في جدب، طالما كنت تستخدم اختصار هو لا لبس فيها أو الاختصارات الخاصة التي يقدمونها لك، ثم يمكنك استخدام ن لاستخدام المقبل بدلا من الاضطرار الى نوع من القادم على طول الطريق. والآن بعد أن قمت ضرب ن مرة واحدة، ويمكنني أن مجرد ضرب أدخل على الاستمرار المقبل بدلا من الاضطرار لتصل ن أدخل، أدخل ن، ن أدخل. يبدو أنا في نوع من لحلقة هذا ما وضع مجموعة [أنا] إلى 0. يبدو أنني لم الخروج من هذه الحلقة ل. إذا كنت أنا طباعة، لذلك أنا هو 2، ثم سأذهب المقبل. أنا طباعة ط، ط هو 3، ثم سأذهب المقبل. أنا الأول وأنا طباعة هو 3. المقبل، طباعة ط، ط 4. في الواقع، والطباعة sizeof (مجموعة)، لذلك حجم الصفيف هو 20. لكن يبدو أن هناك بعض الأوامر جدب خاصة للذهاب حتى يحدث شيء. انها مثل وضع شرط على قيمة المتغير. ولكن لا أتذكر ما هو عليه. إذا كان الأمر كذلك فإننا الاستمرار - ما كنت تقول؟ ماذا طرح؟ [طالب] هل يمكنني إضافة عرض - نعم >>. عرض حتى أتمكن من مساعدة. إذا كان لنا أن مجرد عرض الأول، فإنه سيتم طرح هنا ما قيمة i هو لذلك أنا لم يكن لديك لطباعته في كل مرة. إذا كنا سوف نستمر القادمة، ونحن نرى 0، 1، 2، 3، 4، 5، 0، 1، 2، 3، 4، 5، 0، 1، 2، 3، 4، 5. هناك خطأ رهيب، وأنا يجري إعادة تعيين إلى 0. أبحث في buggy4.c، ونحن نرى كل ما يحدث هو مجموعة الباحث [5]؛ ل(ط = 0، وأنا <= sizeof (مجموعة)، وأنا + +) مجموعة [ط] = 0؛ ماذا نرى أن من الخطأ هنا؟ كما تلميحا، عندما كنت اقوم به في GDB buggy4 - دعونا كسر الرئيسي، المدى - لم أكن طباعة sizeof (مجموعة) فقط لرؤية ما كان الشرط الأول حيث ينبغي أن كسر في نهاية المطاف. أين أنا؟ لم أركض؟ لم أكن تعلن بعد. طباعة حتى sizeof (مجموعة) وهذا 20، والتي من المتوقع منذ بلدي هو مجموعة من حجم 5 و انها صحيحة من 5، لذلك ينبغي أن يكون الشيء كامل 5 * sizeof (الباحث) بايت، حيث sizeof (الباحث) يميل إلى أن يكون 4. حتى sizeof (مجموعة) هو 20. ما ينبغي أن يكون هذا؟ [طالب] مقسمة بواسطة sizeof (الباحث). نعم >>، / sizeof (الباحث). يبدو لا يزال هناك مشكلة هنا. وأعتقد أن هذا يجب أن يكون فقط < منذ انها جميلة دائما الكثير <وأبدا <=. الآن دعونا نفكر لماذا تم كسر هذا الواقع. هل هناك تخمينات لماذا تم إعادة تعيين إلى 0 أنا من خلال كل تكرار للحلقة؟ الشيء الوحيد داخل هنا أن يحدث هو أن مجموعة [ط] ويجري تعيين إلى 0. على نحو ما كان الأمر كذلك، هذا الخط من التعليمات البرمجية تسبب الباحث لدينا أن أضع إلى 0. يمكن [طالب] يكون ذلك بسبب انها تجاوز ذكرى هذا الجزء من أنا عندما يعتقد انها العنصر التالي من مجموعة؟ >> [بودين] نعم. عندما كنا في طريقنا إلى ما بعد نهاية الصفيف لدينا، بطريقة ما أن الفضاء أننا تجاوز يتم تجاوز قيمة ط. وهكذا إذا نظرنا إلى buggy4، وكسر الرئيسي، تشغيل، دعونا طباعة عنوان ط. يبدو انها bffff124. الآن دعونا طباعة عنوان مجموعة [0]. 110. ماذا عن [1]؟ 114. [2]، 118. 11C، 120. مجموعة [5] هو bfff124. حتى مجموعة [5] لديه نفس العنوان كما قلت، وهو ما يعني أن مجموعة [5] هو أنا. إذا كان لديهم نفس العنوان، فهي نفس الشيء. لذلك عندما وضعناها مجموعة [5] إلى 0، ونحن ط وضع إلى 0. وإذا كنت تفكر في هذا من حيث المكدس، الباحث وأعلن لي أولا، وهو ما يعني أنني يحصل بعض المساحة على المكدس. ثم مجموعة [5] يتم تخصيص، ثم بحيث يتم تخصيص 20 بايت على المكدس. حتى يحصل المخصصة لي أولا، ثم الحصول على تخصيص هذه بايت 20. يحدث ذلك أنا الحق قبل الصفيف، وبسبب الطريقة، مثل قلت في الأسبوع الماضي، حيث الناحية الفنية المكدس ينمو إلى أسفل، عند مؤشر إلى صفيف، ويضمن لنا أن موقف 0 في الصفيف يحدث دائما قبل على المركز الأول في الصفيف. هذا هو نوع من كيفية وجهت في الأسبوع الماضي. لاحظت أن في أسفل لدينا عنوان 0 وعلى رأس لدينا عنوان ماكس. المكدس في تزايد مستمر أسفل. دعونا نقول اننا تخصيص ط. نحن تخصيص عدد صحيح الأول، وهو ما يعني دعونا نقول فقط هنا عدد صحيح يحصل المخصصة ط. ثم نحن لدينا مجموعة تخصيص من 5 أعداد صحيحة، وهو ما يعني أن تحت ذلك، منذ المكدس ينمو باستمرار، والحصول على تخصيص تلك الأعداد الصحيحة 5. ولكن بسبب الطريقة المصفوفات العمل، كنت يضمن لنا أن المركز الأول في الصفيف دائما عنوان أقل من الشيء الثاني في الصفيف. ذلك موقف مجموعة 0 دائما أن يحدث أولا في الذاكرة، بينما موقف صفيف 1 يجب أن يحدث بعد ذلك وموقف صفيف 2 يجب أن يحدث بعد ذلك، وهو ما يعني أن 0 موقف مجموعة في مكان ما سيحدث هنا إلى أسفل، أما موقف صفيف 1 أعلاه أن يحدث لأن تتحرك صعودا يعني ارتفاع عناوين منذ الحد الأقصى هو عنوان هنا. حتى مجموعة [0] إلى هنا، مجموعة [1] هنا، مجموعة [2] هنا، مجموعة [3] هنا. لاحظ كيف قبل أن تخصيص عدد صحيح أنا على طول الطريق حتى هنا، ونحن نتحرك أكثر وأكثر في مجموعتنا، ونحن الحصول على أوثق وأقرب إلى عدد صحيح لدينا ط. انها مجرد أن ذلك يحدث مجموعة [5]، الذي هو وظيفة واحدة خارج مجموعتنا، هو بالضبط حيث عدد صحيح أنا حدث لتخصيص. ذلك أن النقطة التي وصلنا يحدث ليكون ضرب المساحة على المكدس تم تخصيص لأني عدد صحيح، ونحن تحديد أن إلى 0. هذه هي الطريقة التي يعمل. الأسئلة؟ نعم. [طالب] لا بأس. حسنا. [طالب] كيف يمكنك تجنب هذا النوع من الأخطاء؟ هذا النوع من الأخطاء؟ لا تستخدم لغة البرمجة C كما الخاصة بك. استخدام اللغة التي لديها حدود الصفيف التحقق. طالما كنت حذرا، تحتاج فقط إلى تجنب الذهاب الماضية حدود الصفيف الخاص بك. [طالب] حتى هنا عندما ذهبنا الماضية حدود الصفيف الخاص بك - [بودين] حيث ان تبدأ الامور تسير بشكل خاطئ. >> [طالب] أوه، حسنا. طالما كنت البقاء في الذاكرة المخصصة للمجموعة الخاصة بك، أنت بخير. ولكن لا يوجد C تدقيق الأخطاء. إذا كنت تفعل مجموعة [1000]، فإنه سيتم تعديل بكل سرور فقط مهما حدث - فإنه يذهب إلى بداية الصفيف، ثم يذهب بعد 1000 مواقف ويضع إلى 0. لم يفعل أي التحقق من أن أوه، هذا لا يكون في الواقع الأشياء فيه 1000. 1000 هو الطريق إلى أبعد مما ينبغي تغيير I، في حين جافا أو شيء ستحصل على مجموعة من مؤشر حدود أو الفهرس خارج حدود استثناء. هذا هو السبب في الكثير من اللغات لديها مستوى أعلى هذه الأمور حيث إذا ذهبت خارج حدود الصفيف، لم تتمكن بحيث لا يمكنك تغيير الأشياء من تحت لك ثم تسير الأمور أسوأ بكثير من مجرد الحصول على استثناء قائلا ان ذهبت الى ما بعد نهاية الصفيف. [طالب] وهكذا ينبغي لنا أن تغيرت فقط <= لمجرد <؟ >> [بودين] نعم. ينبغي أن يكون > [طالب] الحق. المزيد من الأسئلة؟ حسنا. [طالب] لدي سؤال. نعم >>. [طالب] ما هو متغير صفيف الفعلية؟ [بودين] مثل ما هو صفيف؟ مجموعة نفسها هو رمز. انها مجرد عنوان بداية بايت 20 التي نحن الرجوع. يمكنك التفكير في الأمر كمؤشر، وإنما هو مؤشر ثابت. بمجرد الحصول على تصنيف الأشياء، المصفوفة متغير غير موجود بعد الآن. [طالب] فكيف لا تجد حجم مجموعة؟ حجم مجموعة يشير إلى أن حجم الكتلة التي تشير إلى هذا الرمز. عندما كنت تفعل شيئا مثل printf ("٪ P \ N"، مجموعة)؛ دعونا تشغيله. ماذا فعلت مجرد خطأ؟ 'مجموعة' مجموعة أعلن هنا. أوه، هنا فوق. رنة هي ذكية، ويحدث ذلك لاحظت أنني أعلنت مجموعة إلى 5 عناصر ولكن أنا في موقف فهرسة 1000. يمكن أن نفعل ذلك لأن هذه هي الثوابت فقط. يمكن أن تذهب فقط حتى الآن في ملاحظة أنني ذاهب خارج حدود الصفيف. ولكن لاحظت من قبل عندما كان لدينا أنا غير صحيحة، فإنه لا يمكن تحديد عدد القيم ربما أنا يمكن أن تأخذ على، لذلك فإنه لا يمكن تحديد أنني ذاهب إلى ما بعد نهاية الصفيف. هذا مجرد ضجيج كونها ذكية. ولكن جعل buggy4 الآن. لذلك ماذا أفعل الخطأ؟ يعلن ضمنا وظيفة مكتبة "printf". انا ذاهب الى تريد تضمين # . حسنا. تشغيل الآن buggy4. طباعة مجموعة قيمة مثل فعلت هنا، والطباعة على أنها مؤشر طباعة ما يشبه هذا - bfb8805c - الذي هو عنوان بعض هذا في المنطقة كومة العش. مجموعة نفسها مثل المؤشر، ولكنها ليست مؤشر الفعلية، مؤشر منذ منتظمة يمكن أن نغير. الصفيف هو فقط بعض ثابتة. لبنات 20 من الذاكرة تبدأ في 0xbfb8805c العنوان. bfb8805c ذلك من خلال هذا العنوان +20- أو اعتقد -20 - هو كل من الذاكرة المخصصة لهذه المجموعة. الصفيف، لا يتم تخزين المتغير نفسه في أي مكان. عندما كنت تجميع والمترجم - موجة يدوية على ذلك - ولكن المترجم مجرد استخدام حيث يعرف مجموعة أن تكون. أنه يعرف أين يبدأ هذا الصفيف، وهكذا يمكن أن تفعل الأشياء دائما من حيث أن إزاحة من البداية. فإنه لا يحتاج إلى المتغير نفسه لتمثيل مجموعة. ولكن عندما أفعل شيئا من هذا القبيل * الباحث مجموعة = P، أما الآن ف هو مؤشر الذي يشير إلى أن مجموعة، والآن ف فعلا موجود على المكدس. أنا حرة لتغيير ف. يمكنني أن أفعل p = malloc. لذلك أشار في الأصل إلى مجموعة، والآن يشير إلى بعض المساحة على الكومة. لا أستطيع أن أفعل مجموعة = malloc. إذا ضجيج هو ذكي، وسوف يصيح في وجهي الحق قبالة الخفافيش. في الواقع، أنا متأكد من دول مجلس التعاون الخليجي سوف نفعل ذلك أيضا. ذلك نوع مصفوفة 'INT [5]' غير محدد. لا يمكنك تعيين شيء إلى نوع الصفيف لأن مجرد مجموعة ثابت. بل هو الرمز الذي مراجع تلك بايت 20. لا أستطيع تغييره. [طالب] وأين هو حجم الصفيف المخزن؟ [بودين] ليست المخزنة في أي مكان. انها عندما يكون تجميع. فأين هي حجم مجموعة تخزينها؟ يمكنك فقط استخدام sizeof (مجموعة) داخل الدالة التي يتم تعريف المصفوفة نفسها. حتى لو كنت تفعل بعض من وظيفة، فو، والقيام I (الباحث مجموعة []) printf ("٪ د \ ن"، sizeof (مجموعة))؛ ثم إلى هنا أدعو فو (مجموعة)؛ داخل هذه الوظيفة - دعونا تشغيله. هذا هو ضجيج كونها ذكية مرة أخرى. انها تقول لي أن sizeof على المعلمة دالة صفيف سيعود حجم '* كثافة العمليات'. وهذا سيكون خطأ إذا لم يكن ما أردت أن يحدث. دعونا تحويل الواقع قبالة Werror. تحذير. تحذيرات على ما يرام. فإنه لا يزال تجميع طالما أنها تحذير. / a.out هو الذهاب الى طباعة 4. التحذير التي تم إنشاؤها هو مؤشر واضح لما حدث من خطأ. هذه المجموعة كثافة العمليات هو مجرد الذهاب لطباعة sizeof (كثافة العمليات *). حتى لو وضعت مجموعة [5] هنا، انها لا تزال مجرد الذهاب لطباعة sizeof (كثافة العمليات *). وذلك بمجرد نقله إلى وظيفة، والتمييز بين المصفوفات والمؤشرات هو غير موجود. هذا يحدث ليكون مجموعة التي أعلن عنها في بنية تخزين العناصر، ولكن بمجرد أن تمر هذه القيمة، التي 0xbf بلاه، بلاه، بلاه في هذه الوظيفة، ثم وهذا مؤشر يشير إلى أن مجموعة على المكدس. بحيث يعني أن sizeof لا ينطبق إلا في وظيفة التي أعلن عنها الصفيف، وهو ما يعني أنه عندما كنت تجميع هذه الوظيفة، عندما يمر عبر ضجيج هذه الوظيفة، فإنه يرى الصفيف مجموعة من حجم كثافة العمليات 5. ثم لذلك يرى sizeof (مجموعة). حسنا، هذا هو 20. هذا في الواقع كيف يعمل sizeof أساسا لجميع الحالات تقريبا. Sizeof ليس وظيفة، بل عامل. لا استدعاء الدالة sizeof. Sizeof (الباحث)، والمترجم يترجم ذلك تماما إلى 4. حصلت عليه؟ حسنا. [طالب] فما هو الفرق بين sizeof (مجموعة) في الرئيسية وفي فو؟ وذلك لأن نقوله sizeof (مجموعة)، والتي هي من نوع int *، في حين أن مجموعة أسفل هنا ليست من نوع int *، انها مجموعة INT. [طالب] حتى إذا كان لديك المعلمة في مجموعة [] بدلا من مجموعة الباحث *، فهل يعني ذلك لك قد تتغير بسبب مجموعة الآن حان مؤشر؟ [بودين] مثل هذا؟ >> [طالب] نعم. يمكنك تغيير مجموعة ضمن الدالة الآن؟ [بودين] هل يمكن تغيير مجموعة في كلتا الحالتين. في كل من هذه الحالات أنت حر في قول طائفة [4] = 0. [طالب] ولكن يمكنك تقديم وجهة الصفيف إلى شيء آخر؟ [بودين] أوه. نعم. في كلتا الحالتين - >> [طالب] نعم. [بودين] التمييز بين مجموعة [] ومجموعة * الباحث، هناك لا شيء. يمكنك أيضا الحصول على مجموعة متعددة الأبعاد في بعض هنا بناء الجملة لبعض مريحة، لكنه ما زال مجرد مؤشر. هذا يعني أنني حر في أن يفعل مجموعة = malloc (sizeof (الباحث))، ويشير الآن في مكان آخر. ولكن تماما مثل كيف يعمل هذا إلى الأبد ودائما، تغيير هذه المجموعة من خلال جعلها إشارة إلى شيء آخر لا يغير هذه المجموعة إلى هنا لأنها نسخة من حجة، انها ليست مؤشر إلى أن هذه الحجة. والواقع، تماما كما يشير إلى أن أكثر انها بالضبط نفس - شاهدنا بالفعل ما يطبع مجموعة الطباعة - ماذا لو أننا طباعة عنوان مجموعة أو عنوان عنوان مجموعة إلى أي من تلك؟ دعونا نتجاهل هذا واحد. حسنا. هذا على ما يرام. انها تعمل الآن. / a.out. مجموعة الطباعة، ثم طباعة عنوان الصفيف، هي نفس الشيء. مجموعة فقط لا وجود لها. كان يعرف عندما كنت تقوم بطباعة مجموعة، كنت تقوم بطباعة الرمز الذي يشير إلى تلك بايت 20. طباعة عنوان الصفيف، أيضا، مجموعة غير موجود. أنه ليس لديه عنوان، لذلك فإنه يطبع فقط على عنوان تلك بايت 20. بمجرد تجميع أسفل، كما هو الحال في buggy4 المترجمة. / a.out، مجموعة غير موجود. مؤشرات وجود لها. صفائف لا. لبنات من الذاكرة التي تمثل مجموعة لا تزال موجودة، لكن مجموعة متغير والمتغيرات من هذا النوع لا وجود لها. تلك هي مثل الاختلافات الرئيسية بين المصفوفات والمؤشرات وبمجرد إجراء مكالمات وظيفة، لا فرق. ولكن داخل الدالة التي يتم أعلنت مجموعة نفسها، sizeof يعمل بشكل مختلف منذ كنت تقوم بطباعة حجم كتل بدلا من حجم النوع، وأنت لا تستطيع تغييره لأنه رمز. طباعة شيء وعنوان من الشيء يطبع نفس الشيء. وهذا الى حد كبير له. [طالب] هل يمكن أن نقول إن احد مزيد من الوقت؟ ربما فاتني شيء. مجموعة الطباعة وعنوان مجموعة يطبع نفس الشيء، في حين إذا قمت بطباعة المؤشر مقابل عنوان المؤشر، شيء واحد يطبع عنوان ما كنت لافتا إلى، الآخر يطبع عنوان المؤشر على المكدس. يمكنك تغيير مؤشر؛ لا يمكنك تغيير رمز الصفيف. وsizeof المؤشر هو الذهاب الى طباعة حجم هذا النوع المؤشر. * الباحث ذلك ف sizeof (ع) هو الذهاب الى طباعة 4، ولكن الباحث مجموعة [5] طباعة sizeof (مجموعة) هو الذهاب الى طباعة 20. [طالب] وهكذا الباحث مجموعة [5] سيتم طباعة 20؟ نعم >>. هذا هو السبب في داخل buggy4 عندما كان عليه أن يكون sizeof (مجموعة) هذا أنا أفعله <20، وهي ليست ما كنا نريد. نريد I <5. >> [طالب] حسنا. [بودين] وبعد ذلك بمجرد بدء يمر في وظائف، إذا فعلنا الباحث * p = مجموعة؛ داخل هذه الوظيفة، يمكننا استخدام أساسا ع مجموعة وبطرق بالضبط نفس، باستثناء مشكلة ومشكلة sizeof المتغيرة. لكن ع [0] = 1؛ هو نفسه قوله صفيف [0] = 1؛ وبمجرد أن يقول فو (مجموعة)، أو فو (ع)؛ داخل الدالة فو، وهذا هو نفس المكالمة مرتين. لا يوجد فرق بين هذه المكالمتين. جيدة على أن الجميع؟ حسنا. لدينا 10 دقيقة. سنحاول من خلال الحصول على هذا البرنامج من نوع هاكر، هذا الموقع، الذي خرج العام الماضي أو شيء. من المفترض أن يكون مجرد مثل تكتب بشكل عشوائي وبطباعة - أيا كان الملف قد يحدث تحميل ما يبدو كنت تكتب. يبدو نوعا من التعليمات البرمجية نظام التشغيل. هذا ما نريد أن تنفيذ. يجب أن يكون قابل للتنفيذ يدعى ثنائي hacker_typer التي تأخذ في حجة واحدة، الملف إلى "نوع القراصنة." يجب تشغيل الملف القابل للتنفيذ مسح الشاشة وبعد ذلك طباعة حرف واحد من الملف مرت في كل مرة يقوم المستخدم بالضغط على مفتاح. وبغض النظر عن مفتاح ضغط، يجب أن تتخلص من وطباعة حرف بدلا من الملف هذه هي الحجة. أنا الى حد كبير اقول لكم ما هي الأشياء التي كنت بحاجة الى الذهاب الى معرفة هي. لكننا نريد من إطلاعك على مكتبة termios. لم يسبق لي أن استخدمت هذه المكتبة في حياتي كلها، لذلك فقد أغراض ضئيلة جدا. ولكن هذا سيكون في مكتبة يمكننا استخدامها لرمي بعيدا الحرف الذي ضرب عندما كنت تكتب في مستوى الدخول. hacker_typer.c ذلك، ونحن في طريقنا إلى الرغبة في تضمين # . أبحث في الصفحة رجل لtermios - أنا التخمين انها محطة OS أو شيء - أنا لا أعرف كيفية قراءتها. النظر في هذا، فإنه يقول لتشمل هذه الملفات 2، ولذا فإننا سوف نفعل ذلك. أول شيء أولا، نحن نريد أن نأخذ في حجة واحدة، وهي أننا يجب أن ملف فتح. فماذا أريد القيام به؟ كيف يمكنني التحقق لمعرفة لدي حجة واحدة؟ [طالب] إذا argc يساوي ذلك. >> [بودين] نعم. حتى إذا (argc = 2!) printf ("الاستخدام:٪ S [لفتح ملف]"). حتى الآن إذا كنت تشغيل هذا دون توفير الحجة الثانية - أوه، أنا في حاجة إلى سطر جديد - سترى تقول نسبة الإستخدام:. / hacker_typer، ومن ثم ينبغي أن تكون الوسيطة الثانية الملف أريد لفتح. الآن ماذا أفعل؟ أريد أن أقرأ من هذا الملف. كيف يمكنني قراءة من ملف؟ [طالب] فتح لأول مرة. نعم >>. لذلك الدالة fopen. ماذا تبدو مثل الدالة fopen؟ [طالب] اسم الملف. >> [بودين] اسم الملف سيكون argv [1]. [طالب] وبعد ذلك ما تريد أن تفعله حيال ذلك، وبالتالي فإن - >> [بودين] نعم. حتى إذا كنت لا تذكر، هل يمكن أن تفعل فقط الدالة fopen الرجل، حيث انها ستكون CONST مسار * شار حيث أن path هو اسم الملف، * وضع CONST شار. إذا كنت يحدث للا يتذكر ما وضع هو، ثم يمكنك البحث عن واسطة. داخل صفحات الرجل، مائل الحرف هو ما يمكنك استخدامها للبحث عن الأشياء. اكتب ذلك I / وضع للبحث عن واسطة. ن N وهي التي يمكنك استخدامها للتنقل عبر مباريات البحث. هنا تقول النقاط وضع الحجة إلى سلسلة تبدأ مع واحدة من سلاسل التالية. حتى ص، ملف نصي مفتوح للقراءة. هذا ما نريد أن نفعله. لقراءة، وأنا أريد لتخزين ذلك. الشيء هو سيكون * FILE. الآن ماذا أريد أن أفعل؟ أعطني ثانية. حسنا. الآن ماذا أريد أن أفعل؟ [طالب] تحقق ما اذا كان NULL. >> [بودين] نعم. أي وقت قمت بفتح ملف، تأكد من أن كنت قادرا بنجاح لفتحه. الآن أريد أن أفعل الاشياء التي termios حيث أريد أن أول قراءة الإعدادات الحالية وحفظ هذه إلى شيء، ثم أريد تغيير الإعدادات لرمي بعيدا أي حرف I اكتب، ثم أريد تحديث هذه الإعدادات. ثم في نهاية البرنامج، أريد تغيير الإعدادات مرة أخرى إلى بلدي الأصلي. وبالتالي فإن البنية ستكون من نوع termios، وانا ذاهب الى اثنين من هذه تريد. أول واحد سيكون current_settings بلدي، ثم انهم ذاهبون ليكون hacker_settings بلدي. أولا، أنا ذاهب إلى تريد حفظ الإعدادات الحالية، ثم انا ذاهب الى تريد تحديث hacker_settings، ثم الطريقة في نهاية برنامجي، أريد أن تعود إلى الإعدادات الحالية. إنقاذ ذلك الإعدادات الحالية، والطريقة التي يعمل بها، ونحن termios الرجل. ونحن نرى أن لدينا هذا tcsetattr الباحث، الباحث tcgetattr. أمرر في البنية termios بواسطة مؤشر لها. هذه الطريقة سوف ننظر هو - I've نسي بالفعل ما كان يسمى وظيفة. نسخه ولصقه. حتى tcgetattr، ثم أريد أن تمر في البنية أنني إنقاذ المعلومات في، التي ستكون current_settings، والحجة الأولى هي ملف واصف لشيء أريد أن حفظ سمات. ما هو واصف الملف هو مثل أي مرة يتم فيها فتح ملف، فإنه يحصل على واصف الملف. عندما الدالة fopen argv [1]، فإنه يحصل على واصف الملف الذي يتم الرجوع كلما كنت ترغب في القراءة أو الكتابة إليه. هذا ليس واصف الملف أريد استخدام هنا. هناك اصفات الملفات الثلاثة لديك بشكل افتراضي، التي هي المعيار في، انتهت القياسية، والخطأ المعياري. بشكل افتراضي، أعتقد أنه من القياسية في 0، معيار من 1، والخطأ المعياري هو 2. فماذا أريد تغيير إعدادات؟ أريد تغيير إعدادات كلما ضرب حرف، أريد أن رمي بعيدا تلك الشخصية بدلا من طباعته على الشاشة. ما تيار - معيار في، انتهت القياسية، أو الخطأ المعياري - يستجيب إلى الأشياء عندما كنت اكتب على لوحة المفاتيح؟ >> [طالب] نعم >> مستوى فيها. لذلك يمكنني أن أفعل إما 0 أو يمكنني القيام به ستدين. أنا الحصول على current_settings من مستوى الدخول. الآن أريد تحديث هذه الإعدادات، أولا حتى أنا ما نسخ في hacker_settings current_settings بلدي. وكيف البنيات العمل فإنه مجرد نسخ. نسخ هذا كافة الحقول، كما كنت تتوقع. الآن أريد تحديث بعض الحقول. أبحث في termios، سيكون لديك لقراءة من خلال الكثير من هذه فقط لرؤية ما كنت تريد أن تبحث عن، ولكن الأعلام كنت تريد الذهاب الى البحث عن وصدى، ECHO ذلك إدخال أحرف صدى. أولا أريد أن تعيين - I've نسي بالفعل ما هي المجالات. هذا هو ما يشبه البنية. لذلك أوضاع إدخال أعتقد أننا تريد تغييره. سوف نبحث في الحل للتأكد من أن هذا ما نريد تغييره. نحن نريد لتغيير lflag من أجل منع الحاجة إلى البحث عن طريق كل هذه. نريد أن تغيير أوضاع المحلية. سيكون لديك لقراءة من خلال هذا كله شيء أن نفهم كل شيء حيث ينتمي اننا نريد للتغيير. ولكن من داخل وسائط المحلية حيث نحن ذاهبون الى تريد تغيير ذلك. حتى hacker_settings.cc_lmode هو ما يطلق عليه. c_lflag. هذا هو المكان الذي نصل إلى مشغلي أحادي المعامل. نحن نوع من الخروج من الزمن، ولكننا سوف يمر منه سريعة الحقيقي. هذا هو المكان الذي نصل إلى مشغلي أحادي المعامل، حيث أعتقد قلت مرة واحدة منذ فترة طويلة أنه كلما كنت بدء التعامل مع الأعلام، وأنت تسير إلى استخدام أحادي المعامل مشغل الكثير. كل بت في العلم يتوافق مع بعض النوع من السلوك. حتى هنا، وهذا العلم لديه مجموعة من أشياء مختلفة، حيث كل منهم يعني شيئا مختلفا. ولكن ما أريد القيام به هو بدوره قبالة بت والتي تتطابق مع الصدى. ذلك لتحويل هذا الخروج أفعل و= ¬ ECHO. في الواقع، أعتقد أنه من مثل TECHO أو شيء. انا فقط للتحقق مرة أخرى. لا أستطيع termios ذلك. انها مجرد ECHO. ECHO سيكون قليلا واحد. ¬ ECHO سوف يعني يتم تعيين كافة البتات إلى 1، مما يعني يتم تعيين كافة الأعلام إلى true باستثناء بعض الشيء ECHO. من خلال إنهاء أعلام مدينتي مع هذا، فإنه يعني كل الأعلام التي تم تعيينها حاليا إلى true سوف لا يزال يتم تعيين إلى true. إذا تم تعيين وائي ECHO إلى true، ثم يتم تعيين هذا إلى false بالضرورة على العلم ECHO. لذلك هذا السطر من التعليمات البرمجية يتحول قبالة العلم ECHO. خطوط أخرى من التعليمات البرمجية، وأنا مجرد نسخ منها في الفائدة من الوقت وبعد ذلك شرح لهم. في الحل، قال 0. هو على الأرجح الأفضل أن نقول صراحة ستدين. تلاحظ أن أفعله أيضا ECHO | ICANON هنا. ICANON يشير إلى شيء منفصل، وهو ما يعني وضع الكنسي. ما هو وضع الوسائل الكنسي عادة عندما كنت تكتب من سطر الأوامر، المعيار في أي شيء لا يتم معالجة حتى تصل السطر الجديد. لذلك كنت اكتب عندما كنت GetString، حفنة من الأشياء، ثم تضغط على زر السطر الجديد. هذا عندما يكون إرساله إلى مستوى فيه. هذا هو الافتراضي. عندما أنتقل تشغيل الوضع الكنسي، والآن كل حرف واحد تضغط ويحصل على معالجة ما، التي عادة ما تكون نوع من سوء لأنها بطيئة في معالجة هذه الأمور، الذي هو السبب في أنه من الجيد أن العازلة ذلك إلى خطوط بأكملها. ولكن أريد أن تتم معالجة كل حرف منذ أنا لا أريد أن انتظر لي لتصل إلى السطر الجديد قبل يقوم بمعالجة كافة الأحرف لقد كنت تكتب. هذا الوضع الكنسي إيقاف. هذه الاشياء يعني فقط عندما يقوم بمعالجة الواقع حرفا. هذا يعني معالجتها فورا؛ أقرب وقت وأنا كتابتها، معالجتها. وهذا هو وظيفة التي استكمال الإعدادات الخاصة بي لالقياسية في، ووسائل TCSA تفعل ذلك الآن. الخيارات الأخرى هي الانتظار حتى تتم معالجة كل ما هو حاليا على تيار. هذا لا يهم حقا. فقط في الوقت الحالي تغيير الإعدادات لتكون كل ما هو حاليا في hacker_typer_settings. اعتقد انني يطلق عليه hacker_settings، لذلك دعونا تغيير ذلك. تغيير كل شيء لhacker_settings. الآن في نهاية برنامجنا نحن ذاهبون الى تريد العودة على ما هو حاليا داخل normal_settings، التي سوف تبدو وكأنها مجرد وnormal_settings. لاحظت أنني لم تغير أي من بلدي منذ normal_settings الحصول على الأصل. ثم لتغيير منهم فقط إلى الوراء، I تمريرها مرة أخرى في نهاية المطاف. وكان هذا التحديث. حسنا. الآن داخل هنا ساوضح فقط رمز لمصلحة من الزمن. انها ليست أن رمز من ذلك بكثير. ونحن نرى قراءة حرف من الملف. كنا نسميها و. يمكنك الآن fgetc الرجل، ولكن كيف fgetc هو الذهاب إلى العمل هو مجرد انه سيكون لإرجاع الحرف الذي قرأت للتو أو EOF، والتي تتطابق مع نهاية الملف أو بعض حدوث الخطأ. نحن حلقات، الاستمرار في قراءة حرف واحد من الملف، حتى لقد قمنا من تشغيل الأحرف لقراءة. وبينما نحن نفعل ذلك، ونحن ننتظر على حرف واحد من مستوى الدخول. في كل مرة اكتب لك شيئا في سطر الأوامر، هذا ما القراءة في حرف من مستوى الدخول. ثم putchar هو مجرد الذهاب لوضع حرف نقرأ هنا من الملف إلى خارج القياسية. يمكنك putchar الرجل، لكنه مجرد وضع لمعيار بها، انها تطبع ذلك الحرف. هل يمكن أيضا القيام فقط printf ("C٪"، ج)؛ نفس الفكرة. هذا ما تنوي القيام به الجزء الأكبر من عملنا. آخر شيء نحن ذاهبون الى تريد القيام به هو مجرد ملف fclose لدينا. إذا كنت لا fclose، وهذا هو تسرب الذاكرة. نريد أن fclose الملف فتحنا أصلا، وأعتقد أن كل شيء. إذا جعلنا ذلك، حصلت بالفعل مشاكل. دعونا نرى. ماذا كان يشكو؟ يتوقع 'الباحث' ولكن الحجة هي من نوع 'البنية _IO_FILE *'. سنرى ما اذا كان يعمل. يسمح فقط في C99. Augh. حسنا، وجعل hacker_typer. الآن حصلنا على أوصاف أكثر فائدة. وذلك باستخدام معرف غير معروفة من "normal_settings '. لم أكن يطلق عليه normal_settings. دعوت عليه current_settings. لذلك دعونا تغيير كل ذلك. يمر الآن حجة. سوف يجعل هذا 0 في الوقت الراهن. حسنا. / hacker_typer cp.c. كما أنني لم مسح الشاشة في البداية. ولكن يمكنك ننظر إلى الوراء إلى مجموعة المشكلة الأخيرة لنرى كيف مسح الشاشة. انها مجرد طباعة بعض الأحرف في حين أن هذا هو فعل ما أريد القيام به. حسنا. والتفكير لماذا هذا يحتاج إلى 0 بدلا من ستدين، والتي يجب أن تحدد # 0، هذا وتشكو من - قبل عندما قلت أن هناك اصفات الملف ولكن ثم لديك أيضا * FILE الخاص، واصف الملف هو مجرد عدد صحيح واحد، في حين أن لديه FILE * مجموعة كاملة من الاشياء المرتبطة به. السبب في أننا بحاجة إلى أن أقول 0 بدلا من ستدين هو أن ستدين هو FILE * الذي يشير إلى الشيء الذي يتم الرجوع اصف الملف 0. وحتى مع ذلك هنا عندما أفعل الدالة fopen (argv [1]، وأنا الحصول على الملف مرة أخرى *. ولكن في مكان ما في هذا FILE * هو شيء الموافق ملف واصف لهذا الملف. إذا نظرتم الى صفحة مفتوحة للرجل، لذلك أعتقد سيكون لديك للقيام رجل 3 مفتوح - كلا - رجل 2 مفتوح - نعم. إذا نظرتم الى الصفحة لفتح، فتح مثل الدالة fopen المستوى الأدنى، وانها تعود واصف الملف الفعلي. الدالة fopen لا حفنة من الاشياء على رأس فتح، التي بدلا من العودة مجرد أن اصف ملف بإرجاع الملف بأكمله * مؤشر وهو داخل ملف واصف لدينا قليلا. معيار ذلك في يشير إلى شيء FILE *، في حين يشير إلى 0 فقط ملف قياسي اصف في حد ذاته. الأسئلة؟ فجر [يضحك] من خلال ذلك. حسنا. ننتهي. [يضحك] [CS50.TV]