דוד י מלאן: זה CS50 ו זה הוא ההתחלה של שבוע ארבעה. ו, ילד, הוא בפולקסווגן צרות כל בגלל תוכנה. תן לנו להעיף מבט. [וידאו השמעה] -Cars, הדמויות החכמים ביותר בסרטים המהיר ועצבני. יצרנית מכוניות גרמנית השבוע פולקסווגן מצא את עצמה באמצע שערורייה של פרופורציות פוטנציאל פליליות. -Volkswagen הוא מרענן למליארד בקנסות, אישומים פליליים אפשריים למנהליה, כ החברה מתנצלת לחבלול 11 מ'מכוניות ל לעזור לו לנצח את בדיקות פליטה. דגמי דיזל -Certain היו נועד עם תוכנה מתוחכמת שמידע משומש כוללים עמדת ההיגוי והרכב להאיץ כדי לקבוע את הרכב היה עובר בדיקות פליטה. תחת נסיבות ש, המנוע יפחית את פליטות רעילות. אבל המכונית הייתה מבוים כדי לעקוף כי כשזה היה מונע. פליטה מוגברת 10 עד 40 פעמים מעל רמות EPA מקובלות. [סוף ההשמעה] דוד י מלאן: אז בוא תסתכל על זה ולראות בדיוק איך זה יכול להיות מיושם ואיך ייתכן שזה משפיע כל כך הרבה מכוניות כמו זה. אז ביד שלי כאן הן העיתונות שחרור שהונפק על ידי EPA-- הסביבה סוכנות להגנה ש היא סוכנות הרגולציה האמריקנית ש מטפל בחששות סביבתיים, ולאחר מכן בפועל הודעה משפטית שהייתה לשלוח לפולקסווגן רק לפני כמה ימים. אז EPA כותב, וחושף כעת בפומבי, תוכנה מתוחכמת אלגוריתם על מסוים כלי רכב פולקסווגן מזהה כאשר המכונית עוברת בדיקת פליטה רשמית והופך את פליטות מלאים שולט על רק במהלך הבדיקה. היעילות של זיהום כלי רכב אלה מכשירי בקרת פליטות הוא מאוד מופחת במהלך כל הנסיעה הרגילה מצבים. התוצאה היא מכוניות שעומדות ב סטנדרטים במעבדה או הבדיקות תחנה, אך במהלך פעולה רגילה לפלוט oxides-- חנקן או NOx-- במהירות של עד 40 פעמים סטנדרטית. התוכנה המיוצרת על ידי פולקסווגן הוא מכשיר סוף ציטוט ציטוט, תבוסה, כפי שהוגדר בנקי חוק האוויר בארה"ב. הם ממשיכים ואומרים ש המשרד לאיכות הסביבה וסוכנות אחרת נחשף מכשיר התבוסה תוכנה לאחר ניתוח עצמאי על ידי חוקרים במערב אוניברסיטת וירג'יניה. זיהום NOx תורם ל דו תחמוצת חנקן, אוזון בגובה קרקע, וחומר חלקיקים עדין. חשיפה לאלה מזהמים נקשר עם מגוון רחב של השפעות בריאותיות חמורות, כולל אסתמה גדלה התקפות ונשימה אחרת מחלות שיכולות להיות רציני מספיק לשלוח אנשים לבית החולים. חשיפה לאוזון ו חומר חלקיקים יש גם נקשר עם מוקדם מוות עקב נשימה קשורה או לב וכלי דם הקשורים אפקטים. ילדים, הקשישים, אנשים עם מחלות בדרכי הנשימה קיימות מראש במיוחד בסיכון ל השפעות בריאותיות של מזהמים אלה. די הוא לומר, שזה די רציני. ובואו נלך על לקרוא רק קטע אחד יותר ואז נסתכל ההשלכות הבסיסיות זה בהקשר של מכונית. באופן ספציפי, פולקסווגן מיוצר ומותקן תוכנה שבנקראה בקרה אלקטרונית module-- או ECM-- של כלי רכב אלה שחשו כאשר הרכב שנבדק ל עמידה בתקני פליטת ה- EPA. בהתבסס על תשומות שונות, כוללים עמדתו של גלגל ההגה, רכב מהירות, משך המנוע של פעולה, ולחץ ברומטרי, בדיוק תשומות אלה מעקב הפרמטרים של הליך הבדיקה הפדרלי המשמש ל בדיקת פליטה לאישור המשרד לאיכות הסביבה מטרות. במהלך בדיקת הפליטה של ​​המשרד לאיכות הסביבה, תוכנת ECM כלי הרכב רץ תוכנה אשר מיוצרת תוצאות פליטה תואמת. בכל שעה האחרות, תוכנת ECM הרכב רץ כביש נפרד כיול שהקטין את האפקטיביות של מערכת בקרת פליטה כוללת, במיוחד קטליטית סלקטיבית הפחתה של NOx Lean trap-- שאנחנו עוד נראה ברגע. כתוצאה מכך, פליטה של ​​תחמוצות חנקן גדל בפקטור של 10 עד 40 פעמים מעל הרמות תואמות EPA בהתאם לסוג של מחזור כונן. אז מה זה אומר באמת, ו קוד מקור לריצת התוכנה על פולקסווגן יש לא עדיין נחשף בפומבי, הוא ש, ביעילות, זה שווה הוא איפשהו שם בפנים הקוד של פולקסווגן. אם אתה נבדקים, ואם המכונית מזהה גורמים סביבתיים מסוימים כמו ההגה עמדה או התנועה או היעדרה של המכונית או כל מספר של גורמים אחרים ששערו כרגע להיות חלק מנוסחה זו, הם פשוט להדליק פליטה מלאה. במילים אחרות, הם מתחילים פולטות פחות המזהמים. אחר, בכל מצב אחר כאשר הוא אינו מזוהה כ במעבדה, הם פשוט לא. ואז אתה יכול לפשט את זה ליותר פסאודו קוד בטון עם משהו אוהב את זה. אם הגלגלים פונים אבל ההגה הוא לא, רמיזות כי המכונית היא בכמה סוג של גליל מסתובב אבל באיזשהו מחסן נבדק, אז תתנהג כ המשרד לאיכות הסביבה הייתי רוצה ש. לעשות אחרת לא. אז בואו נסתכל בסרטון וידאו קצר ש לוקח מסתכלים על מה ההשלכות הם זה בעצם מכאני. [וידאו השמעה] -Last יום שישי ה EPA הודיע ​​כי חלק מכוניות פולקסווגן אאודי עשו בין 2009 והשתמש בזה שנה מכשיר תבוסה שנקרא לעקוף חוקי פליטה נועד לשמור על האוויר נקי. אבל מה זה אומר בדיוק? ובכן, יש לי מכוניות מודרניות עשרות מחשבים בתוכם. וחלק ממחשבים אלה לעזור לתאם את הפונקציות של המנוע לאופטימלי ביצועים תוך הקפדה שאין יותר מדי זבל יוצא מצינור הפליטה. הם בעצם עובדים בדרך זו במשך כמה עשורים. בעיקרון, כל חלק של המנוע של מכונית מודרנית יש חיישן או בקר על זה, ואלה מחשבים קוראים בנתונים אלפי פעמים בהתאמות קבלת השניה כמו היחס של דלק לאוויר זה הולך לצילינדרים. פולקסווגן רמאות אלה ודגמי אאודי הם דיזלים, ויש לי דיזלים אחד יותר מחשב חשוב באמת פרמטרים מבוקרים, שהוא כמות דלק שלא נשרף הולכת לפליטה. עכשיו זה נשמע רע. לא נשמע כמו שאתה רוצה דלק לא רצוי להיכנס לפליטה. אבל במקרה של דיזל, יש לך משהו נקרא NOx מלכודת שהוא מכשיר ש סופג ומלכודות לתחמוצות חנקן כי הם מזהמים שהייתם אחרת תלכו לאטמוספרה. ואת ההשפעה של שמלכודת NOx משופר עם דלק שלא נשרף. אז מכשיר תבוסה היא תכנית מיוחדת בתוך מחשבים אלה שיכולים לעשות את זה נראה כמו המכונית פוגשת פליטה סטנדרטים גם כאשר זה לא. היה לי פולקסווגן בעיה על ידיה. מנועי דיזל היו ידועים להשגת גדול במשק דלק, אבל מלכודת NOx עובדת רק טובה כאשר נמצא בשימוש יותר דלק. אז המכונית הייתה לזהות, שימוש במכשיר תבוסה זו, כאשר הוא מקבל את הפליטה בדיקה, שזה יהיה להשתמש יותר דלק, לעשות את עבודת מלכודת NOx גם, פליטות תהיה בסדר. אבל אז אתה מקבל על הכביש, המכשיר מכבה, אתה שורף פחות דלק אבל אתה לשים עד 40 פעמים יותר מזהמים לאטמוספרה. אבל איך לעזאזל עשו המכונית יודעת שזה היה נבדק לתאימות פליטה? המשרד לאיכות הסביבה אומרת שזה היה מתוחכם מערכת שבדקה את הדברים כמו גלגל הגה, מהירות, כמה זמן המנוע היה ב, ואפילו בלחץ אטמוספרי. במילים אחרות, היה אין דרך זה היה מקרי כי התוכנה הייתה תוכנן בזהירות רבה כדי לאתר בדיקת פליטה רשמית. זה קצת רציני למדי שטעייה וזה מדוע פולקסווגן הוא ב צרות רציניות כזה. למעשה, המנכ"ל שלהם, מרטין Winterkorn, רק ירד. אז מה קורה עכשיו? ובכן, אם אתה אחד מהמיליון והחצים Jettas דיזל, הביטלס, גרבי ברך, Passats, או יבוצע אאודי A3s, החדשות טובות היא היא כי המכונית שלך היא עדיין בטוחה לנהוג. אתה לא צריך לשים אותו משם עד פולקסווגן מנפיק זוכר. אבל בשלב מסוים הם כנראה הולך להיות כדי לעדכן את התוכנה בתוך המכונית שלך. כשזה קורה לך אולי תקבל פחות קילומטרים למכל. עורכי דין כבר מתכוננים לתובענות ייצוגיות כך בעלים עשויים לקבל פיצוי בשלב מסוים בעתיד. אבל זה לא הולך ל לקרות בזמן קרוב. [סוף ההשמעה] דוד י מלאן: אז זה מעלה למעשה שאלת תמונה גדולה יותר מעניינת כלסמוך. נכון? לכולנו יש מכשירי iPhone או אנדרואידים או משהו בכיסים שלנו סביר ביותר בימים אלה, או מחשבים ניידים על הברכיים שלנו, כי הם תוכנה פועלת עשתה על ידי אפל ומיקרוסופט וצרורות של חברות אחרות. אבל איך אנחנו יודעים כי מה ש מוצרי תוכנה אלה עושים הוא למעשה מה אלה חברות אומרים שהם עושים? לדוגמא, מי ל אומר שכל פעם שאתה לבצע שיחת טלפון ב- iPhone שלך או בטלפון אנדרואיד או כמו, שמספר הטלפון הוא גם לא שהועלה לשרת מסוים של חברה בגלל כמה תכנית שיש לך נכתב, בין אם זה ההפעלה מערכת עצמה כמו iOS או אנדרואיד, או בגלל שהורדת כמה יישום צד שלישי כי איכשהו הוא מקשיב לכל דבר שאתה מקליד באו כל מה שאתה בעצם אומר. איך אתה יודע את זה, כש אתם מפעילים קלאנג או הפוך ללקמפלך תוכנה של בCS50, איך אתה צוות של CS50 ש, בדרך של ספריית CS50, לא היה כל כניסה מחרוזת שאי פעם קיבלו או בכל רמ"ח איברים אי פעם קיבלו? ובכן, אתה יכול בהחלט נראה בקוד המקור של משהו כמו ספריית CS50, יכול להסתכל על קוד המקור למערכת הפעלה לינוקס פועל על IDE CS50. אבל הצגה מדהימה הוחזר בשנת 1984 בקבלת פרס טיורינג על ידי מדען מחשב מפורסם מאוד ידוע as-- קן תומפסון שם ש פרס טיורינג קיבל ש הוא סוג של המדע של מחשב פרס נובל, אם תרצה, עבור עבודתו על מערכת הפעלה בשם יוניקס, שהוא דומה מאוד ב רוח למה שאנו משתמשים בו היא לינוקס. והשאלה שהוא שאל בו נאום קבלה, מהות בהנחת המסגרת ל שנים על גבי שנים של דיון על אמון וביטחון, היה זה. באיזו מידה צריך אמון אחד הצהרה שprogram-- חתיכה של software-- הוא ללא סוסים טרויאניים? אולי זה חשוב יותר לתת אמון האנשים שכתבו את התוכנה. ולמעשה, אנחנו כבר מקושרים לשיחה שהוא נתן בעת ​​קבלת הפרס הזה בשנתי ה -80 באתר האינטרנט של CS50 תחת דף ההרצאות להיום. כי מה שתראה הוא שהוא בעצם נותן לי דוגמא פשוטה למדי של כמה אפילו מהדר כמו קלאנג או מה ש מהדרים אחרים השתמשו בעבר, מה אם משובץ בנו מהדר את עצמנו משתמשים הוא קצת אם מצב שבעצם אומר, אם אתה שם לב שהקוד הזה משתמש פונקצית GetString או GetInt הפונקציה, קדימה ולהכניס דלת אחורית או סוס טרויאני כך שתכנית ש עכשיו יש כמה אפסים ואלה שעושים משהו זדוני. כניסה לכולכם הקשות, העלאת נתונים ש לחלק שרת, או כל דבר באמת. ומה קן תומפסון ממשיך לעשות בהרצאה שלו הוא להוכיח שגם אם יש לך גישה למקור קוד של מהדר ש בזדון יכול להיות עושה את זה, זה לא משנה, כי יש עוף והביצה מציאות של רב בעבר שנים לפי מהדרים משמשים לקמפל את עצמם. במילים אחרות, דרך חזרה, כאשר מישהו היה שכתב את המהדר הראשון. ולאחר מכן, כל זמן שהם מעודכנים מהדר על ידי שינוי קוד המקור שלה, הוספת תכונות וrecompiling זה לאנשים כמונו להשתמש, גם, הם משתמשים ישנים גרסה של המהדר לקמפל החדש גרסה של המהדר. ואם אתה תסתכל בשיחה שהוא נתן, תראה את זה כי מעגלי ש, למעשה אתה יכול לקבל באגים או סוסים טרויאניים מוטבעים בתוכנה אנו משתמשים. וגם אם אתה מסתכל על קוד מקור לתוכניות אלה, זה אולי אפילו לא יהיה ברור כי בתחבולות היא למעשה בחלק הגרסה ישנה יותר של מהדר שמאז כבר הזרקת האיום לתוכנה שלנו. וזה רק כדי לומר, ש באמת לא יכול ולא צריך תוכנה פועלת על אמון המחשבים הניידים שלנו או טלפונים או כל מספר של מקומות. ואכן, מאוחר יותר בסמסטר הזה כש על תכנות אינטרנט אנחנו מתחילים לדבר ובעצם להתחיל לבנות יישומים עצמנו אינטרנט, נדבר על אלה איומים ואחרים. עכשיו, לך אולי תהית ושמת לב שיש דארת קטנטונת ויידר בסרטונים ש סף היה מראה שיש על פולקסווגן. אם שמעולם לא ראו, אני חשבנו שאנחנו צריכים להאיר מצב הרוח כי זה כל מאוד מדכא ומפחיד. אני הולך להסתכל אחורה בסופרבול 2,011 כאשר מסחרי על ידי Volkswagen-- וזה כמעט גורם להם חביבים again-- שודר לראשונה בטלוויזיה. זה הסרטון השני 60 כי אני חושב שאתה נהנה. [וידאו השמעה] [מוסיקה - נושא מתוך "מלחמת כוכבים"] [כלב נובח] [מכונית מתחיל] [סוף ההשמעה] דוד י מלאן: כן. אני רק בודק. המכונית שנמצאת ברשימה של הפרות. בסדר. אז אנחנו מסתכלים על כמה פסאודו קוד רגע לפני. והנה גדול יותר קטע קוד פסאודו קוד כי ראינו כמה פעמים עד כה. ובואו נשתמש בזה הזדמנות עכשיו להציג תכנות חדש טכניקה שעשינו לראות אלגוריתמי בשבוע שעבר כשהסתכלנו במין מיזוג. אבל בואו למסד אותה ולראות איך אנו עשויים להשתמש בו בקוד בפועל, ואז אנחנו הולכים להשתמש בזה טכניקה במורד הכביש ביותר סביר כדי לפתור בעיות מסוימות אחרות. אז זה היה אחת התוכניות הראשונות ש אי פעם כתב, אם כי בקוד פסאודו קוד. ומה בתכנית זו אפשר לנו לעשות קורס היה למצוא מייק סמית בספר טלפונים. ושים לב בקווים מסוימים שמונה ו -11 שהיו הצהרה עבור לזו. ולמעשה, מסוים שפות, C ביניהם, יש לי למעשה הצהרה שהיא, פשוטו כמשמעו, ללכת הלמאפשר לך לקפוץ לשורה מסוימת. זה בדרך כלל בעין יפה כי יכול להיות התעלל את זה מאוד בקלות ואתה יכול להתחיל לקפוץ שלך תכנית בכל המקום, בניגוד לשימוש בסוג של היגיון ובקרת הזרימה שהשתמשנו עד כה רק עם לולאות ותנאים וכדומה. אבל אנחנו יכולים לפשט אלגוריתם זה בקוד פסאודו קוד כדלקמן. במקום זה איטרטיבי או לולאת גישה שבו אנחנו כל הזמן חוזרים ו בחזרה וחזרנו לקו שלושה, למה אנחנו לא רק סוג של הדוגית ועוד בדרך כלל אומרים בשורה שבע ו -10, פשוט להחליף שני אלה זוגות של קווים עם, אחר אם סמית 'היא קודם לכן בספר שנציע ב לחפש את מייק ב מחצית השמאלית של הספר. אחר אם סמית 'היא שלב מאוחר יותר ב ספר, לחפש את מייק בימין מחצית הספר. ושים לב כבר המעגלי. נכון? אני מחפש מייק ב ספר טלפונים ולאחר מכן סופו של דבר פגע אולי קו שבעה או אולי קו 10 וההוראה שלי לעצמי הוא חיפוש למייק במחצית ספר טלפונים. ובכן, איך אני מחפש מייק? אני באמצע מחפש מייק, למה אתה סוג של שולח לי במעגל? אבל זה בסדר כי מה הוא קורה לגודל הבעיה, כפי שנכתב בקו 7 ו -10? אנחנו לא סתם אומרים חיפוש למייק, לחפש את מייק. אנחנו אומרים במפורש מה? חפש אותו במחצית השמאלית של המחצית הימנית שהיא ביעילות מחצית מגודלה של הבעיה. אז זה בסדר שאנחנו סוג של עוסק בהמעגליות זה, טענה חוזר זה, כי לפחות אנחנו מה שהופך את הבעיה קטנה יותר ויותר. וסופו של דבר אנחנו הולכים להגיע כי במקרה בסיס מה שנקרא בי יש לנו רק עמוד אחד left-- כמתנדב שלנו בשבוע שעבר did-- היו לנו עמוד אחד עזבנו ולאחר מכן אנחנו לא צריך לשמור מחפש מייק סמית בגלל שהוא או בדף או שהוא לא. אז איך אנחנו יכולים ליישם את הרעיון הזה, זה סוג של המעגליות בקוד בפועל? ובכן, אנחנו יכולים למנף את טכניקה זה ידוע בדרך כלל כרקורסיה. וראינו את זה ב פסאודו קוד לסוג מיזוג בשבוע שעבר. נזכיר כי זו הייתה פסאודו קוד לסוג מיזוג. זה לטעון אפילו יותר פשוט מיון בועות או בחירה או הכנסה רק במונחים של הפשטות שבה אתה יכול לבטא את זה. אבל זה בגלל ש אנחנו סוג של מעגלי אומר, לחפש משהו על ידי מחפש את זה שוב. אבל אנחנו מחפשים גם ב המחצית השמאלית או ימני המחצית ואז אנחנו סופו של דבר מיזוג במקרה זה. אבל גם כאן, עם שני קווי סוג, אלה היה לנו את זה שוב רעיון של רקורסיה. וקונקרטי מה זה אומר, בהקשר של אלגוריתם, הוא שאלגוריתם הוא רקורסיבית אם היא משתמשת או קוראת לעצמו. או במונחים של C, פונקציה היא recursive-- פונקציה שנקראת foo הוא רקורסיבית אם foo, אי שם בקוד המקור שלה, קורא foo הפונקציה עצמה. וזה רע אם כל foo אי פעם עושה הוא לקרוא את עצמו שוב ושוב. זה בסדר אם foo סופו של דבר ייעצר, כפי שעושה מיון מיזוג, באומרו, חכה רגע, אם בעיה זו היא סופר קטן, למשל, או שמצאתי לו מי אני מחפש, רק לחזור. לא באופן רקורסיבי, לא מחזור קורא לעצמי שוב. ואז בואו נסתכל איך זה באמת עשוי לעבוד. אז אני הולך קדימה ופתוח שתי דוגמאות קוד המקור כאן. אחד מהם נקרא סיגמא 0. וזה בכלל לא רקורסיבית, אבל בואו ניקח להסתכל על מה התכנית הזו עושה. אני כבר הפשטתי את כל הערות מזה, אבל כל של קוד המקור בCS50 של יש אתר אינטרנט הערות אם אתה רוצה לקרוא אותו שוב מאוחר יותר. ובואו נעשה זוג של שפיות בודק כאן. אז בחלק העליון של קוד זה, יש לנו כוללים CS50.h. מה זה עושה? למה הוא כאן? במונחים של ההדיוט סביר. מה זה עושה? כן. קהל: אז זה פונקצית GetInt עובדת. דוד י מלאן: אז זה פונקצית GetInt עובדת. בגלל בתוך זה קובץ, CS50.h, ש אנו רואים לפני זמן רב ב מבחינת קוד המקור שלה, יש חבורה של פונקציות declared-- GetInt, GetString, וחבורה של נוספות-- ואלא אם כן אנחנו באמת יש לי הכוללים קו, קלאנג מהדר הוא לא הולך יודע שהוא קיים. וכנ"ל לגבי קו שני שבו int מוגדר printf, שהיא פונקציה אנחנו שומרים באמצעות לא מעט. עכשיו, קו ארבעה נראה קצת פאנקי כי זה פשוט אניה אחת. יש לו פסיק, לא מתולתל פלטה, שאף קוד הפנימי שלו. אבל מה עשה שאנו מכנים הדבר הזה בעבר שבועות? כן. אז אב טיפוס. ולמה יש לנו אב טיפוס שנראה להיות קצת מיותר בדרך כלל, כי אנחנו בדרך כלל לראות את הפונקציה שוב מאוחר יותר בקובץ, נכון? אז למה אנחנו נו-- אתה פשוט מגרד את הראש שלך, אבל אני אקח אותה. כן. קהל: [לא ברור] פונקציה לאחר העיקרי. דוד י מלאן: בדיוק. כך שהמהדר יודע ש סופו של דבר להגדיר או ליישם פונקציה שלאחר עיקרי, ככל הנראה. אז קלאנג ורוב מהדרים הם סוג של מטומטמים והם רק תדעו מה אתה אומר להם. ואם ברצונך להשתמש פונקציה שנקראת סיגמא, כדאי ללמד מהדר שהיא קיימת מראש. עכשיו, עצמו עיקרי, אפילו למרות שזה חבורה של קווים, הוא די מוכר בתקווה על ידי החברה. יש לו לעשות בזמן לולאה מטרתו בחיים כאן כנראה הוא להגיע מספר חיובי מהמשתמש. ורק לשמור להציק לו או עד שהם משתפים פעולה. לאחר מכן, בקו 16 יש לי שיחה מעניינת. IntAnswer. שעל יד שמאל צד נותן לי Int אשר יכול store-- נקרא Answer-- שהוא הולך לאחסון, ככל הנראה, ערך ההחזרה של סיגמא. אז סיגמא הוא רק שם שרירותי אך משמעותי כי אני כבר ניתנו לפונקציה מטרתו בחיים הוא לקחת argument-- אחד אנחנו קוראים לזה N בcase-- זה ורק כדי לקחת את הסכום של מספר ש בתוספת כל מספר חיובי זה קטן יותר מזה. אז אם אני עובר במספר 2 ל סיגמא, אני רוצה להוסיף 2 בתוספת 1 בתוספת 0-- לא 0-- כך שנותן לי 3. אם אני עובר ב 3 לסיגמא, אני רוצה יש 3 ועוד 2 בתוספת 1, אשר נותן לי 6. וכן הלאה. אז זה רק מוסיף את כל מספרים קטנים או שווים לזה. עכשיו, כאן למטה אני פשוט הולך להדפיס את התשובה. אז כבדיקת שפיות מהירה, בואו להפוך סיגמא 0-- סיגמא הנטוי נקודת 0-- ותן לי להקליד 2. ואני אכן מקבל 3. תן לי להקליד 3. אני אכן מקבל 6. ואם כל אחד יכול לעשות את המתמטיקה במהירות, אם אני עושה 50 מה אני הולך לקבל? קהל: [לא ברור]. דוד י מלאן: ובכן, לא. אבל 1,275 וזה די קרוב. אז זה הוא התוצאה של עושה 50 בתוספת 49 בתוספת 48 פלוס 47 פלוס 46 כל הדרך למטה עד 1. אז זה כל סיגמא עושה. אבל בואו לראות איך יש לנו יישם את זה עכשיו. אז כאן היא הפונקציה עצמה. וזה לא נראה לי משהו לעשות עם רקורסיה עדיין. למעשה, אנו משתמשים טכניקת בית ספר ישנה. אני אתחול סכום משתנה בשם לאפס, אז יש לי foreloop כאן, ואני מכריז Int נקרא אני, הגדרת אותו שווה ל1-- למרות שאני יכול להגדיר אותו שווה ל אפס, אבל מאז שאני עושה בנוסף, למי אכפת אם זה אפס או אחד. זה הולך להיות כל השפעה. אז אני iterating כל עוד אני הוא פחות או שווה למ ', ש הוא הטיעון שהתקבל ב. ואז אני פשוט לשמור הגדלה I. ותובנה של הלולאה כל מה שאני עושה הוא עושה סכום בתוספת שווה I. וזה מכוון. אני לא רוצה לעשות, בזה מקרה, כמו סכום בתוספת בתוספת. אני רוצה להוסיף למעשה הערך הנוכחי שלי שהולך ונעשה יותר ויותר גדול וגדול יותר לנקודתי הריצה. ואז אני חוזר סכום. וכך תשובה מקבלת את סכום הערך. ואז אני להדפיס אותו. אז יש כאן הזדמנות, אם כי, כדי לפשט סוג של קוד זה מושגית והסוג של מכה אחת זה אכפת לי במונחים של פשטות למרות ש לוקח זמן כדי למיין של להעריך למה זה הוא חזק בדוגמאות הקטנות הללו. הנה סיגמא one-- כך גרסה שנייה של קוד זה. הכל למעלה הוא זהה כך שאותו סיפור חל כמו קודם. אבל עכשיו בואו נסתכל על יישום של סיגמא ש אני כבר שנותרתי בה רק אלה lines-- ארבע שורות של קוד, באמת, בתוספת כמה סוגריים מסולסלים ושטח לבן. אבל מה אני עושה? אם מ 'הוא פחות או שווה ל אפס, אני צריך להתמודד עם סוג של כי במקרה סופר פשוט. ואם אתה נותן לי אפס או כלום שלילי שהוא פשוט מוזר, אני רק הולך באופן שרירותי אבל לחזור באופן עקבי אפס. אני לא רוצה את הדבר הזה ל להיכנס כמה אינסופי מוזרה לולאה בגלל ערך שלילי. אז רק שאני אומר, אם אתה נותן לי אפס או פחות, אני חוזר לאפס. אבל זה טוב כי זה דף הבודד של ספר טלפונים מה שנשאר. אני נושך את בעיה מאוד ספציפית ולא קורא משהו באופן רקורסיבי. אבל בשורה 31, מה ש אני נראה עושה? הסוגריים רק שומרים דברים, אני מקווה, קצת יותר ברור. אבל כל מה שאני עושה הוא אני חוזר m-- מה אתה מוסר me-- בתוספת ערך של m-- מצטער, בתוספת השווי של סיגמא של מטר מינוס 1. אז מה זה אומר? אם אתה נותן לי את המספר 3 כקלט, התשובה אני רוצה לקבל סופו של דבר הוא 6 כי 3 בתוספת 2 בתוספת 1 נותן לי 6. אבל איך אני חושב על איך קוד זה פועל? בפעם הראשונה שאני קורא סיגמא ואני עובר בשווי 3, זה כמו להגיד על פיסה נייר, הנה הערך 3 וכבר עבר את זה לא כסיגמא. 3 הוא כמובן לא פחות מ 0 כך המצב אם אינו חל. האחר עושה. אז מה עליי לעשות? אני רוצה לחזור מ ', שהוא 3, בתוספת של סיגמא מ 'מינוס 1. אז תן לי לעקוב אחר זה. אני הולך לשים את זה פיסת נייר במורד. ומה ערך, להיות ברור, אני הולך לעבור לסיגמא בנקודה זו בסיפור הזה? איזה מספר? 2, נכון? 3 מינוס 1 הוא 2. אז אני רק צריך קצת פיסת נייר כאן. אז עכשיו סיגמא הוא מקבל נקרא שוב. וכבר במכוון אותי את זה כי זה כמו סוג של השהיית גרסה זו של הסיפור כי עכשיו אני ממוקד על אות מ 'של מינוס 1. אז מ 'היה 3, מ' מינוס 1 הוא 2. אז הנה הוא 2 כי אני כבר עברתי. 2 הוא כמובן לא פחות מ 0 כך מקרה שלא חל. אחר אני חוזר מ ', שהוא זה דבר, בתוספת של סיגמא מה ערך? אז אם סיגמא של 1-- כי מ 'הוא עכשיו 2 כך 2 מינוס 1 הוא 1. אז עכשיו יש לי רק את הערך 1. אני מעביר רק את המספר 1 לsigma-- הפונקציה או את עצמי כאן-- כך 1 הוא כמובן לא פחות מאפס, עדיין אינו חל. תמורה אחרת 1 בתוספת סיגמא של מה? 0. אז תן לי רק לזכור ש. אני אחזור לכך בהמשך. עכשיו אני הולך קדימה ויוד את המספר 0, כי זה הטיעון שלי או פרמטר. אני עברתי המספר 0 ולבסוף תהליך זה רק חוזר על עצמי מודעה nauseum אין להפסיק משום מה אני מייד לעשות ברגע שאני רואה את זה 0? אני חוזר לאפס. אז עכשיו אתה צריך להריץ אחורה את הסיפור. אם אני עכשיו הולך אחורה בזמן, מה היה הדבר האחרון אני עשיתי אם היית, פשוטו כמשמעו, אחורה וידאו? אני הולך להרים את האחרון 1 וזה נותן לי 1 בתוספת 0 הוא 1. אם אני שומר אחורה סיפור, שהולך לתת לי 2 בתוספת ערך זה פועל, שהוא 1. אז זה 3. ואז אני הולך לשמור וינדינג. כשהנחתי את המספר הראשון 3-- כך 3 ועוד 3 נותן לי 6. ועכשיו, אם אתה כבר rewound וידאו עד לנקודה זו, זה היה מאוד השאלה הראשונה ששאלתי. כאשר עבר 3, מה הוא סיגמא של 3? זה אכן 6, הסכום של את כל החלקים האלה של נייר. אז אם זה לוקח קצת זמן לעטוף את דעתך מסביב, זה בסדר. אבל רואים את זה היה little-- זה היה מאוד מכוון שאני נערם מספרים אלה על גבי זה. זה סוג של כמו שיש memory-- שיא ​​בזמן, כמו scrubber בוידאו, כי אני אכן יכול להריץ אחורה ב. ואנחנו הולכים לחזור ל מטאפורה שבקצת. אבל קודם, מתברר שיש הרבה חנונים ואנשים מצחיקים, אני מניח, בגוגל. היית מישהו שמאוד טוב במוח Googling מתקרב לרגע ו תעזור לי לחפש משהו? מפתח מאוד, נמוך מאוד. מישהו שאף פעם לא לבוא לפני, אולי. אוקיי. כן? בחייך. בואו למטה. מה השם שלך? סם: סם. דוד י מלאן: סם, בא למטה. זה אותו. נחמד לפגוש אותך. היי. בוא לכאן. אז כל מה שאני צריך שתעשה, אם אתה יכול, סם, הנה גוגל. אתה יכול לחפש את רקורסיה הטווח? אל תקלקל. ועכשיו let's-- כן. לחץ על אישור ש. טוב יותר לחץ על ש. אהה, לקבל את זה. לא? אוקיי. אז בואו נעשה כמה אחרים. לא כל כך הרבה בנושא אקדמי כאן, אבל יש לך אי פעם חיפש גוגל להיפוך אותיות? SAM: מס ' דוד י מלאן: אישור. חפש היפוך אותיות במקום רקורסיה. מה דעתך על אלכסון. אי פעם חיפש באלכסון? עכשיו, זה אחד זה קצת קשה אבל אני מקווה לראות everything's-- אישור. זה רק אתה ואני נהנים מזה. אוקיי. אז לבסוף, one's-- זה זה קצת באלכסון. עכשיו לעשות רול חבית. נפלא. בסדר. תודה גדולה לסם. הנה לך. תודה. אז מה קורה בכל דוגמאות המטופשות האלה? אז באמת, מתחת למכסת המנוע של מיליון של גוגל שורות קוד ככל הנראה הוא כמה טיפשי אם תנאים שהם במהות בדיקה אם יש למשתמש הקליד בביטוי הזה, לעשות משהו שכנראה לקח סכום טריוויאלי של זמן ליישם רק ל להיות משעשע בדרך זו. אבל זה כל מה שחין עד מתחת למכסת המנוע. אבל, כמובן, רקורסיה יותר מgeekier דוגמא בין טריקים מיוחדים אלה. ואין ספק שיש את האחרים שיש כמו גם שאולי יש לנו אפילו לא גילה עדיין. אז תסתכל, או לשקול עכשיו התכנית הבאה, ובהחלט לתפוס כל של אלה בדרך החוצה. אני הולך קדימה ו לפתוח את תכנית ש הולך לנסות להחליף שני ערכים. אבל לפני שאנחנו הולכים לשם, בואו נעשינו את זה. האם אנו יכולים לקבל אחד יותר מתנדב, אני חושב? האם אתה רוצה להתנדב? לא? בואו למעלה. בואו למעלה. בסדר. אז השם שלך הוא מה? לורן: לורן. דוד י מלאן: לורן. בואו למעלה, לורן. אז לורן הוא להיות אתגר כאן הוא כדלקמן. נחמד לפגוש אותך. אז לורן כאן יש בחזית שתי הכוסות הריקות שלה. ויש לנו כמה כתום מיץ וקצת חלב ואנחנו הולכים ללכת קדימה ולעשות את הדברים הבאים. אנחנו רק הולכים למלא את זה. כמה גרם של חלב לכאן ובואו למלא מיץ תפוזים קצת יותר כאן. ומול כל חברים אלה הקהל, להחליף את שני הערכים של הכוסות הללו. שים את מיץ התפוזים בכוס חלב והחלב בכוס מיץ תפוזים. איך היית עושה את זה אם היית ב הבית והיה לו גישה לאספקה ​​אחרת? לורן: שים את זה בכוס אחרת. דוד י מלאן: אישור. אז בואו זמני משתנה, אם יהיה. וללכת קדימה עכשיו וליישם אותו נוהל החלפה זו. כל כך טוב. אנחנו כבר לשים OJ לזמני משתנה, חלב לתוך משתנה OJ, ועכשיו משתנה הזמני למשתנת חלב. אוקיי. כל כך טוב מאוד שנעשה עד כה. אז מתברר out-- להחזיק ש חשבתי לרגע. הנה, לסתם חנון זה קצת, זה יהיה קוד C המקביל שאנחנו פשוט ליישם. היו לנו שתי כניסות, ו- B, שניהם שאנחנו פשוט נגיד לפשטות הם int של. ושים לב כאן, אם אני רוצה להחליף הערכים של שני משתנים, A ו- B, אנחנו אכן צריכים מתווך, משתנה זמני, כוס זמנית, שלתוכו יוצק את אחד הערכים כך שיש לנו מיקום עבורו. אבל אז הקוד הוא בדיוק כלורן כאן מיושם. עכשיו, רק כדי לקבל משוגע קצת, מתברר כי אתה יכול לעשות את זה בלי משתנה זמני. כדי לעשות זאת כראוי, אם כי, אנחנו הולכים יש לרמות עם כמה כימיה. יש לנו כמה כוסות נוספות כאן. אז הדבר הכי קרוב שנראה כמו perhaps-- חלב והמים או חלב וOJ-- הוא שיש לנו כמה מים, כדי שנמלא את זה עם כמה אונקיות של מים צלולים. זה כנראה יותר מדי. כן. זה בהחלט יותר מדי. חכה רגע. ועכשיו יש לנו נפט, אשר, כפי שאני זוכר ממחלקה לכימיה בבית הספר התיכונה, אני מקווה שזה לא לערבב עם מים. אבל זה סוג של סוג של נראה כמו חלב וג'יי. אז עכשיו, ללא שימוש ב משתנה זמני, אתה יכול להחליף את שני הערכים האלה? אז שמנים הולכים לכוס המים, מים נכנס לכוס השמן. לורן: לא כוסות אחרות? דוד י מלאן: לא כוסות אחרות. ולי לא ממש בדק את זה לפני השנה אז אני לא יודע אם זה יהיה באמת עובדים כימי. שלא היה אמור לקרות. האם זה עובד? בסדר. אז הפרדה? טוב. עכשיו יש לנו כדי לקבל את מים לתוך הכוס אחרת. ריכוז כימיה חכם יכול כנראה לעשות את זה יותר טוב ממני. לורן: המים זה בתחתית. דוד י מלאן: water-- שהיה מה מפתח הפעם האחרונה שעשינו את זה. אתה צריך לעשות את זה בסדר הנכון. כן. זה בסדר. אז עכשיו יש לנו שתי כוסות של שמן. אוקיי. זה בסדר. אבל אם זה עבד כימי מאשר אני- לורן: זה מים. דוד י מלאן: זה בעיקר מים. בסדר. אבל זה עדיין אותו הכוס כמו קודם. אז לשפוך it-- לנסות את זה שם. אוקיי. זהו שימוש טוב של זמן בכיתה היום. אוקיי. אז עכשיו we-- נחמד. בערך. בסדר. אז מאוד טוב. תודה ללורן. מאוד יפה מאוד. אז רק כדי לפוצץ את דעתך, וזה אולי משהו לשחק עם אם תרצו בזיהוי CS50, אתה יכול, למעשה, להחליף את שני משתנים ללא שימוש במספר שלם זמני. וזה קוד C המקביל. ואם אתה זוכר שמעברת יום רביעי, הצגנו, אם לזמן קצר, כמה מפעילים חדשים בג ועושה מישהו זוכר מה הגזר הקטן סמל הוא, כי משולש קטן סמל מהמקלדת מייצג? מה סיבי האופרטור מפעיל? קהל: EXOR. דוד י מלאן: EXOR. בלעדי או. אז אם אתה רוצה, רק בשביל כיף ב בית, לתת וב שני שרירותי ערכים כמו כל eight-- ואני היה בוחר ערך שמונה קצת. אם אתה עושה את זה עם 32 סיביות, אתה משתעמם מהר מאוד. אבל רק לתת קצת שמונה ערך זה מה ש, אחד או שניים, ולתת לי ב ערך דומה. ולאחר מכן באמצעות ההגדרה של XOR מיום רביעי שעבר, חלים שלאט לאט, כל אחד מ שמונה סיביות בכל אחד מאלה וב, ואז לעשות את זה בדיוק לקוד זה. וזה לא נכון מה אתה רואה כאן על המסך. זה אכן מסתכם לשלוש פעולות XOR ואיכשהו באורח פלא ו ב יחליף תפקידים מבלי לאבד את כל מידע. אז טריק השמן ומים הוא גלגול עולם אמיתי קרוב אני יכול לחשוב עליו כדי לחקות את זה. אבל זה בוודאי קל יותר להשתמש משתנים זמני, כמו במקרה זה כאן. וגם זה הזדמנות לומר, מדי, של מיקרו אופטימיזציה סוג זה, כמדען מחשב הייתי אומר, אילו סוג של כיף להתרברב איך עשה את זה בלי כמו החלפה עם משתנה נוסף, זה לא כל כך משכנע. בגלל להציל 32 סיביות, כ במקרה של int בפועל, לא כל כך משכנע במערכת שבה ייתכן שאתה משתמש עשרות מגה בייט או זיכרון כזה עוד יותר בימים אלה. ואכן, כאשר אנו מקבלים לקבוצת בעיה מאוחר יותר ואתה מיישם כישוף בודק ואתה לערער לעשות זאת עם זיכרון RAM קטן כמו זה וקצת כ זמן ככל האפשר על computer-- אתה עדיין יש לי שבוע ליישם it-- אתה נו-- אתה תהיה מאותגר כדי למזער את המשאבים הללו. וזה באמת רק חובילח סמסטר זה שבו תוכל להיות מעודד לגלח את אפילו הביצועים הטובים ביותר עולה אחר. אז יכולים what-- איך אנחנו רואה את זה בקוד בפועל? תן לי ללכת קדימה עכשיו ולפתוח את הדוגמא שבכוונה נקרא לא להחליף, כי זה לא למעשה להחליף את המשתנים כפי שאתה בעצם יכול לצפות. אז בואו נסתכל. הנה תכנית שאין לה CS50 ספרייה קורה, I / O סטנדרטי פשוט. עכשיו יש לנו אב טיפוס להחלפה למעלה שרק אומר שזה חייב להיות מוגדר מאוחר יותר. והנה עיקרי. אני באופן שרירותי שהוקצה x ו- y, בהתאמה, אחד הערכים ושני רק בגלל שהם קטנים וקל לחשוב עליו. ואז יש לי רק חבורה של printfs שבו יש לי צ'ק על שפיות. x הוא 1 ו- y הוא 2 הוא ככל הנראה מה printfs אלה יגיד. אז לא קסם עד כה. אז אני הולך לתבוע ב להדפיס def, החלפת נקודת נקודת נקודה. אני הולך להתקשר להחלפה פונקציה, עובר בx ו- y. ובואו נניח לעת עתה ש החלפה מתבצעת בדיוק כפי שהיה לפני רגע עם משתנה זמני. ואז אני טוען באומץ, החליף. x הוא עכשיו זה וy הוא החברה ש. אבל את הקובץ, כמובן, נקרא לא להחליף. אז בואו באמת רואים מה קורה. אם אני לא לקמפל החלפה ולאחר מכן לעשות ./noswap, x הוא 1, y הוא 2. החלפה החליף. x הוא 1, y הוא 2. כך זה נראה למעשה להיות פגום גם למרות swap-- בואו לגלול למטה now-- מיושם בדיוק ל קוד הצעתי לפני רגע. אז אנחנו לא הולכים לקבל מפוארים עם חומר XOR לעת עתה. גם זה, רק צריך לעבוד כמו עם חלב וג'יי, אבל זה לא נראה שזה עובד. אז בואו נעשה את זה שוב. אולי אני פשוט לא רצתי את זה נכון. אז בואו לרוץ לא להחליף שוב. אולי אני- לא. אז זה פשוט לא עובד. אז בואו לעשות בדיקת שפיות קטנה. תן לי ללכת קדימה כאן בהחלפה ורק להוסיף, חכה רגע, הוא אני% / n ובוא התוספת הערך של. כי אני באמת רוצה כדי לראות מה קורה. ואכן, זה הוא טכניקת ניפוי שייתכן שאתה משתמש ב שעות משרד או בבית כבר, בדומה למחצית הראשונה של דן הווידאו של Armendariz בPSET3 שבו אנו הצגנו הדפסת def כ טכניקה מומלצת, לפחות במקרים פשוטים. תן לי ללכת קדימה ולרוץ לעשות אין החלפה שוב, ./noswap. מעניין. אז שם לב מה שנראה אמיתי. איקס הוא 1, y הוא 2, אבל הוא 2 כאשר b הוא 1. אז שני אלה איכשהו החליפו אבל x ו- y לא מקבלים החליפו. אז כדי להיות ברור, מה שקורה הוא, כאן יש לי x ו- y ואלה הם משתנים מקומיים ב היקף העיקרי, אני מעביר בx ו- y כדי להחליף. עכשיו, החלפה, כפונקציה נפרדת, הוא חופשי להתקשר טיעוניה או כל דבר הפרמטרים שלו שהוא רוצה. Foo או בר או x או y או או ב. רק כדי להבהיר שהם אינו זהה לx ו- y כשלעצמה, אני כבר אמרתי וב. אבל אנחנו יכולים לקרוא להם כל מה שאנחנו רוצים. וכך זה נראה כמו ההחלפה מתבצעת עברה x-- AKA זה-- וזה שעבר AKA ב y--. איכשהו שלושת קווים אלה החלפת ערכים אלה בדיוק כלורן עשה עם חלב וג'יי. אבל כאשר אנחנו להדפיס הערכים, A ו- B אכן להחליף אבל x ו יש לי y ללא שינוים. נזכיר כי x ו- y הם כאן. אז אנחנו יכולים לראות את זה באמצעות טכניקה אחרת גם כן. וגם זה טכניקה משובץ בבעיה להגדיר שלוש. בואו נלך קדימה ולעשות את זה ב CS50 מזהה אם אתה לא כבר יש. עלינו צד יד ימין יש לי כרטיסיית Debugger זה. ואם אתה פותח את זה, יש איזה מידע מסתורי זה שזרק אותך בהתחלה. אבל בואו להפריד זה ממש מהר. אז אחד, אתה רואה משתנים מקומיים. מתברר כי לבנות לIDE CS50, ו הרבה סביבות פיתוח נוסף בדרך כלל, הוא הבאגים. כלי שמאפשר לך לראות באופן חזותי מה קורה בתוך התכנית שלך מבלי להזדקק להוספה printfs ועריכה והפעלה והוספה של printf והידור ו ריצה, שכבר, בשעתי עבודה או בבית, הוא כנראה מקבל די משעמם. אז הנה, ברגע, אנחנו הולך לראות בזמן אמת הערכים של המשתנים המקומיים שלנו. אנחנו גם הולכים להיות מסוגלים להגדיר מה שנקרא נקודות עצירה ש הזדמנויות בתכנית שלי כדי להשהות ביצוע בשורה מסוימת של קוד כי אני סקרן לגבי. נכון? תוכניות אלה מנוהלות בשבריר שני. זה סוג של נחמד לבני אדם האיטיים כדי להיות מסוגל להשהות, לקחת רגע, לראות מה שקורה סביב קו מסוים של קוד ללא חריש התכנית דרכו וסיימתי לגמרי. אז נקודות עצירה הולכת כדי לאפשר לנו לשבור ולהשהות בשלב מסוים. ערימת שיחה היא דרך מפוארת של אומר מה פונקציות כרגע להיקרא באותו הרגע. ראשי תמיד נקרא ראשון. אבל אם ראשי קוראים פונקציה שנקראת החלפה, אנחנו באמת הולכים לראות את זה מגדל של פונקציות שהיו נקרא בסדר כרונולוגי הפוכים. אז בואו לראות את זה. אני הולך להקטין את התצוגה. אני הולך לחזור לקוד שלי. ורק בגלל שאני רוצה להיות קפדן כאן, אני הולך קדימה ולחץ רק בצד השמאל של קו חמש. וזה יוצר נקודה אדומה. ושים לב בצד ימין שהבאגים יודעים, היי, אני רק אמרתי נקודת עצירה ב במיוחד קו noswap.c חמש, בקו הזה של קוד. אז הבאגים יודעים אני ש ביקש שבפעם הבאה אני מפעיל אותו להשהות את התכנית שלי ביצוע יש ולא רק מנהל את כל עסק סופר מהיר. אז עכשיו אני הולך ללחוץ על Debug כפתור בחלקו העליון של IDE וזה הולך לעשות את הדברים הבאים. זה הולך לפתוח בתחילה מעט מסוף שני מחפש מפחיד window-- איתור באגים מרחוק מ לארח כזה וsuch-- ואנחנו נחזור למה ש כל זה אומר שלפני זמן רב. אבל מה שחשוב עבור החברה הוא שהנקודה אדומה נפגעה, הבאגים יש במכוון עצרתי execution-- לא על קו שכשלעצמם אלא בראשון שורת קוד בפועל בתפקיד זה. ולכן קו שבעה הוא עכשיו מודגש בצהוב. ועכשיו בואו נסתכל בצד ימין. זה נראה כמו, כברירת מחדל, יפה מספיק, יש x מה ערך? 0. ויש לו y מה ערך? אפס. וזה צפוי במובן שx וy-- שיש line-- הצהוב לא בוצע עדיין. אז x לא צריך את ערך 1. אולי יש לו כל ערך אחר, ערך זבל שנקרא. והיינו לנו מזל שבזה אפס בנקודה זו, במהות. אז עכשיו יש רק כמה כפתורים שאנחנו צריכים לטפל על כאשר באגים בדרך זו. שימו לב כאן, יש לנו לחצן הפעלה. ואם נשחקנו או נפגע לחדש, זה רק הולך לרוץ דרך שאר התכנית או עד שהוא מגיע נקודת עצירה נוספת. אבל אני כבר לא קבעתי אחר נקודות עצירה כך שזה רק הולך לרוץ עד הסוף. סוג זה של תבוסות המטרה לחטט. אז במקום, אכפת לי סמלים אלה בצד הימין. ואם אני מרחף מעל שלהם, כפי שאתה גם צריך, תראה טיפים כלי tips-- קטנים. זה אחד הוא לדרוך על. עכשיו זה לא אומר שדלג את השורה הבאה של קוד. זה רק אומר לבצע את זה ו להעביר למשנהו, להעביר למשנהו, להעביר למשנהו. במילים אחרות, באמצעות כפתור ש, אני יכול ללכת באמצעות הצעד שלי קוד אחד בכל פעם. שורה אחרת שורה, פשוטו כמשמעו. עכשיו, בצד הימין של כי, יש עוד אחד שנראה ברגע. זה מה שנקרא צעד לתוך סמל זה הולך כדי לאפשר לי צלילה לפונקציה אחרת. אבל בואו יראו את זה ברגע. אז אני הולך ללחוץ לדרוך על. ועכשיו שם לב, כפי שאני לוחץ לחצן זה בצד ימין למעלה, לשמור על העיניים שלך בערך פי מקומי משתנים ולראות מה קורה לx. x הוא כעת 1 כי קו צהוב עכשיו ביצע ואנחנו כבר עברנו לקו 8. ורק y רגע צריך לקוות להיות 2. עכשיו, שום דבר שמעניין קורה לקצת. כל זה הוא printf. ושים לב, במסוף המשני שלי חלון, אני רואה את הפלט של def הדפסה. ועכשיו אני צריך לעשות החלטה כמתכנת. אני יכול לדרוך על הקו הזה של קוד, הרצתו אבל לא מקבל סקרן לגבי מה שבפנים. או שאני יכול באמת להיכנס לזה ולהיכנס פנימה של החלפה עצמו. אז בואו נעשה את זה האחרון. תן לי ללכת קדימה ולחצו לא שלב במהלך אבל צעד לתוך. שים לב, פתאום חלון השינויים כדי להדגיש הראשון שורת קוד בהחלפה. זהו קו 21. ועכשיו, מה סוג של פאנקי הוא ש, אם אתה מסתכל על כאן, כצפוי, ב פסיק הוא 1 ו -2, בהתאמה. למה הוא זמני 32,767? נזכר זמני ש, בדומה הכוס הריקה לפני רגע, הוא הכריז כאן על קו 21. למה 32,000- אני מתכוון, למה הוא זה רק חלק הערך מוזר? כן? קהל: זה לא אותחל. דוד י מלאן: זה לא אותחל. אז המחשב שלנו תמיד יש זיכרון פיזי. תמיד יש לו זיכרון RAM הפיזי. ותמיד יש אפס של ואחד שנמצא שם, נכון? מכיוון שאנו משתמשים מחשב כל היום, אתה משתמש IDE CS50 או השרתים כל היום. אז RAM כי יש גם כמה אפסים או חלק אחד של חלק או את האפסים ואחדים. לא משנה אם או אתה לא משתמש בהם. אתה לא יכול פשוט יש לי ריק חללים שבו אתה רוצה ביטים. הם גם אפסים ואחדים. אז מתברר זמני, כי לא אנחנו כבר אותחלו את זה עדיין, יש לנו 32 סיביות אלה אבל יש להם לא אותחל לכל ערכים ידועים. אז כל מה שהם היו רוב בשימוש לאחרונה for-- אלה 32 bits-- אנחנו רק רואים את החפצים של כמה שימוש קודם של 32 בפרט אלה ביטים. ברגע שלוחץ על שלב מעל אם כי, אוף, טמפ הוא הולך לקבל את הערך 1. ואם אני עושה את זה שוב, הוא הולך להיות נתון הערך 2 ולאחר מכן ב הולך יינתן הערך 1. ואז מה נחמד עכשיו ב נקודה זו של הסיפור הוא שהבאגים הוא מראה לי, סופר לאט בקצב שלי, מה ש המצב של החלפה הוא. אבל שם לב שבחלק העליון כאן, הודעה שערימת השיחה בפועל יש לו שתי שכבות לזה. עכשיו אחד שמודגש כ החלפה, אם אני לוחץ על ראשי במקום, שימו לב כמה המשתנים המקומיים לשנות כי המפתחים פשוט יכולים לקפוץ סביב ולהיכנס לכל היקף שונה. אז למרות שאנחנו עושים את כל זה לעבוד בצורה נכונה והחלפת A ו- B, אם אני הולך קדימה ואחורה בין החלפה שבו הוא 2 ו- B הוא 1 וראשים, יש ראשי נפגעו בכלל? מס ' אז מה takeaway כאן? ובכן, מתברר שכל זמן אתה קורא לפונקציה כמו החלפה, ואתה עובר את טענותיו, מה ש אתה עובר לפונקצית החלפה במקרה זה הוא עותק טיעונים אלה. אז אם x ו- y הם כל בהתאמה 32 סיביות, מה שהחלפה הוא מקבל הוא מקומי שתי חדש משתנים, או טענות, נקרא וb-- אבל אלה הם שרירותיים names-- אבל הדפוס של אפסים ואלה בתוך A ו- B הם בשורה לתהיה זהה לx ו- y אבל הם לא אותו דבר כמו x ו- y. זה כאילו ראשי יש בחתיכה שלה נייר המספר 1 ו -2 לx ו- y, ואז כשזה ידיים ש פיסת נייר כדי להחליף, החלפה מקבלת מהר מאוד העט שלו, רושם 1 ו -2 על גיליון נייר משלו, ידיים לגבות XY המקורי לראשים ואז עושה משלו דבר עם A ו- B. וזה עכשיו סופר חשוב כי יש לכך השלכות לא טריוויאלי לבעצם כתיבת קוד נכון כי זה היה נראה שאנחנו לא יכולים להחליף שני משתנים. כתבתי פונקצית החלפה נכונה. אנחנו התקנו אותו עם לורן כ פונקצית החלפה נכונה במציאות, אבל כנראה אף אחד שמ עניינים אם אתה לא יכול למעשה להחליף שני ערכים באופן קבוע. אז אנחנו צריכים בדרך אחרת כדי לקבל למעשה בשלב זה, ואנחנו צריכים להיות מסוגלים למעשה לפתור את הבעיה הזו. ומתברר out-- ואנחנו נבוא חזרה לתמונה מסוימת זה לפני long-- זו דרך אחת ש אולי אתה מצייר זיכרון של המחשב שלך. זה רק מלבן. אתה יכול לצייר אותו בכל מספר הדרכים אבל זה נוח לצייר אותו כ מלבן מהסיבה הבאה. אנחנו הולכים להתחיל היום ומעבר מדבר על הערימה שנקרא. והערימה היא רק נתח של RAM-- נתח של memory-- כי יש פונקציות גישה כאשר הם נקראים. וכך מתברר כי ב תחתית ערימה זו מקום שבו כל המשתנים המקומיים של ראשי ו- C org וV org וכל הדברים האלה הולכים ללכת כברירת מחדל. ואם ראשי קורא תפקיד אחר כמו החלפה, גם, החלפה הוא הולכת לקבל עוד שכבה של זיכרון עד מעליו. וכך, רק כדי לתת לך שטחי מהירה תמונה של זה, אם אני הולך על כאן-- ותן לי המראה הזאת ב מעל כ"תראה מה באמת יש לי, אם אכפת לנו רק על חלק תחתון של תמונה זו לעת עתה, הוא שכאשר אני מפעיל את תכנית והראשים מקבל נקראים, ראשי ניתן נתח של זיכרון RAM במחשב שלי שהוא בתחתית ערימה זה מה שנקרא. ואני הולך לצייר אותו בכוונה כריבוע. אז זה כמו 32 ​​סיביות או ארבעה בתים. ואם פונקציה העיקרית זה יש x משתנה בשם עם ערך של 1 ויש לה משתנה בשם y עם הערך של 2, זה כמו לקחת רסיס זה של זיכרון ש ראשי ניתנו על ידי ההפעלה מערכת וחלוקה אותו כך ש משתנה המקומי הראשון הולך כאן, השנייה אחת הולך כאן, וזהו זה. כאשר ראשי קוראים החלפה, החלפה מקבל פרוסת זיכרון משלו שאנחנו לצייר ככה ממערכת ההפעלה, וזה הולך לה מבוסס משתנים מקומיים של ביישום שלנו קודם לכן עם משתנים מקומיים וb שתחילה לקבל את הערכים 1 ו -2. אבל אז, ברגע ש קוד החלפה מבצע, ולורן מחליפה למעשה ג'יי וחלב, מה קורה? ובכן, 2 זה הופך 1, זה 1 הופך 2, ו, דרך אגב, יש משתנה זמני זה להיות שימוש שכל הזמן שסופו של דבר הולך. אבל זה לא משנה כמה עבודה שאתה עושה בשורה זו ל-- במרחב זיכרון זה, x ו- y הם נגע לחלוטין. אז אנחנו צריכים איזו דרך הנתינה החלפה ופונקציות כמו זה גישת סוד, אם תרצה, ל פונקציות like-- לזיכרון כמו x ו- y. אז בואו נסתכל דוגמא שעוזרת שלנו לראות בדיוק מה היה הולך על זה כל זמן. אני הולך קדימה ולפתוח השוואה אפס. ואני הולך לסגור הבאגים שלנו, אני הולך כדי לסגור הודעה מחפשת זה מפחיד רק אומר, חכה רגע, אתה באמצע הניפוי. אני הולך להסתיר כרטיסייה זו כאן רק כדי לחזור לפשטות. אז אל תדאגו אם GDB נהרג. זה רק אומר שיש לו את התכנית כבר להפסיק, בכוונה במקרה זה, על ידי. ועכשיו שקלו אפס עושה את זה. אני משתמש CS50 ספרייה בקלט / פלט סטנדרטי. יש לי פונקציה העיקרית שראשון אומר, לומר משהו, ומקבל מחרוזת. אז אומר את זה שוב ו מקבל מחרוזת אחרת. ושים לב ששתי מחרוזות אלה נקראים ים ולא, בהתאמה. ועכשיו בתכנית זו, שקלו אפס, המטרה שלה בחיים, זה אמור להגיד לי, לא אני מקליד את אותו הדבר? ואז אני חוזר לשבוע אחד. אני משתמש המפעיל שווה שווה שלי שהינה מפעילת האיכות. לא מפעיל המשימה, מפעיל השוויון. אני רק השוואה של ולא. אז בואו באמת ללכת קדימה ולעשות את זה. ואני הולך קדימה ולעשות השוואת אפס. אני הולך לעשות ./comparezero. ואני מתכוון ללכת קדימה ולומר משהו כמו, בואו נעשה את אמא באותיות קטנה ומה לגבי אמא באותיות גדולה. וכמובן אני מקליד דברים שונים. בסדר. זה היה צפוי. בואו להפעיל אותו שוב. בשתי פעמים לעשות אותיות קטנות, אותיות קטנות. זה נראה סופר זהה לי. הזן. אוקיי. אולי זה פשוט מוזר כי זה לא לחבב את הדקדוק שלי. אז בואו לעשות MOM הון, ההון MOM, זהה. דברים שונים. אז למה זה? ובכן, מה באמת הולך במתחת למכסת המנוע כאן? אז בואו נחזור על כאן לרגע ולשקול מה GetString הוא בעצם עושה. כשאתה מתקשר GetString, זה אנחנו פונקציה את עצמנו כתבנו וזה איכשהו מקבל רצף של תווים מהמשתמש. ונניח שראשון זמן אני קורא GetString, שנותן לי נתח של זיכרון שנראה כך. ואם הקלדתי בכל האותיות הקטנות מ 'O-m-- ומה שקורה אחרי זה? רק בדיקת שפיות מהירה. אפס קו נטוי. אנחנו יודעים את זה. וזוכרים ששחקנו סביב עם שמו של Zamila וחבורה של שמות אחרים כאשר רוב היה כאן מחפשים על מה שקורה בתוך זיכרון. אז סיפור זה בדיוק אותו הדבר. זה מה שGetString חוזר אליי. עכשיו, הקוד שלי רגע לפני מאוחסן ערך ההחזרה של GetString בשם של במשתנה. ואז, בפעם השנייה אני קורא לזה, זה מאוחסן בזה לא משתנה בשם. אז אם אני הולך לכאן, אני צריך לצייר variable-- המקומי זה ואני בדרך כלל הולך ל לצייר מחרוזת כפשוט-- שנציע ב קורא לזה s-- כריבוע קטן כאן. ועכשיו, somehow-- איך אמא ללכת בתוך ים משתנה זה? ובכן, אנחנו צריכים לחזור לעקרונות הראשונים כאן. מה GetString חוזר בעצם? אז מתברר שM-O-M קו נטוי אפס, וכל מספר מיתרים אחרים בזיכרון כמו Zamila ורוב או אנדי או כל האחרים, כמובן בנו זיכרון RAM של המחשב או זיכרון. והזיכרון RAM שלך יש like-- יש לך חלטורה של זיכרון RAM, שתי הופעות של זיכרון RAM, או מיליארדים או שני מליארד בייטים, או אולי אפילו יותר בימים אלה. אז בואו נניח, למטרות של היום, כי זה לא משנה איך אנחנו מונים שלהם, אבל אנחנו יכולים למנות כל מאותם מיליארדים או שני מיליארדים או ארבעה מליארד בייטים. ובואו רק באופן שרירותי אומרים ש זה הביס הראשון, הנגיסה שנייה, שלישי, רביעי. אני לא במכוון באמצעות אפס ל היום אבל אנחנו נחזור לזה. אז במילים אחרות, אם זה פעם הראשונה שאני משתמש בתכנית, אני רק מקבל מזל וראשון נשיכה היא במיקום אחד ואז שתי אז שלושה מארבעה. ואם אמשיך ציור, מספר התיבה שני מליארד יהיו דרך לכאן. אז מה אתה חושב, אז, GetString חוזר בעצם? זה לא חוזר קו נטוי M-O-M אפס כשלעצמה, משום שברור לא יתאים בתיבה שאני נמשך. אז מה עוד יכול GetString למעשה חוזר כל השבועות האלה? התשובה היא ב מנהלים כאן איפשהו. אתה לא יכול להתאים קו נטוי M-O-M אפס, אז מה יכול להיות הגיוני במקום? אם היית צריך להיות סופר חכם, לשים על כובע ההנדסה שנקרא, מה אתה יכול לחזור? מהו הסכום לפחות של מידע אתה יכול לחזור כי היית עדיין לך למצוא M-O-M בזיכרון? כן? קהל: אחת. דוד י מלאן: אחת. ולמה אחד? קהל: כי זה הייתי אומר לי לך לאן ללכת [לא ברור]. דוד י מלאן: בדיוק. אני רק הולך להחזיר את כתובת של המחרוזת שאני מקבל. הכתובת בזה מקרה הוא מקום אחד. אז מה באמת מאוחסן בs-- וכל כך משתנה מחרוזת far-- רק היה כתובת של מחרוזת ש. בינתיים, אם אני קורא GetString פעם שנייה ואני הקלד ב, פשוטו כמשמעו, באותו thing-- M-O-M עם M-O-M lowercase-- וקו נטוי אחר אפס, ועכשיו אולי התכנית שלי של כבר פועל מזה זמן אז אולי זה הוא 10, זה מיקום 11, זה 12, זה 13. המחשבים באמצעות כמה אחרים זיכרון מכל סיבה. מה עכשיו הולך בשני שלי משתנה בt התכנית שלי? 10. בדיוק. ולכן כאשר אנו מסתכל על קוד מקור של תכנית זו שבו אני פשוט מנסה להשוות בין שני ערכים, הוא זה שווה שווה לt, מה התשובה האנושית הברורה? רק לא כי 1 לא שווה 10. וכך טמון הזדמנות עבורנו באמת רק כדי לחזור ל, שוב, ראשון עקרונות וחושבים על, ובכן, מה קורה מתחת למכסת המנוע? אנחנו כבר מדברים על פיסות בתים וזיכרון, אבל זה באמת שימושי כדי להבין כי כשאתה קורא GetString, למרות שאנו חושבים על זה חוזר M-O-M או אמא מחרוזת או אנדי או Zamila או כמו, מבחינה טכנית זה פשוט מחזיר את הכתובת של נתח זה של זיכרון. אבל זה בסדר. כי איך אני יודע איפה המחרוזת מסתיימת? אם אני רק נתתי ההתחלה? ובכן, הקו הנטוי אפס, נכון? בדיוק בזמן ליניארי שאני יכול להדפיס עם M-O-M def ההדפסה. וברגע שאני רואה את קו נטוי אפס, לא אכפת לי שבו התחלתי, אני כבר יודע במשתמע שבו אני צריך לסיים. וכך היום מסמן את beginning-- ו תן לי לעשות את זה כי אנחנו באופן דרמטי עבר הרבה צרות ל להגיע לכאן אלה הכשרת wheels-- אז היום את הגלגלים העזר להתחיל לרדת ואנו חושפים בleast-- [מחיאות כפות] זה היה בהחלט שווה את הנסיעה ליעד זה בבוקר, כן? אז now-- יש, מתברר את, אין דבר כזה מחרוזת. מחרוזת לא קיימת. זה מילה נרדפת שהיו לנו בתוך ספריית CS50. מכאן ואילך, אנחנו הולכים להתחיל לקרוא ים ולא לא מחרוזות אבל כוכבי char. וכוכב char שנציע ב להפריד לפני זמן רב. אבל זה אומר, כי גם אם אנו ממשיכים באמצעות GetString לעכשיו, מבחינה טכנית אני צריך להיות כוכב אומר char וכוכב char. ומתברר מה כוכב ש הולך לציון הוא משהו בשם מצביע או כתובת. ולמעשה, טיזר למה שלפנינו הוא קליפ שני זה 20 משלנו חבר ניק Parlante בסטנפורד ש, לפני די הרבה זמן, לבלות סכום מגוחך של זמן, כטוב ביותר שאני יכול לומר בו מטבח או במרתפו, מה שהופך את האולפן מציג לעולם דמות בשם בינקי שאיתם אנו יהיו להיות הציג בפעם הבאה למצביעים. אז הנה תצוגה מקדימה של מה לבוא. [וידאו השמעה] היי, בינקי. התעורר. זה זמן בשביל כיף מצביע. -מה זה? למד על מצביעים? אה, סוכריה. [סוף ההשמעה] דוד י מלאן: ובנימה זאת, אנו רואים אותך ביום רביעי. בסדר. מי ריקודים? בחייך. מי ריקודים? אתה רוצה שאני לקבל את זה התחיל? אני לקבל את זה התחיל. Woooo! לורן: מפואר מתוק משה.