[השמעת מוסיקה] ROB בודן: בסדר. לכן, דבר הראשון ראשון, של וידאו מפרצוף מוכר. [וידאו השמעה] -בסדר. זה CS50, וזה תחילת השבוע שלושה. אני מצטער אני לא יכול להיות שם איתך היום, אך הרשה לי להציג של רוב בודן של CS50. [השמעת וידאו END] [מחיאות כפות וקריאות עידוד] ROB בודן: הסרטים ב וידאו כי הוא פנטסטי. בסדר. אז קודם כל, יש ארוחת צהריים אחר. זה מחר בשעה 1:15. אין ארוחת צהריים ביום שישי הקרוב. זה עם Quora. וטומי עדיין לא כאן, אבל אחד אנשים שיש CF לשעבר הראש, טומי McWilliam. אז הוא בחור כיף. אתה צריך לבוא. בסדר. אז בשבוע שעבר, התחלנו מתפרקים על מה מחרוזת באמת. אנחנו מכירים מאז תחילת ש זה רצף של תווים. אבל בשבוע שעבר, אנחנו התעמקתי בעובדה כי מה הוא באמת רצף של דמויות, טוב, עכשיו יש לנו מערכים של תווים. ואנחנו יודעים שמחרוזת, זה מערך של דמויות, ממש בסוף, יש לנו הבתים null המיוחדים הזה, זה קו נטוי הפוך 0, המציין את סוף המחרוזת. וכך מחרוזת היא מערך של דמויות, אבל יכול להיות לנו יותר מ רק מערך של תווים, יכול להיות לנו מערך של כל סוג של דבר שאנחנו רוצים. לכן, אם אתם זוכרים משבוע שעבר, גילאי תכנית שהציג דוד ממש מהר. דבר אז קודם כל אנחנו הולכים לעשות הוא לשאול את המשתמש למספר שלם, מספר האנשים בחדר. ברגע שיש לנו מספר שלם, אנחנו מכריזים מערך. שים לב תחביר סוגר זה. אתה הולך להתרגל לזה. אז אנחנו מכריזים על מערך של משתנה נקרא גילים, ויש n מספרים שלמים במערך זה. אז דפוס זה ממש כאן, int 4 זה אני שווה 0, הוא שאני פחות מ n, i בתוספת בתוספת, שהוא גם הולך להיות דפוס שאתה מקבל מאוד בעבר. כי זה פחות או יותר איך אתה תמיד הולך לחזר על מערכים. אז לזכור כי n הוא אורכו של המערך שלנו. וכן כאן, אנו מבקשים שוב ושוב לגיל שלי אדם בחדר. אחרי זה, אנחנו יורדים, ועל כל מה סיבה שרירותית, שלאחר מכן להדפיס את הבנים כמה הם הולכים להיות שנה מעכשיו. והפעלת תכנית ש, בואי להפוך גילים, מנקדים גילים נטויים. אז מספר האנשים בחדר, נניח שיש שלוש. ואומר, האדם הראשון הוא 13, הבא הוא 26, והאחרון הוא 30. אז זה יהיה לחזר על שלושה אלה אנשים, להדפיס 14 החוצה, 27, ויום 31. אז לזכור שכאשר אנו מצהירים מערך בגודל n, המדדים שב מערך, יש לו את המערך ערכים ו מדדי 0, 1, 2, כל הדרך עד n מינוס 1. לכן, כאשר אנו אמרתי שיש שלושה אנשים בחדר, ואנחנו מכניסים לפה איטרציה הראשונה תעבור את זה לולאה, אני הולך להיות 0. אז במדד 0. אנו מקצים הראשונים גיל משתמש המזין. אז בפעם הבאה, אנחנו נכנסים שני n משתמש מזין, וב לצד שני, n האחרון. אז שם לב שמערך של גודל שלוש אין שום דבר במדד בשלוש. זו אינה בתוקף. בסדר. אז, חוזר כאן. אז עכשיו שיש לנו עסק עם מערכים, יש לנו כמה היכרות. עכשיו אנחנו הולכים לעבור לפקודה שורת טענות, אשר הולכים להיות די רלוונטי לקבוצה את הבעיה הזו. אז עד עכשיו, בכל פעם שיש לך הכריז הפונקציה העיקרית שלך, יש לנו אמר void main int. אז הריק רק אומר כי אנחנו לא עוברים כל טיעונים לפונקציה זו. עכשיו אנחנו הולכים לראות עיקריים ש יכול לקחת כמה טיעונים. כאן אנחנו קוראים להם int argc וסוגר argv מחרוזת. בסוגריים, שוב, מה שמצביעים עם מערכים שיש לנו עסק. אז הנה, בסוגריים argv המחרוזת, אנחנו התמודדות עם מערך של מחרוזות. אז argc, שהולך להצביע כמה טיעונים שיש לנו עבר לתכנית זו. ולראות מה זה אומר, בואו נסגור את זה. על אישור. אז עד עכשיו, יש לנו לרוץ בכל תכנית כמו גילאי לוכסן נקודה. אנחנו יכולים גם, בשורת הפקודה, בעבר להעביר טיעונים, ולכן המונח, פקודה שורת טענות. אז הטענה הראשונה, שלום עולם. אז הנה, argc יהיה שלוש. זה הספירה של הטיעונים בשורת הפקודה. Argc הוא תמיד לפחות 1, שכן נקודה סלאש גילים, עצמו, נחשב כאחד טיעוני שורת הפקודה. אז שלום הוא הראשון. אם גילאי לוכסן נקודה הוא האפס, ולאחר מכן שלום הוא ראשון, והעולם הוא ויכוח שורת הפקודה שני. אז argv המחרוזת, אנחנו הולכים לראות, מכיל מחרוזות, לוכסן הנקודה גיליו, הלו, ועולם. ו, לפי בקשתו של דוד, אנחנו הולכים לשחק וידאו מציג את זה. [וידאו השמעה] -עד עכשיו בתוכניות שיש לנו כתב, יש לנו להכריז void main int כעיקרי. וכל הזמן הזה, יש חלל ש פשוט היה לציין כי תכנית אינה לוקחת כל טיעוני שורת הפקודה. במילים אחרות, כאשר משתמש מפעיל תכנית, הוא או היא יכולה לספק הפקודה טיעוני שורה על ידי כתיבה נוספת מילות או ביטויים לאחר התכנית שם בשורת הפקודה. ובכן, אם אין לך אתה רוצה את התכנית שלך ל לקחת טיעוני שורת הפקודה, אחד או עוד מילות כאלה, אנחנו צריכים להחליף לבטל עם כמה טיעונים. אז בואו לעשות את זה. כולל CS50.h. כולל io.h. הסטנדרטי Int הראשי. ועכשיו, במקום הריק, אני הולך תציין int נקרא argc, ו מערך של מחרוזות הנקראות argv. עכשיו, argc ו argv הוא פשוט אמנות. אנחנו יכולים קראנו טיעונים אלה רוב מה שאנחנו רוצים. אבל מה שחשוב הוא שargc הוא int כי, בהגדרה, הוא הולך להכיל את ספירת הוויכוח, מספר המילים בסך הכל ש המשתמש הקליד בשורת הפקודה שלו או שלה. argv, בינתיים, וקטור ויכוח, הוא באמת הולך להיות מערך אחסון את כל המילים שיש למשתמש הקליד בשורת הפקודה שלו או שלה. בואו להמשיך לעשות משהו עכשיו עם אחד או יותר מאלה טיעוני שורת הפקודה. בפרט, בואו נלך קדימה והדפסה מה מילת המשתמש מקליד אחרי השם של התכנית בשורת הפקודה. סוגר פתוח. סוגר על סגור. קו נטוי הפוך אחוזים printf ים ופסיק. ועכשיו אני צריך להגיד לי printf מה ערך כדי לחבר אל מציין מיקום זה. אני רוצה את המילה הראשונה שיש למשתמש הקליד אחרי השם של התכנית, ואז אני הולך כדי לציין argv סוגר 1, קרוב סוגריים, פסיק. עכשיו, למה סוגר סוגר 1 ולא 0? ובכן, מתברר, מאוחסן באופן אוטומטי בargv 0 הולכים להיות השם האמיתי של התכנית. אז המילה הראשונה שהמשתמש מקליד אחרי השם של התכנית הוא, על ידי אמנה, הולך להיות מאוחסן בargv 1. בואו עכשיו לקמפל ו להפעיל את התכנית. הפוך argv 0, argv לוכסן נקודת 0. ועכשיו מילה כמו שלום. Enter. ויש לנו את זה, הלו. [השמעת וידאו END] ROB בודן: בסדר. סגור את זה. אז לוקח תסתכל על תכנית ש אנחנו פשוט גם הצגנו לנו,, רק להראות, אם אנחנו להדפיס argv 0, לעשות, עכשיו מה זה, argv 0, argv לוכסן נקודת 0. אז, כצפוי, הוא מדפיס את שמה של התכנית, שכן argv 0 הוא תמיד הולך להיות שם של התכנית. אבל בואו נעשה משהו קצת יותר מעניין. אז בסט הבעיה, אתה תהיה הציג לפונקציה, atoi זה. אז מה אנחנו משתמשים atoi ל? זה הולך להמיר מחרוזת למספר שלם. אז אם אני עובר את המחרוזת, אחת שתיים שלוש, לatoi, זה יהיה להמיר את זה למספר השלם, אחת שתיים שלוש. אז אנחנו הולכים להמיר הראשונים ויכוח שורת הפקודה למספר שלם, ואז פשוט להדפיס מספר שלם. אז בעצם, אנחנו סוג של מחדש של getint, רק מספר השלם נכנס בפקודת קו במקום בתכנית באופן אינטראקטיבי. אז, מה שהופך argv 0, בואו נעשיתי את זה כאן, ולסגור את זה. אז פועל argv 0, ובואו להיכנס מספר שלם, אחת שתיים שלוש ארבע אחת שתיים. אז זה יהיה להדפיס את המספר השלם, אחד שתיים שלושה ארבעה אחת שתיים. יש כמה דקויות לatoi כי זה יהיה להפסיק לדאוג לכל דבר מעבר לאופי מספרי חוקי, אבל זה לא משנה. אז מה אתה חושב שקורה אם אני עושה את זה? אשמת פילוח. אז למה זה? אם אתה מסתכל אחורה על התכנית שלנו, אנחנו המרת argv 1, הטענה הראשונה לאחר את שם התכנית, למספר שלם. אבל אין ויכוח עבר לאחר שם התכנית. אז הנה, אנחנו רואים שמדובר בעגלה תכנית, שכן, אם ננסה להפעיל אותו ללא כל ויכוחים זה פשוט יתרסק. אז עוד דפוס נפוץ תראה הוא משהו כמו, אם argc הוא פחות משני, המצביעים על כך שלא היה לפחות את שם התכנית ו טענה ראשונה, אז אנחנו נעשה משהו כמו printf, לא מספיק טיעוני שורת הפקודה. זה כנראה לא אחד טוב כדי להדפיס, זה כנראה משהו, כמו אתה צריך להיכנס למספר שלם בשורת הפקודה. אני רק בסופו של אותו שם. ולאחר מכן לחזור 1. אז לזכור שבסופו שלנו תכנית, אם אנחנו חוזרים 0, זה סוג של מצביע על הצלחה. ועיקרי גם באופן אוטומטי מחזיר 0 אם לא. אז הנה, אנחנו retuning 1 כדי לציין שזה לא הצלחה. ואתה יכול להחזיר את מה שאתה רוצה, פשוט, 0 מציין הצלחה, ו כל דבר אחר מצביע על כישלון. אז בואו להפעיל גרסה זו של דברים. אז עכשיו, אם אנחנו לא נכנסים לשורת הפקודה ויכוח, זה יהיה נכון להגיד לי שלנו, לא שורת הפקודה מספיק. לא סיימתי את המשפט. אחר, אם אנחנו באמת להעביר אותו אחד, הוא יכול להשלים את התכנית. אז ככה היית משתמש בתכנית + כדי לאמת את מספר טיעוני שורת הפקודה כי הם עברו בפועל. אז בואו לעשות את התכנית הזאת קצת יותר מסובך, ומסתכל השני איטרציה של דברים. אז עכשיו, אנחנו לא רק הדפסה ויכוח שורת הפקודה ראשון. הנה, אנחנו iterating משווי i int 0, הוא שאני פחות מ argc, אני בתוספת בתוספת, וargv הדפסה, אינדקס i. אז דפוס זה, שוב, זה אותו הדבר דפוס כמו קודם, רק שבמקום לקרוא למשתנה n, אנחנו משתמשים בתכנית +. אז זה iterating מעל כל מדד במערך, ומדפיס כל אלמנט במערך זה. וכך, כאשר אנו מפעילים תכנית זו, טוב, אני לא נכנסתי לשורת פקודת כל טיעונים, כך שזה רק הדפסים את שם התכנית. אם אני נכנסתי לחבורה של דברים, זה יהיה להדפיס אחד, כל אחד בשורה הנפרדת. על אישור. אז בואו ניקח את זה צעד אחד קדימה. ובמקום להדפיס כל ארגומנט בשורה הנפרדת, בואו להדפיס כל אופיו של כל ארגומנט בשורה הנפרדת. אז לזכור כי argv הוא מערך של מחרוזות. אז מה היא מחרוזת, אבל מערך של תווים? אז זה אומר שargv הוא באמת מערך של מערך של תווים. אז מנצל את זה, בואו להתעלם מכך לעת עתה. בואו רק לשקול את argv המחרוזת 0. אז אם אנחנו רוצים להביא את כל תו של argv 0 בשורה הנפרדת, ולאחר מכן אני רוצה לעשות את הדפוס שאנחנו רגילים, הוא אני פחות מאורכו של המערך, אשר כאן, strlen של, זה לא מה שאני רוצה לעשות, מחרוזת ים שווה argv 0. אז האם אני פחות מאורכו שלנו מערך, אשר במקרה זה הוא מערך של דמויות, אני בתוספת בתוספת. וכך, כפי שראינו בשבוע שעבר, זה אידיאלי אם נעבור שstrlen מחוץ של המצב, שכן n יהיה הוספה strlen של ים בכל פעם שאנחנו הולכים דרך הלולאה, וזה לא הולך להיות שינוי. כך תהיה לנו להגדיר אותו שווה ל n לכאן. על אישור. אז עכשיו, אנחנו iterating מעל כל מדד במערך. וכך, אם אנחנו רוצים להדפיס כל דמות שבמערך, אחוזים ג היא את הדגל אנחנו רוצים להשתמש לתווים. ועכשיו אני סוגר הולך להיות מחרוזת, אופי אינדקס i, כך שאם מחרוזת היתה שלום. לאחר מכן s 0 הולכים להיות שעות, שעות והסוגר 1 יהיה בדואר, וכן הלאה. אז עכשיו אנחנו רוצים לשלב את שני הדברים האלה. אנחנו רוצים להדפיס כל תו של כל ארגומנט שורת הפקודה. אז אנחנו הולכים להיות מקוננות עבור לולאה. ומקובל, הדלפק הראשון אני, הבא הולך להיות j, n יהיה strlen של i argv, i היא פחות מ n, בתוספת בתוספת i. ועכשיו במקום שאני argv הדפסה, כך argv סוגר אני הולך למדד - זה הולך להיות בשורת פקודת i-ה ויכוח, argv i, j הולך להיות דמות JTH של טיעון i-ה. אני להיפטר מזה עד כאן עכשיו מאז שהכנסנו אותו לתוך הלולאה ש. אז שווה לשווים של המחרוזת argv i, j ולאחר מכן סוגר את ים. ובכן, אנחנו לא צריכים להצהיר של משתנה זה. במקום זאת, אנחנו פשוט לשלב הבאים שני למה שהיה לנו, argv i, j. 1 רמקול: [לא ברור]. ROB בודן: שיחה טובה. אז זהו שבורים. אם אני באמת רצתי אותו, הייתי עושה זאת הבין את זה. אז הדלפק אכפת לי בזה במיוחד עבור לולאה היא j, איטרטור. אז היית להיתקל בבעיות, כנראה ללולאה אינסופית, אם אנחנו לא תקן את זה. זו הסיבה שאנחנו גם מדברים על באגים היום. על אישור. אז בואו נריץ את התכנית. ובואו בעצם להוסיף printf נפרד ממש כאן, כי פשוט תדפיס קו נוסף, שכן זה אומר שכאשר אנו להפעיל את התכנית, יהיה ריק קו בין כל תו של כל ארגומנט שורת הפקודה. ובכן, נראה מה זה אומר. אופס. יש כמה באגים. שגיאה במשתמע הכרזה פונקצית ספריית strlen. אז חוזר לתכנית שלנו, אני שכח חשיש כולל string.h. אז string.h הולך להיות קובץ כותרת שמצהיר פונקצית strlen. בסדר, זה הידור. עכשיו, בואו להפעיל אותו. אז בדיוק את זה. זה הולך להדפיס אותנו שם תכנית, שלום עולם. זה הולך להדפיס כל דבר, שכל אחד אופי, בשורה הנפרדת. על אישור. אז בואו באמת לקחת את זה צעד אחד קדימה. ובמקום להשתמש string.h, בואו לחשוב על איך היינו ליישמנו פונקצית strlen. אז מייד אני אתן לי חתימת פונקציה. אז בואו נקראים בmy_strlen, וזה הולך לקחת את מחרוזת כטיעון, ואנו מצפים לחזור אורכו של חוט זה. אז, איפה בחור? כן. על אישור. אז זוכר מהשקופית מוקדם יותר כי היה גם בשבוע שעבר, כי מערך של תווים, טוב, מחרוזת, אז בואו נגיד שזה של המחרוזת שלנו. אז אם ים הוא המחרוזת, הלו, ולאחר מכן, H-E-L-L-O, בזיכרון, שהולך להיות, ולאחר מכן קו נטוי הפוך זה 0 אופי. אז איך אנחנו מקבלים את אורכו של ים? ובכן, החוכמה היא מחפשת את זה תגובה נגד 0 אופי, null זה שליחות קטלנית. אז האלגוריתם הולך להיות משהו כמו כמה מספיק דמויות ש-- בואו יש יד זה מייצג חלק דלפק, בואו נקראים לאורך int זה. לכן, החלו מכאן, אנחנו הולך לחזר על המחרוזת שלנו. אז התו הראשון, זה H, וזה לא יחזור לקצץ 0, ולכן האורך הוא 1. לחזר לתו הבא, E, וזה לא קו נטוי הפוך 0. אורך הוא 2. L, 3. L, 4. O, 5. ולבסוף, אנו מגיעים לקו נטוי 0, ולכן זה אומר, גם, מחרוזת זה נגמרה. אז בואו נחזור 5. אז בעצם יישום זה, ראשון, אורך n שלי שווה 0, יד ימין שלי. ואנחנו הולכים לחזר - 1 רמקול: [לא ברור] ROB בודן: אה, לירות. שיחה טובה. בום. אז אורך n שווה 0. אז עכשיו, באורך של הזמן שלא שווה ולאחר מכן, קו נטוי הפוך 0. אז תזכור, קו נטוי הפוך זה 0, זה הוא דמות ממשית, וזה מצביע על סוף המחרוזת. בדיוק כמו, גם, קו נטוי הפוך n הוא דמות ממשית. קו נטוי הפוך 0 הולך להצביע סוף המחרוזת שלנו. אני לא רוצה לשים את זה שם. ובעוד של אינדקס על ידי אורך הוא לא שווה לשליחות קטלנית null, אז אנחנו רק הולכים להגדיל אורך. אז, בסוף התכנית שלנו, אורך הוא סופו של דבר הולך להיות 5 במקרה זה. ואנחנו רק נחזור אורך. על אישור. אז עכשיו כאן למטה, אני לא לעשות my_strlen. בואו לאסוף אותו כדי לוודא הכל פועל בצורה חלקה. אני עושה ב 2? או שזה היה 1? שצריך לעשות. בסדר. אז זה argv 2. עובד כצפוי, אם כי היה שהאחד עשיתי את זה ב? כן. על אישור. גרסה זו של דברים שלא הייתה לי קו printf החדש אחרי, אבל זה לא עושה שום הבדל. על אישור. אז עבד כמצופה. עכשיו אנחנו יכולים אפילו לשלב את זה צעד אחד נוסף, שבו הודעה לכאן, טוב, ראשון, שאנו אוחזים strlen של argv i, ולאחר מכן אנחנו iterating מעל כל תו במחרוזת. אז במקום לעשות את זה, מה אם אנחנו פשוט לשלב את ההיגיון הזה של המתנה עד שהגענו לקו נטוי הפוך 0 תקין לתוך זה ללולאה? אז לחזר בזמן שאני argv, j עושה קו נטוי הפוך לא שווה 0. אז בואו להפעיל אותו ראשונה. בסדר. אז הנה, מצב זה אומר - בואו לנקות את זה. אז עכשיו, לתת לזה להיות argv שלנו. לכן, כאשר אני פשוט רצתי תכנית שלפני, argv הוא מערך של מחרוזות. וכך, אם אני מפעיל את זה עם argv לוכסן הנקודה 2, שלום העולם, אז argv את עצמו הוא באורך 3, לargv אפס, הלו, ועולם. ובתוך כל אחד ממדדים אלה הוא, עצמו מערך, שבו זה אהיה נקודה, זה יהיה קו נטוי, אני לא יודע אם זה היה בכיוון הנכון, אני לא חושב שזה היה. -R-V מקף, צריך יותר מקום. בואו לחתוך למערך זה. -R-V מקף 0, ולאחר מכן קו נטוי הפוך 0. ולאחר מכן באנדרלמוסיה יהיה שלום. בואו נגיד, קו נטוי הפוך H-E 0. ולבסוף, קו נטוי הפוך W-O 0. אז האלגוריתם שאנחנו פשוט כתבנו, מקונן ללולאות, מה שהם עושים הוא, שיש לנו ראשון דלפק אני ולאחר מכן j. זה יהיה קל יותר עם קוד על מסך, בואו נחזור לזה. על אישור. אז שם לב שהוא אני איטרטור זה iterating על כל פקודה קו טיעון. וי הוא iterating איטרטור על כל תו שב ויכוח שורת הפקודה. אז מה printf הפנימי ביותר זה עושה הוא, יש לנו printf argv 0 0, printf argv 0 1, argv printf 0 2, 0 3, 0 4, 0 5, 6 0, אבל עכשיו, argv 0 7 הולך קו נטוי הפוך שווה 0. אז אנחנו יוצאים כי ללולאה, ועכשיו אני סובב ל1. ועכשיו אנחנו הולכים להדפסה argv 1 0, argv 1 - 1 טוב, עכשיו, מאז שחתכתי שלום קצר, argv 1 2 הולך שוב להיות קו נטוי הפוך 0. וכך, להגדיל i ולהמשיך, ו כן הלאה, עד שלהדפיס את כל עולם, ואלו הם שורת פקודת שלוש טיעונים, ואנחנו נצא מתוך הלולאה החיצונית ביותר, ו לסיים את התכנית שלנו. על אישור. אז בואו נחזור לכאן. אז תוכל להרוויח היכרות מסוימת עם טיעוני שורת הפקודה על זה בעיה מסוימת שנקבעה. עכשיו, ניפוי שגיאות. אז אתה כנראה כבר היה צריך לעשות ניפוי חלקם עם הקודם שלך בעיה מוגדרת. ודרך קלה מאוד אחד מהניפוי, קודם כל, בואו נסתכל על תכנית מרכבה. ובכן, הליכה בתכנית זו, אנחנו הולכים לשאול את המשתמש עבור מספר שלם, מספר שלם לתפוס את זה, ולאחר מכן, באופן שרירותי, יש לנו לולאה בזמן ש הוא רק הולך הפחה אני עד שזה שווה ל10. בואו רק נניח אני נכנסתי מספר שלם גדול מ 10. אז הפחה אני עד שזה שווה ל10. ואז יש לנו בזמן שעוד לולאה זאת, בזמן שאני עושה לא שווה 0, אנחנו הולך הפחת i ידי 3. אז אם אתה רואה את הכוונה של באג כאן, זה שזה יהיה ההפחה i כדי להיות 10, ואז זה יהיה תוך לולאה מפחית i מ10, 7, 4, 1, ל2 שליליים, לשלילי 5, וכן הלאה, לאינסוף שלילי, מאז אני אף פעם לא באמת שווה 0. ואז בסוף של תכנית זו, יש לנו את פונקצית foo שהיא הולך על הדפסה שאני. אז זו תכנית קצרה וסתמית, ובאג הוא מובן מאליו, במיוחד אחרי שרק אמר את מה שהיה באג. אבל כאן הכוונה היא, ובכן, אולי זה בעצם נראה כמו חלק משלך פתרונות מחמדנים מהאחרונים בעיה מוגדרת, ואולי יש לך כמה לולאה אינסופית בתכנית שלך, ואין לך מושג מה גורם לכך. אז טכניקת ניפוי מאוד שימושית הוא רק להוסיף printfs בכל רחבי את הקוד שלך. אז הנה אני רוצה printf מחוץ בעוד לולאה ראשונה. וכאן אני רוצה printf, ואני פשוט אדפיס לי. אני מוכן אפילו לעשות קודם ואילו לולאה, i. בחוץ, שני בזמן לולאה. שוב, להדפיס בתוך מכאן, הערך i. ובואו נריץ את זה. באגים לוכסן אז נקודה. הזן את מספר שלם. בואו נעשה 13. ובום. אנחנו רואים שאנחנו לולאות אינסופיות בתוך תוך הלולאה השנייה. אז עכשיו אנחנו יודעים מה הוא באג. אבל ניפוי printf הוא מושלם גדול, אבל ברגע שהתוכניות שלך לקבל יותר ויותר מסובך, יש פתרונות מתוחכמים יותר ל מקבלים דברים עובדים. אז בואו נסיר את כל printfs אלה. ובואו נוודא שאני לא לשבור שום דבר. על אישור. אז התכנית אנחנו הולכים להציג נקרא GDB, לGNU Debugger. טוב, בעצם, בואו להסיר באגים עבור שני, ולעשות את הניפוי שוב. ובכן, למעשה ראשון, שיעור טוב בטיעוני שורת הפקודה. שים לב שפקודת קלאנג זה שהוא איסוף כל מה שהוא עבר בשורת הפקודה, אלה טיעוני שורת הפקודה. אז איך בדיוק אתה הולך להיות באמצעות טיעוני שורת הפקודה, כפי שאנו עשה בעבר, וכמו שאתה יהיה בPSET 2, ככה קלאנג הוא משתמש בהם. אז שם לב שדגל, מקף הראשון ggdb3, מה שאומר הוא, קלאנג, אתה צריך לקמפל את קובץ עם כוונה שסופו של דבר נעשינו את זה צריך לנפות אותו. אז כל עוד יש לך דגל ש, אז אנחנו יכולים ניפוי שגיאות GDB. וזה יהיה לפתוח את הבאגים של גנו. אז יש הרבה פקודות כי אתה צריך להתרגל. כי ראשון אתה בטח מייד צריך הוא הפעלה. אז מה הפעל הולכים לעשות? זה הולך להתחיל התכנית שלנו. אז לרוץ, תכנית מתחילה, התכנית שואל אותנו למספר שלם, 13. ואז זה לולאות אינסופיות צפוי, חוץ מזה שהוצאתי את printfs, אז אנחנו אפילו לא רואים את זה. יצא כרגיל. אה. זה אפשרי, כי זה עטוף כל להיפך, חזרה ל-- התעלמות ש. מניח שזה לא יצא באופן נורמלי. יש תשובה מסובכת לזה. אז עכשיו, זה לא מאוד שימושי. אז פשוט רצתי התכנית שלנו בתוך הבאגים זה לא עוזרים לנו בכל אגב, מאז שהיו יכול פשוט לעשות נקודה לקצץ באגים מבחוץ GDB. אז פקודה אחת ש אתה בטח - ואני אפסיק עם זה. Control-D או להפסיק, שניהם עובדים. אז בואו לפתוח אותו שוב. פקודה נוספת שאתה בטח מייד רוצה להתרגל להיא הפסקה. כך תהיה לנו לשבור בעיקרי לעת עתה, ואז אני אסביר לך את זה. ובכן, הנה אנחנו רואים שאנחנו לקבוע נקודת עצירה בשורה זו בdebug.c. אז מה פריצת הדרך היא שכאשר אני הקלד ארוך, התכנית הולכת תמשיך עד אני מכה נקודת עצירה. לכן, כאשר אני מכה ארוך, התכנית מתחילה, ואז זה פורץ ברגע זה נכנס לתפקידו העיקרי. לשבור עיקרי הולך להיות משהו אתה די נפוץ לעשות. ועכשיו, כדי להכיר לך לחלק מפקודות יותר. שים לב כאן, שזה אומר שאנחנו פרץ בקו 11, שהוא printf, הזן מספר שלם. אז את הפקודה הבאה הולכת להיות איך אנחנו הולכים לשורה הבאה של קוד. זה הולך כדי לאפשר לנו לצעוד דרך קו התכנית שלנו על ידי קו. אז הבא. עכשיו קו 12, אנחנו הולכים כדי לקבל את המספר השלם. הבא. ואם אתה רק על Enter שוב, זה יהיה לעשות שוב את הדבר האחרון שעשית. אז אני לא צריך להקליד הבא בכל פעם. אז הכנס את מספר שלם, 13. אז עכשיו, קו 14, ואילו היא i גדולה יותר מ -10, ואני אעשה הבא. ואנחנו רואים שאנחנו הולכים הפחת i. אז אנחנו הולכים להפחתי שוב. אז עכשיו, עוד שימושי הפקודה הדפסה. אז הדפסה הולכת להדפיס הערך של המשתנה. בואו להביא את הערך שלי משתנה. בואו להדפיס i. זה הולך להגיד הוא שאני 11. עכשיו אנחנו שוב על הבא תוך היא i גדולה מ 10. אז אני עדיין גדול מ 10, מכיוון שזה 11. אני מינוס מינוס. בואו להדפיס אני שוב. כצפוי, זה 10. אז עכשיו, הבא. זה חוזר למצב, הוא אני יותר מ -10, אבל הוא עכשיו אני 10, כך זה לא יותר מאשר 10, ולכן אנו צופים זה ליפול מתוך הלולאה. ועכשיו אנחנו מתחת לקו זה של קוד. ופקודה אחרת, רשימה, היא רק הולכת כדי להציג את הקודם והבא כמה שורות של קוד, ב למקרה שאיבדת את עצמך. אז אנחנו פשוט יצאנו ואילו לולאה זו, ועכשיו יש לנו נכנסתי זה תוך לולאה, קו 18. אז בזמן שאני עושה לא שווה 0. ו, הבא, אני שווה אני מינוס 3, ואנחנו שמתי לב, זה פשוט להמשיך. ואנחנו יכולים להדפיס לי. כל פקודה יש ​​סוג של קיצורי דרך. אז p הוא קיצור של הדפסה. אז אנחנו יכולים i p. רק לשמור מחזיק n, או להמשיך לעשות הבא. הדפסה אני שוב. אתה רואה עכשיו זה שלילי 167. אז זה יימשך לנצח, אבל לא באמת לנצח, מאז שראית, זה יהיה למעשה בסופו בשלב כלשהו. אז זה מתחיל GDB. אבל בואו נעשה עוד דבר אחד בGDB. אה, ניפוי שגיאות. אז, במקרה הספציפי הזה, לולאה אינסופית במקרה בתוך הפונקציה העיקרית. ולעת עתה, רק לקבל את זה שאני הולך להעביר את הלולאה האינסופית לתוך פונקצית foo. רק תזכור את זה, בסוף זה תכנית, טוב, זה היה במקור קורא foo, שרק היה הולך להדפיס לי. אבל עכשיו אנחנו קוראים foo, שהוא הולך הפחה אני עד שזה 0, ו לאחר מכן להדפיס משתנה ש. על אישור. תשמור את זה. הפוך ניפוי שגיאות. ועכשיו, לאתר באגים gdb. על אישור. אז אם אני פשוט הפעל אז אני לא הולך ל תוכל לשלב למעשה דרכי שורה אחר שורת תכנית. אז בואו לשבור בראשי, ולאחר מכן הקלד ארוך. אז לעבור את זה, printf, הזן מספר שלם, לקבל את המספר השלם, 13. אז אנחנו הולכים לשמור decrementing עד היא i גדולה מ 10. ואז אנחנו הולכים ליפול דרך תוך לולאה, ולהגיע לקו - בואו לפתוח אותו בחלון נפרד. אז אנחנו מופחתים עד שאני כבר לא היה יותר מ -10, ואז אנחנו קרא לפונקציה, foo. אז מה קרה ברגע שאני מכה foo פונקציה, טוב, אני נקרא foo, ו אז אני כבר לא היה שליטה על GDB. אז ברגע שאני מכה הבא בקו זה, דברים נמשכו עד שזה קרה, שבו התכנית יצאה כאשר - מניח שזה לא היה קיים סופו של דבר. ראית שזה להשהות קצת. אז למה שאני לא מאבד את השליטה על התכנית בשלב זה? ובכן, כשאני מקליד הבא, שהולך השורה הבאה המילולית של קוד ש יבצע. אז אחרי השורה 21, את השורה הבאה של קוד שיבצע הוא קו 22, אשר הוא, יציאה מראשית. אז אני לא רוצה סתם ללכת לשורה הבאה של קוד. אני רוצה להיכנס לפונקציה, foo, ולאחר מכן גם צעד דרך אלה שורות של קוד. אז בשביל זה, יש לנו אלטרנטיבה. בואו להפסיק את זה שוב. לשבור ראשי. אה, 1, הבא, הבא, 13, הבא, הבא, הבא, בזהירות, לפני שפגענו foo קו. על אישור. אז עכשיו, אנחנו בקו 21, שבו אנחנו קוראים לfoo. אנחנו לא רוצים להקליד הבאים, מאז ש יהיה פשוט להתקשר foo הפונקציה, ו תלך לשורה הבאה של קוד. מה שאנחנו רוצים להשתמש הוא שלב. אז יש הבדל בין שלב והשלב הבא, שבו שלב צעדים לתוך לתפקד, ולאחר מכן הולך על הפונקציה. זה פשוט מבצע את מכלול הפונקציה וממשיך לנסוע. אז שלב הוא הולך להביא לנו לפונקציה, foo. ואנו רואים כאן, עכשיו, אנחנו שוב ב בעוד לולאה זה זה, בתאוריה, הולך להמשיך לנצח. ואם אתה מכה שלב, כשזה אפילו לא פונקציה לקרוא, אז זה זהה לבא. אז זה רק כשאתה בקו הוא קורא לפונקציה שהשלב הוא הולך להיות שונה מבא. אז צעד יביא אותנו לכאן. צעד, צעד, צעד, צעד, צעד, צעד, ו אנחנו פשוט לולאה אינסופית לנצח. כך שאתה עלול להתרגל לכך כמו שלך דרך של זיהוי לולאות אינסופיות, היא רק מחזיק את מקש Enter זה כדי לראות איפה אתה נתקע. ישנן דרכים טובות יותר לעשות את זה, אבל לעת עתה, זה מספיק בהחלט. וסגנונית, כדי להתאים לסגנון 50, הייתי צריך לעשות את זה. על אישור. אז פקודה אחת האחרונה כדי להציג. ובכן, בואו GDB באגים פנימה אז במקום לשבור בעיקרי, אם אני יודע את פונקצית foo הוא גם בעיה, אז יש לי יכולים פשוט אמר, לשבור בfoo, במקום. בואו נגיד שאני אשבור ב שני עיקרי וfoo. אז אתה יכול להגדיר נקודות עצירה רבות כמו שאתה רוצה. כשאני מקליד ארוך, זה קורה לעצור ב-- אוו, בואו להדר מחדש, שכן שיניתי דברים. אתה תראה קו, אזהרה, מקור זה קובץ מעדכן יותר מהפעלה. אז זה אומר שאני פשוט נכנסתי לכאן ושינה את אלה כדי להתאים את הסגנון 50, אבל אני לא הידור מחדש את התכנית. אז GDB גורם לי מודע לכך. אני אפסיק, לעשות ניפוי שוב, פגע באגים gdb. על אישור. אז עכשיו, בחזרה למה שאני עושה. לשבור foo העיקרי, הפסקה. עכשיו, אם אני מפעיל את התכנית, כך שזה מתכוון להמשיך עד שיגיע נקודת עצירה. נקודת העצירה שקורה לי להיות הראשון בראשי. עכשיו, במקום לעשות הבא, הבא, הבא, הבא, הבא, עד שפגעתי foo, אני ניתן להקליד תמשיך, שימשיך עד שתגיעו לנקודת עצירה הבאה. אני צריך להזין את המספר השלם ראשונה. תמשיך ימשיך עד שפגעתי נקודת העצירה הבאה, שהוא ש פונקציה של foo. אז על הפעלה תרוץ עד שתגיע נקודת עצירה, אבל אתה רק להקליד ריצה כש אתה מתחיל את התכנית, ולאחר מכן, מכאן ואילך, זה ימשיך. אם אני רק עשיתי לשבור עיקרי ו אז רץ, זה ישבור ב ראשי, ולאחר מכן להמשיך. מאז אין לי נקודת הפסקה בfoo, הזן את המספר השלם, אז עכשיו אני לא הולך לשבור בfoo. זה רק הולך אינסופי לולאה עד ש. על אישור. אז זה פתיח לGDB. אתה צריך להתחיל להשתמש בו בסטי הבעיה שלך. זה יכול להיות מאוד מועיל לזהות באגים. אם אתה באמת פשוט, קו אחר קו, ללכת באמצעות הקוד שלך, ולהשוות את מה שהוא למעשה קורה עם מה שאתה מצפה לקרות, אז זה די קשה לפספס באגים שלך. על אישור. אז בשבוע שעבר דוד הביא את זה דברים הצפנה סוד מפתח עבור בפעם ראשונה, שבו אנחנו לא רוצים סיסמאות רק להיות מאוחסן עלינו מחשב בחלק בקובץ טקסט רגיל, שבו מישהו יכול לבוא ופשוט לפתוח אותו ולקרוא אותם. באופן אידיאלי, הם היו מוצפנים בדרך כלשהי. ובבעית הסט 2, אתה תהיה התמודדות עם שיטה אחת של הצפנה, או, כן, בשתי שיטות, אבל הם לא כל כך גדולים. אם אתה עושה את מהדורת ההאקר, אתה גם הולך להיות התמודדות עם פענוח כמה דברים. אז הבעיה כרגע היא, ובכן, גם אם יש לנו את ההצפנה החזקה ביותר אלגוריתם בעולם, אם תבחר סיסמא עניות במיוחד, אז זה לא אעזור לך מאוד, שכן אנשים עדיין יהיה מסוגל להבין את זה. גם אם רואה את המחרוזת מוצפנת ו זה נראה כמו בלגן של זבל שלא מזיז להם, אם הם עדיין רק צריך לנסות כמה סיסמאות כדי להבין את זה, אז אתה הם לא מאוד בטוחים. אז צפה בסרטון וידאו ש הופך לנקודה זו. [וידאו השמעה] קסדה, אתה שד. מה קורה? מה אתה עושה לבת שלי? -הרשה לי להציג את מבריק מנתח פלסטי צעיר, ד"ר פיליפ Schlotkin, האף הגדול עבודת אדם בכל היקום, ובוורלי הילס. -הוד מעלתו. האף עבודה? אני לא מבין. כבר היה לה ניתוח פלסטי באף. זה היה שש עשרה בהווה מתוק. -No. זה לא מה שאתה חושב. זה הרבה יותר, הרבה יותר גרוע. אם אתה לא נותן לי את שילוב ל מגן האוויר, ד"ר Schlotkin יהיה לתת לבת שלך בחזרה את אפה הישן. -No. מאיפה לקחת את זה? -בסדר. אני אגיד לי. אני אגיד לי. לא, אבא. לא, אתה לא חייב. -אתה צודק, יקירתי. אני אתגעגע אל האף החדש שלך. אבל אני לא אספר לו את השילוב, לא משנה מה. -טוב מאוד. ד"ר Schlotkin, לעשות הגרוע ביותר שלך. -הנאה. [כלים מתחדדים] -No. חכה. חכה. אני אגיד לי. אני אגיד לי. -ידעתי שזה יעבוד. בסדר. תן לי. -השילוב הוא אחד. -One. -One. ושתיים. ושתיים. ושתיים. ושלוש. ושלוש. ושלוש. ארבעה. ארבעה. ארבעה. חמש. חמש. חמש. -אז השילוב הוא אחד, שתיים, שלוש, ארבעה, חמש. זה השילוב הכי הטיפשי ששמעתי בחיים שלי. זה מסוג הדברים שאידיוט היה על המטען שלו. -תודה לך, הוד מעלתך. מה עשית? -כיביתי את הקיר. -אין לך לא. אתה כיבית את הסרט כולו. -כנראה שלחצתי על הכפתור הלא נכון. ובכן, לשים אותו על גב. שים את הסרט על גב. -כן, אדוני. כן, אדוני. -בואו נלך, ארנולד. בואו, גרטשן. כמובן, אתה יודע שאני עדיין צריך לחייב אותך על זה. [השמעת וידאו END] ROB בודן: בסדר. אז עכשיו שאנחנו כבר מדברים על ביטחון במובנים מסוימים, נחמד פוסטר סרט קטן, ולכן בשנים האחרונות ימים, בנושאים אלה עם NSA ניטור כל דבר. זה יכול להיות קשה להרגיש כמוך יש איזשהו פרטיות ב עולם מקוון, אם כי אני לא יכול להגיד לי אתה רוב הפרטים של פריזמה. אז נע מעבר PRISM, אנחנו לא מתכוונים שמדבר על זה, עכשיו חושב על המחשב הנייד שלך. אז עד כאן, אני רוצה לעבור לחשבון שלי בפועל, עם הפינגווין הקטן שלי. אז יש לי להגדיר סיסמא, וכי סיסמא היא מה שאני רוצה שזה יהיה. אך יש לזכור כי מה שאני מתחבר בעם, ולכן התחברות זו הפקודה, היא חלק מהתכנית. זה חלק מהתכנית שהייתה נכתב על ידי אדם כלשהו. וכך, אותו אדם, אם הם זדוני במיוחד, שביכולתם אמר, בסדר, אז אם הסיסמה שאני נכנסתי שווה לשלי הסיסמה בפועל, או שזה שווה כמה סיסמא מיוחדת - דוד הוא מדהים או משהו - לאחר מכן נתת להם להיכנס אז יש לי מתכנת זדוני יכול גישה לכל מחשבי מקינטוש שלך, או Windows, או משהו כזה. אז זה לא הרבה של דאגה, שכן, אני מתכוון, זה תכנית התחברות שסופק עם OS X, מאות או שיש לי אלפי אנשים סקר את הקוד הזה. וכך, אם, בקוד שלך באיזה מקום, אתה לומר אם מחרוזת זו שווה שווה דוד הוא מדהים, ההתחברות, ואז מישהו זה הולך להיות, כמו, חכה. זה לא בסדר. זה לא צריך להיות כאן. אז זו דרך אחת אנחנו מקבלים דברים להיות סוג של מאובטח. אבל תחשוב על תוכניות אפילו שאתה כותב. בואו נגיד שאתה כתב את תכנית ההתחברות. אז תכנית התחברות זה שאתה כתב, כל כך ברור, אתה טוב מתכנת. אתה לא הולך לשים את כל זדוני אם x שווה שווה דוד הוא מדהים לקוד שלך. אבל התכנית הזו, מה אתה עושה להשתמש בו כדי לקמפל תכנית זו? משהו כמו קלאנג. אז מה אם האדם שקרה לי לכתוב מיוחד קלאנג בדק בקלאנג משהו כמו, אם אני קומפילציה התחבר תכנית, ולאחר מכן להזין את הקוד הזה לתכנית ההתחברות שאומרת, אם x שווה שווה דוד הוא מדהים? אז לא ממש, אבל יש לנו את אותו בעיה כאן, שבו קלאנג, טוב, אלפים, אם לא עשרות אלפי אנשים, בחנו קלאנג, יש לי הביט בשורותיה של קוד ואמר, בסדר, אין שום דבר רע כאן. כמובן, אף אחד לא עושה דבר זה זדוני. אבל מה הוא צלצול עצמו, כמו, מה אם אני לקמפל קלאנג? מה אם יש לי כמה מהדר כי הידור קלאנג שמוסיף לקלאנג זה גרזן מיוחד שאומר, בסדר, כשאני לקמפל קלאנג, אז הפעלה אני מקבל צריך במיוחד לחפש בתוך תכנית ההתחברות ולהכניס סיסמא זו, שווה שווה דייב הוא מדהים? אז לזכור שהמהדר שלך עצמו צריך להיות הידור בשלב כלשהו. אז אם מה שאתה בוחר לקמפל קלאנג עם, עצמו הוא זדוני, אז אתה יכול להיות דפוק לגמרי דרך לאורך הקו. אז הנה, יש לנו קן תומפסון ודניס ריצ'י. אז זו תמונה איקונית. דניס ריצ'י הוא בצד הימין. הוא גדול - פחות או יותר כתב ג אז אתה יכול מודה לו על זה בכיתה. קן תומסון זה בצד השמאל. שניים מהם בעצם כתבו UNIX. ובכן, הם היו תורמים עיקריים בUNIX. היו שם עוד כמה אחרים. אז קן תומפסון, בשלב מסוים, הוא זוכה בפרס טיורינג. ואת הפרס טיורינג, תמיד שמע זה הפניה בדרך זו, זה פרס נובל במדעי מחשב. אז בפרס טיורינג, שיש לו לתת נאום תודה שלו. והוא נותן מאוד מפורסם הנאום הזה החברה, הנקרא הרהורים על אמון אמון, שיש לנו מקושר באתר הקורס. ובנאום הזה, הוא אומר, בסדר, אז כתבתי UNIX, ועכשיו כל שלך אנשים משתמשים UNIX. עכשיו, זוכר את היום שלינוקס היא צאצא ישיר של UNIX. OS X ישירות משתמש UNIX. Windows לא כל כך הרבה, אבל הרבה רעיונות נלקחו מUNIX. אז הוא עולה לבמה ואומר, בסדר, אני כתבתי UNIX. ורק כדי שהחבר 'ה יודעת, אני תוכל להתחבר לכל אחד מהמחשבים שלך. מאז שמתי אחד מיוחד אלה אם x שווה שווה קן תומסון הוא מדהים, אז מותר לי להתחבר. אז אנשים אומר, גם, איך עשיתי את זה? הסתכלנו על תכנית ההתחברות ושום דבר שם. הוא כמו, ובכן, אני שונה מהדר כדי להיכנס בתכנית ההתחברות כך שתכנית ההתחברות עכשיו תהיה לי x ששווה שווה קן תומפסון הוא מדהים. והם אומרים, טוב, זה לא נכון. אנחנו מסתכלים על מהדר, ו מהדר אין כל קווים קוד כזה. הוא כמו, בסדר, אבל מה אתה קומפילציה מהדר עם? והם חושבים, והוא, כמו, ובכן, אני זה שנתן לך את המהדר אתה משתמש כדי לקמפל את המהדר, כך אתה להרכיב מהדר, כי עצמו הוא זדוני, ויהיה לשבור את תכנית ההתחברות. אז בעצם, בשלב זה, אין אין דרך בה אתה יכול להסתכל על המקור קוד של תכנית ההתחברות כדי לראות מה לא בסדר. אתה לא יכול אפילו להסתכל ב קוד מקור של קומפיילר כדי לראות מה לא בסדר. היית צריך להסתכל על המכונה קוד, בינארי בפועל של מהדר הידור לראות, רגע, אלה שורות של קוד לא צריכים להיות כאן. אבל קן תומפסון לקח את זה צעד אחד עוד יותר ואמר, טוב, יש התוכניות המיוחדות הללו, שלמעשה לעזור לך לקרוא בינאריות של תוכניות, ולכן אם מישהו השתמש בתכנית זו כדי קראתי בינארי, הם היו רואים את אלה שורות של קוד. הוא הותאם תוכניות אלה לומר, כל נכון, אם אתה מסתכל על מהדר, לא להראות את זה במיוחד קבוצה של בינארי. אז אתה צריך לקחת את זה צעד אחד , שיש להם עוד יותר ובעצם יכול מספר רמות נלקחו מבעקיפין, ובשלב מסוים, אף אחד לא באמת הולך להיות בדיקה. אז מוסר ההשכל של הסיפור הוא, שאת לא הולך לכתוב צלצול בכיתה זו. אתה הולך להיות באמצעות טיפוס צלצול הרבה בכיתה זו. לכל מה שאתה יודע, קלאנג הוא זדוני תכנית שמחבלת בכל תכנית אחת שנאספה אי פעם. וכדי להשאיר אותך על שמאוד מאיים שים לב, לראות אותך ביום רביעי. [מחיאות כפות] SPEAKER 2: בCS50 הבא. SPEAKER 3: שלא יעז להגיד את זה. אתה יכול לעשות את זה. אתה כבר עשית את זה קודם, אתה יכול לעשות את זה היום, אתה יכול לעשות את זה מחר. אתה כבר עושה את זה במשך שנים. פשוט ללכת לשם ולעשות את זה. אתה יכול לעשות את זה. [השמעת מוסיקה]