[השמעת מוסיקה] דוד י מלאן: זה כמו סמינר הלימודים הראשונה היום. אוקיי. אז מאוד גשום בחוץ. זה נוטה לקרות בימי רביעי, אבל כל עוד ההזדמנות לשאלות היום. אז בואו נתחיל מלמעשה עם הסרט ברגע. אבל יתחילו בחגיגיות כמו תמיד. זה CS50, וזה הוא סוף השבוע 4. אז אם יצאתי לך לראות טלוויזיה או סרט שבי יש כמה מומחי מחשב ו המשטרה, או ה- FBI, או כמה סוכנות מנסה לתפוס כמה יריב, גם, שיש לך כנראה שמע את הביטוי "לשפר" לפי טכנאי שאיכשהו קסם מתקרב לאין שיעור רחוק כדי לראות את הפושעים זהות או מספר לוחית הרישוי באפילו הבלחה של מראה או הנצנוץ של עין של מישהו. אז אכן, בואו נסתכל כמה כאלה סצנות מהוליווד. [וידאו השמעה] או קיי, עכשיו בואו לקבל מבט טוב עליך. -תחזיק את זה. הפעל את זה בחזרה. -חכה דקה. פנה ימינה. : רווחה, להקפיא את זה. -מסך מלא. או קיי, להקפיא את זה. -Tighten על ש, יהיה לך? -Vector שב בחור בגלגל האחורי. -Zoom בכאן במקום הזה. -עם הציוד הנכון, התמונה יכול להיות מוגדל ומחודד. -מה זה? "זאת תכנית שיפור. "אתה יכול ברור שעד כל? -אני לא יודע. בואו לשפר אותו. A6 סעיף -Enhance. -אני משופר הפרט, and-- אני חושב שיש מספיק כדי לשפר, לשחרר אותו למסך שלי. -אני משופר ההשתקפות בעיניה. בוא להפעיל את זה דרך שיפור וידאו. -Edgar, אתה יכול לשפר את זה? -חכה. "יש לי כבר עובד על השתקפות זו. ההשתקפות של-מישהו. -Reflection. "מצאתי השתקפות של פניו של האיש. השתקפות בחור'. "מצאתי השתקפות. -Zoom במראה. , אתה יכול לראות את השתקפות. "אתה יכול לשפר את התמונה מכאן? "אתה יכול לשפר אותו ממש כאן? "אתה יכול לשפר את זה? אתה יכול לשפר אותו? "בסדר." "החנות לשפר את זה? "אתה יכול לשפר את זה? -Hold בשני, אני לשפר. -Zoom בדלת. -Times 10. -Zoom. -לעבור לגור. -יותר. "חכה, לעצור. -Stop. -Pause זה. -Rotate 75 מעלות סביב האנכי, בבקשה. -Stop. חזור לחלק על הדלת, שוב. -Got משפר תמונה שיכול מפה סיבית? היי, אולי נוכל להשתמש בPradeep שיטת סן לראות בחלונות. תוכנת -זהו היא מדינה של האמנות. בחור' ערכים עצמי כבוי. -עם תקין שילוב של algorithm-- החיסול נלקח של -הוא אלגוריתמים לרמה הבאה, ואני יכול להשתמש בם כדי לשפר את התצלום הזה. -Lock ובלהגדיל את ציר z. -Enhance. -Enhance. -Enhance. -Freeze ולשפר. [סוף ההשמעה] דוד י מלאן: בסדר, כל כך כל אלה הם למעשה מילות. הם פשוט מתוחים יחד ב דרך שלא הגיוני למעשה. ולמעשה, קורסים, CS50 וכמותו נוטה להרוס הרבה טלוויזיה וסרטים בשבילך. כי כאשר מומחי מחשב אלה הם מטלטל את תנאים ואומרים דברים מפוארים כמו וקטורים עצמיים, וציר z, וכל מספר אחר למעשה מונחים טכניים יותר, הם באמת רק בחוטים מילות יחד לעתים קרובות מדי. האם זה אחד מתקוותינו הוא ש, כתופעת לוואי של נטילת קורסים ככה, יהיה יותר אנשים ב עולם בעצם להיות מסוגל לשקול ב ורק מעט שבמעט להשפיע איכות ודיוק של הסרטים האלה? למעשה, בואו נסתכל על מציאות. אז הנה התמונה של צוות מרי, אחד מעמיתי ההוראה שלנו. ונניח שהיא חשוד במשהו. ובכל זאת, יש ניצוץ של כמה ראיה בעינה, או בהשתקפות של משקפיה. ובכן, אם אנחנו עושים בדיוק כמו הסרטים מציע, שבו אנו זום ו" לשפר ", זה כמה מידע הוא בפנייה של מרי כאשר אתה ללכוד תמונה עם שרזולוציה מקורית. ואכן, אתה יכול לראות נקודות אלה. ואלה הם מה הם פיקסלים שנקראו, P-אני-X-E-L-S, וזה רק כיכר בדרך כלל שהוא נקודה שמלחינה תמונה. ובחזרה ביום, ואפילו למעשה היום עם כמה משל היום טלוויזיות LED או טלוויזיות LCD, אם יש לך אחד בחדר שלך או בבית, אם אתה רוצה ללכת עד סופר קרוב לזה, ו במיוחד אם זה טלוויזיה מבוגרת במקצת, כנראה שאתה יכול אפילו לראות נקודות אלה וזה מה שמרכיב את תמונה. ואין עוד מידע מזה. אנחנו יכולים "לשפר", במובן של החלקה על דברים וסוג של הסיק סוג של, סוג של מה ש צבע צריך להיות ליד העין של מרי כך שזה לא ממש כך pixelated. אבל אם אני ממשיך התקרבות, שם הוא האיש הרע בעיניה. כמו שכולו מידע שיש לנו. אתה לא יכול ליצור מידע מאין. יש רק סופי מספר הביטים שיש. אז בבעיה 4 סט, שבו יש לך הזדמנות לשחק עם של עולם מסוג זה. בבעיה 4 סט, אתה לחקור את עולם של גרפיקה, וזיהוי פלילי, ובעצם לכתוב קוד שמשחזר תמונות איבדו. אתה כותב קוד ש מתפעל תמונות קיימות וסופו של דבר להבין מה קורה מתחת למכסת המנוע. ו, מתברר, זה בעצם לא כל כך מסובך. לדוגמא, אם אנחנו רוצים מייצג הסמיילי בי עם פיקסלים שחורים אלה, או הנקודות השחורות הללו, טוב, אנחנו יכולים פשוט מייצגים שלהם כבאמת מפת סיביות. ואם היית אי פעם שמעת ש מפת סיביות ביטוי, אולי עכשיו זה מתחיל לעשות תחושה קצת יותר היום. אנחנו כבר יודעים מה הוא קצת. זה 0 או 1. ומפה היא רק משהו כמו פיסת נייר זה נותן לך כיוונים ויש לי אולי רשת של X ו- Y-קואורדינטות. אז הנה היא מפת סיביות. זה מפה של ביטים לפי 1 הוא כנראה הולך לייצג פיקסל לבן, ו 0 הולכים לייצג פיקסל שחור. אבל אנחנו בהחלט יכולים להעיף סביבו. זה לא ממש משנה כל כך עוד אנחנו עולים בקנה אחד. וכאן הוא איך, בbinary-- בתוך הזיכרון של מחשב, או אפילו בתוך של קובץ עליך קשה drive-- אתה יכול לאחסן הפשוט של תמונות הסמיילי. אבל מה אנחנו, כמובן, חסר בתמונה זו? צבע, נכון? זה השלב הבא ברור או שיפור לשפר את זה עם הצבע. אז למרבה הצער רק עם אחד קצת, 0 או 1, אנחנו יכולים לייצג צבע. זה יכול להיות אדום, או כחול, או שחור, או לבן, או ירוק, או ורוד, או כל זוגות של צבעים. אבל למען הפשטות, אנחנו פשוט מניח בשחור לבן. אז מה אנחנו צריכים באופן הגיוני אם רוצה ליישם צבע בתמונה? מה יש לנו לעשות? כמו אם הגורם המגביל כאן הוא שעם אחד קצת אתה יכול רק בשני מצבים, 0 או 1, לבן או שחור, מה אתה רוצה לעשות? נתונים נוספים: קהל. דוד י מלאן: יותר ביטים, כן נתונים נוספים, יותר ביטים. ואכן, זה בדיוק איך תמונות צבע מיוצגות. במקום להשתמש קצת בודד, 0 או 1 לכל פיקסל, כל נקודה, אתה פשוט להשתמש מרובה. אולי להשתמש 8, אולי, יותר נפוץ להשתמש 24, ואכן, בבעיה הגדר 4, יהיה לך לשחק עם קובץ פורמט שמשתמש 24 סיביות בדרך כלל. אבל רובכם כנראה מכיר JPEG. אם אי פעם לקחו תמונה בטלפון שלך, או נטען או ראה משהו ב פייסבוק, או פליקר, כל מספר של אתרים מבוססי תמונה, יש לך כנראה ראה תמונת JPEG לפני. ומתברר, זה הקובץ פורמט שאנחנו הולכים להשתמש בPSet 4, לפי שאתה הולך צריך לשחזר תמונות כי אני כבר שנמחק בטעות מ כרטיס זיכרון פגום במצלמה, אם אתה. ומתברר שלמרות ש JPEG הוא די sophisticated-- זה הרבה יותר מתוחכם מהנקודות השחורות והלבנות ראינו לפני רגע, כי יש אלגוריתמים מפוארים למעשה ש הם משמשים לדחיסת JPEG, כך שאתה יכול להיות ממש נחמד, תמונה באיכות אלא באמצעות מעטים יחסית סיביות. ואנחנו נחזור ל דחיסה לפני זמן רב. מתברר כי הראשון שלושה בתים בimage-- JPEG לא משנה מה אתה כבר לקח תצלום ל-- הם הערכים 255, 216, 255. במילים אחרות, אם אתה רק לראות דפוס של ביטים, מיוצג כאן כשלוש בתים, או 24 סיביות יסתכמו, בהסתברות גבוהה שאתה יכול להסיק ש אתה מסתכל על זה שלוש הראשונים בתים של JPEG. וזה מה שנקרא כחתימה של JPEG. הרבה פורמטים של קבצים בחוץ נוטה להתחיל עם דפוסים מסוימים של 0s ו 1s, כך ש- Windows ו- Mac OS, וiOS, ויודע אנדרואיד איזה סוג של קובץ שהם הם, בנוסף לקובץ שנקרא סיומת שהרבה קבצים יש לי. אם יש לך .jpg, זה עוד רמז למחשב. אז בואו עכשיו להסתכל על זה קצת יותר מבחינה טכנית. אנחנו יודעים עשרוניים מערכת היא 0 עד 9. אנחנו יודעים בינארי הוא 0 ו -1. ואם אתה חושב לחזור לPSet 0, היו לנו אותך להתמודד עם, עבור קצת, משהו נקרא הקסדצימלי, שבו יש לך 16 ספרות, במקום 10 או במקום 2. וספרות אלה, על ידי אמנה, הם 0 עד 9 ולאחר מכן דרך F, כאשר F מייצג את מה ש מספר עשרוני, בדיוק כמו שפיות מהירה לבדוק? אז, 15. וחייב לייצג 10, רק על ידי הטבע של ההזמנה שנתתי לי. זה רק מוסכמה שרירותית, אבל זה די סטנדרטי. אז אם אנחנו מסתכלים על דפוס זה של שלוש bytes-- בואו פשוט להתחיל להסתכל על זה ב אופן עקבי עם איך מדעני מחשב בדרך כלל להסתכל ולחשוב על קבצים. אתה בהחלט יכול לחשוב על קבצים ב0s, ו1s, ועשרוני, אבל במציאות, אנו נוטים להשתמש בינארי או יותר בדרך כלל hexadecimal-- חזרה מPSet 0. אז הרשה לי להציע כי 255, 216, 255 ו רק דפוסים של 0s ו 1s אלה. ואתה יכול לבדוק את זה אם אתה רוצה לעשות את המתמטיקה מהשבוע 0. אבל, לעת עתה, רק להניח שזה אכן נכון. אני פשוט כבר שוכתב שלוש עשרוני מספרים כשלושה ערכים בינאריים. עכשיו מה שאני הולך לעשות הוא רק להוסיף קצת שטח לבן, רק למען הקריאות. והודעה, אני רק הולך לנוע בין דברים. אז לפני, אחרי, לפני, אחרי. אני עושה שום דבר מעניין אחרים לא רק מתפשט החוצה דברים כל כך הודעה שכל סט של שמונה ביטים הוא עכשיו שני סטים של ארבעה ביטים. זה שימושי כי הקסדצימלי במיוחד אופנתי כי כל ספרה הקסדצימלי 0 דרך F, או לייתר דיוק 0 עד 15, יכול להיות מיוצג עם בדיוק ארבעה חתיכות. במילים אחרות, בהקסדצימלי אם אתה רוצה לייצג 0, זה רק 0000, ארבעה אפסים. ואם אתה רוצה לייצג 15, זה 1111, אשר הוא ארבע חתיכות. ואם אתה עושה את המתמטיקה, אם זה המקום אלה, זה מקום 16s, זה הולך לתת אתם-- ולא שקורה צריכה-- מצטער, בינארי, זה הולך לתת לך 15, מקום אלה, המקום, ארבע ושמיניות זוגות מקום. אז הרשה לי להציע ש סט של ארבעה ביטים בצד השמאל זה מה שאנחנו הולכים לקרוא F. זה המספר הגדול ביותר שאתה יכול לייצג עם ארבע חתיכות. ואנחנו כבר יודעים מהקסדצימלי, F הוא הספרה הגדולה ביותר בהקסדצימלי. יש לנו F אחר שם, עוד שני שם. ועכשיו, רק לקחת על אמונה שאני עשיתי את זכות המתמטיקה ושהמחצית השמאלית מאותם קטעים, 1101, הוא אותו הדבר כמו בד הקסדצימלי. ויד ימין, 1000, היא רק 8. וזה אחד קל לראות, נכון? Represents-- 8 נכון מתחת כי מקום שמיניות. אז יש לנו אחד בעמודה שמיניות ושום דבר בארבעה, בזוגות או אלה. אז עכשיו יותר קונבנציונלי, בני האדם נוטים כדי לכתוב ספרות הקסדצימלי כמו זה, אתה פשוט תמחץ אותם יחד, ואז אתה קידומתם עם 0x. זה לא אומר כלום מלבד רמז חזותי לhuman-- כאן מגיע value-- הקסדצימלי כי זה יכול אחרת לא יהיה ברור. כלומר, בסופו, ש הדפוס של אפסים ואחדים, או הדפוס של הקסדצימלי ספרות שקול שאתה הולך להתחיל לחפש בבעיה סט 4 הוא זה-- ומפרט הבעיה סט 4 יצעד אתה תעבור את זה יותר detail-- אבל מבין כסוג של מסתורי כ זה עשוי להיראות במבט ראשון, אתה הולך להתחיל לראות את זה הרבה. ואכן, גם בGDB, הבאגים שהצגנו ביום שני ודן מציג בPSet 3, הולך ללעתים קרובות להראות לך ערכים הקסדצימליים רק בגלל שהם נוטים להיות יותר קונבנציונלי מאשר עשרוני או בינארי בעולם של מחשבים. עכשיו בואו לשים את זה בהקשר. רבים מייתכן שתזכרו את זה תמונה כאן, שבאו ממה? Vista, כך שגם מוקדם יותר ש, Windows XP עשתה את הופעת הבכורה של זה. אז זה נוף יפה. ולמעשה, אם אתה לחטט online-- אני חושב שזה מאמר בויקיפדיה, בי מישהו הלך מאוד להפליא את מצא מיקום זה בעולם הקים שלו או את המצלמה שלה ב בדיוק place-- תקין והיום זה נראה like-- אבל זה בדיוק את אותה ההגדרה. תמונה זו, אם כי, היא בקובץ מפת סיביות פורמט שנקראה, ב-מ-ע '. ואנחנו הולכים לקחת סופר מבט מהיר על מה שזה אומר. אבל מפת סיביות היא רק דרך של שונה תמונות מייצגות עדיין משתמשים בפיקסלים ב0s ו 1s, סופו של דבר. אבל במבט מהיר, יש לו חתימה מעניינת יותר בתחילת הקובץ. זה לא רק שלוש בתים, ולא שיש חבורה של דפוסים של בתים שלמה שנקבע מראש משמעות. לדוגמא, אי שם ב כמה בתים הראשונים של תמונת מפת סיביות הוא הולך להיות בגודל של תמונה, הרוחב של התמונה, הגובה של התמונה, כך מטה שימושי, אם תרצה. מידע שימושי שפוטושופ או כל גרפיקה לתכנת אתה משתמש אולי באמת אכפת. אז עוד על כך ב בעיה הוגדר 4, אבל זה רק לומר ש בסופו של היום כל הפורמטים של הקבצים שאתה כבר משתמש עבור קבצי Microsoft Word years--, קבצי מספרים, קבצי Excel, כל מספר של פורמטים של קבצים שאולי יש לי כמה סיומת קובץ ידועה רק 0s ו 1s מתחת למכסת המנוע. ובני האדם החליטו מה הן האמנות, מה דפוסי 0s ו 1s מייצגים קובץ Word לעומת קובץ Excel, לעומת כל מספר של פורמטים של קבצים אחרים. אז בPSet 4, יהיה לך הזדמנות לשחק עם זה. אבל מה זה אומר שיש לי struct. זהו למעשה segue נחמד עכשיו לC, שבו יש רק כמה תכונות של נוספות ש אנחנו לא בחנו עדיין. זו שפה די קטנה ואחד התכונות נחמדים על C היא struct. לדוגמא, אם אתה רציתי represent-- בואו אמרתי שאתה רוצה יש לי משתנה ש מייצג סטודנט בתכנית כלשהי. אולי אתה כותב כמובן תכנית רישום, או קניות ליבה כלי, או משהו כזה. מה הן פיסות של נתונים הקשורים לתלמיד שמגיע אל המוח? כמו תלמיד מיוצג עם מה ערכים? כן? יש לך שם כסטודנט. מה עוד יש לי תלמיד טיפוסי? קהל: [לא ברור] דוד י מלאן: אז, מצטער. קהל: גיל. דוד י מלאן: גיל או יום הולדת באופן שקול, כן. מה עוד? קהל: מספר תעודת זהות? דוד י מלאן: אז מספר תעודת זהות, אולי מספר טלפון, אולי במעונות, או בית, או במכללה, או משהו כזה. כל מספר של פיסות מידע ש אולי יש לך ברשימת אנשי הקשר שלך זה מה שעשוי להגדיר תלמיד. אז אם אנחנו רוצים לעשות את זה, בקוד, אנחנו יכולים לעשות משהו פשוט כמו זה. אולי יש לנו תכנית, כך ש יש נניח, int הראשי (void). ואם אני רוצה לייצג סטודנט שאולי אני צריך, למשל, מחרוזת קראה בשם לתלמיד ש, מחרוזת נקראת מעונות לסטודנטים ש, אולי int נקרא זיהוי לתלמיד ש. ומכיוון שאני משתמש בחוט, אני צריך לחזור ולשים את CS50.h. אולי אני צריך ללכת stdio.h. אז תן לי לעשות מנעו אלה ואני הולך לקרוא student.c זה לעת עתה ולשמור את זה. ועכשיו אני יכול לעשות משהו עם המשתנים הללו. ואנחנו רק הולכים לכתוב כי כתגובה בקוד פסאודו, כי זה לא מעניין מה שאנחנו עושים עכשיו. אוקיי, אז זה הוא תכנית ש איכשהו מאחסן תלמיד. מה אני רוצה לעשות אם אני רוצה לאחסן שני תלמידים? אז האינסטינקט הראשון שלי הולך יהיה בסדר, חכה רגע, אם יש לי תלמיד אחר למה לא אני פשוט לעשות מחרוזת 2 שם, מחרוזת במעונות 2, ID2 int. ושעשינו נעלם בדרך הזאת לפני ומה היה הפתרון שלנו למה שנראה להיות סוג של העתק דבק hackish עבודה כאן? קהל: מערך. דוד י מלאן: כן, אנחנו יכולים להשתמש במערך. זכות זו מהר מאוד הופך מסורבל. אתה צריך למיין של שרירותי להתחיל שמות כל אחד מהמשתנים הללו. ואתה, האדם, צריך לשמור לעקוב המתאים NAME2 אישור עם dorm2 מתכתב עם ID2. זה פשוט הופך להיות בלגן. אז זה הרבה יותר קל, זוכר מלפני כמה שבועות, רק שיש לשמות מחרוזת נקראים ואולי לתת לנו שלושה מאלה. ואז אולי יש לנו מעונות מחרוזת ויש לי שלושה מאלה, או עם קבוע, int תעודות זהות ויש לי שלושה מאלה. אבל גם עכשיו זה מרגיש מרושל, נכון קטן. על תלמידים, ובכל זאת אנחנו מדברים אני באמת מגורים ברמה הנמוכה פרטי יישום. התלמיד הוא שם ומעונות וזיהוי. למה אני לא יכול פשוט להצהיר על משתנה בשם תלמיד וקוראים לזה זה. ואם אני רוצה תלמיד אחר, למה אני לא רק קורא לזה לא. או אם אני רוצה כל חבורה של תלמידים, למה לא אני רק אומר שיש לי בכיתה של כל תלמידים, וזה שלושה מהם. במילים אחרות, למה אני לא יכול לבוא עם הסוג שלי נתונים, הנקרא סטודנטים, בתוכה הוא שם, הוא זהות, היא במעונות, הוא מספר כלשהו של תחומים אחרים. ומתברר לך יכול לעשות בדיוק את זה. אז יש C תכונה זו נקראת struct. זה תכונת שפה ש מאפשר לנו לעשות בדיוק את זה. אני הולך קדימה ולפתוח structs.h לאן אנחנו הולכים לראות הבא הגדרה של תלמיד. מתברר - וזה אחד אפילו פשוטה יותר מזו כרוכה בזיהוי רגע לפני. אם אתה רוצה לבוא עם סוג נתוני תוצרת בית שלך, ובנוסף לint, char ו לצוף וכל האחרים אלה שקיימים, אתה יכול לעשות זאת על ידי פשוטו כמשמעו כתיבת struct typedef, אז כמה סוגריים מסולסלים, בתוך שבו אתה רשימת המשתנים שאתה רוצה לקשר עם נתונים מותאמים אישית חדשים הקלד כמו שם ומעונות, ואז אחרי הסוגריים המסולסלים אתה נותן שם לסוג הנתונים החדש. כך, למשל, תלמיד. ומה שיפה זה שעכשיו הוא אם אנחנו מסתכל על הקוד המקביל, הכנס, ראשון מכל, הוא לשים את זה בע"ה נקודת משהו קובץ בשם, קובץ כותרת, שיש לנו לא התחיל להשתמש בעצמנו יותר מדי. אבל אנחנו הולכים להתחיל באמצעות לא מעט עכשיו. ומה אנחנו יכולים לעשות עם זה, סופו של דבר, בכמה שורות הקוד האלה הוא מצהיר בדיוק ש סוג הנתונים, תלמיד. ועכשיו בואו להשתמש בו. אני הולך עכשיו ל קובץ בשם structs1.c. ובואו נסתכל כמה מאפיינים כאן. אז הדברים עד כאן הוא בעיקר מוכר, ואנו אחזור למה שהוא לא מוכר ברגע. זה כמובן כולל קובץ כותרת, שהיא חדשה, כמו גם, פרט לPSet 3 שבו, כזכור, יש לנו helpers.h. אז אתה יכול להיזכר helpers.h #include. למה למרות שאני משתמש ציטוטים במקום סוגריים זווית? כאשר אני בוחר ביניהם? כמעט תמיד אני נראה להשתמש בסוגריים בזווית. ואז, פתאום ב קו שש אני משתמש במרכאות כפולות. למה זה יכול להיות? כן? קהל: [לא ברור] דוד י מלאן: זה בפועל, מה? קהל: זה בIDE שלך. דוד י מלאן: כן, זה בIDE בפועל. ובואו לא להתעכב על IDE, כי זה רק כלי שאני משתמש. זה בנוכחי שלי ספרייה, באופן ספציפי. אז structs.h הוא הקובץ שלי אינו מותקן בIDE, במערכת ההפעלה עצמה, ולא זה בספרייה הנוכחית שלי. אז הכנס הוא אם אתה רוצה לכלול קובץ הכותרת שלך, אתה פשוט להשתמש במרכאות כפולות. מה שאנחנו קוראים את הדבר הזה ב קו 8, באופן כללי? זה מה? משהו define #. זה מייצג קבוע, נכון? אם אתה רוצה יש לי ערך בתכנית שלך שאתה משתמש בכל חבורה של פעמים, זה כנס טוב גורם אותו, להכריז עליו, עם סמל החשיש להגדיר, אז, על ידי אמנה, בכל אותיות רישיות word-- למרות שזה לא בהחלט הכרחי, אבל זה כנס אנושי לנצל קבועים כך שהם קופצים החוצה בך visually-- חלל ו לאחר מכן הערך שאתה רוצה להיות שווה ערך לשמו של קבוע ש. לא פסיק, אבל אתה פשוט על פי תבנית שיש. אז מה אני עושה בקוד בפועל זה. אז בואו נסתכל התכנית העיקרית כאן. בקו 12 כי אני כללתי structs.h, עכשיו יש לי באורח פלא בי רשות סוג נתונים חדש. אין לי רק גישה לint, וchar, ולצוף, ומחרוזת, וכחול ועוד. עכשיו יש לי גישה ל סוג נתוני תלמידים. אז בקו 12, אני שילוב של שני ideas-- אחד סוג נתונים מותאם אישית ושני, באמצעות מערך. וכך בתכנית זו אם אני רוצה לתמוך למעשה שלושה תלמידים שונים בתכנית שלי, אני פשוט יכול לומר לי משתנה סטודנטים שנקראו, כל אחד מהם הוא סוג של תלמידים, ש הוא סוג נתונים מותאמים אישית שלי. ו, במיוחד, תן לי שלושה מאלה במערך שלי. אז עכשיו מה שאנחנו עושים בתכנית זו? הנה רק לiterating לולאה 0-3, כי זה מהו הערך של תלמידים. אני רק להציג הודעה למשתמש תן לי את שמו של התלמיד. ולאחר מכן בקו 17, ש יש קו בעיקר מוכר. יש לנו ידידנו הוותיק GetString בצד הימין. ומה קטע של תחביר חדש כנראה, אם מעולם לא מתוכנת ב- C לפני, ומעולם לא השתמש structs? כן? קהל: .name. דוד י מלאן: .name. אבל זה לא יותר מדי של קפיצה, כי עכשיו אני סוגרים תלמידים נותן לך את תלמיד i-ה. ואם אתה רוצה לצלול בתוך המבנה ש, אתה פשוט להשתמש תקופה אחת ו לאחר מכן את השם של המשתנה בתוך, או הרכוש בתוך ש אתה רוצה לקבל גישה ל. כמו כן, אם אני מכן תנחה משתמש, נותן לי במעונות של הסטודנטים, באופן דומה ניתן לאחסן ש מחרוזת במשתנה המעונות בתוך של מבנה שהתלמיד. ועכשיו דברים לקבל קצת מפואר. וזה הולך להיראות באולי הרבה די בקרוב. אבל אתה רואה את זה הרבה יותר בPSet 4, אז בואו רק מבט חטוף על זה עכשיו. מתברר כי בקו 23 ב 38, מה אתה חושב שאני אולי אני עושה? אני כבר הסרתי את ההערות להיום, אבל את הגרסה של הקוד באינטרנט ל יש התייחסות כל ההערות. מה אני נראה עושה? קהל: שמירת הקובץ עם כל המידע שהמשתמש נכנס. דוד י מלאן: כן, בדיוק, זה הוא דרך חדשה כי אנחנו רואים שני, תכונה נוספת של C, לפי שאני יכול ליצור קבצים שלי. עד כה, כמעט בכל תכנית שכתבת הוא חסר אזרחות. ברגע שזה נעשה בריצה, וזהו. אין זיכרון או זיכרון שלו. אין קובץ שנשמר. אבל אם אתה רוצה להציל את הקלט שיש קרה, כמו במשחק או תכנית כמו זה, מתברר שאנחנו יכולים לעשות זאת. ואתה רואה את זה יותר ב 4 PSet ובסעיף. אבל הקו הזה 23 במהות יוצר קובץ בשם students.csv. וייתכן שלא ראה לפני זה. גם אם אף פעם לא למדו מדעי המחשב לפני, CSV הוא משתנים מופרדים בפסיקים. זה כמו גבר של עניים מאוד גרסה של קובץ Excel, מה שאומר שזה יכול להיות נפתח ב- Excel ובמספרי אפל, ויש לו שורות ועמודות. אבל זה לא קניינית פורמט כמו מיקרוסופט או אפל של. זה רק פסיקים מפרידים ערכים שאנו רואים ברגע. ופשוט לקחת את ניחוש. בקו 23, במאוד הסוף, הטיעון השני שלי לפונקציה החדשה הזה שנקרא ו פתוח לפתוח קובץ הוא w. מה יכול w לציין? כן? קהל: הוא מאפשר לך לכתוב לקובץ? דוד י מלאן: הוא מאפשר לי אתה כותב לקובץ. אז יש כמה גרסאות שאנחנו יכולים לחבר כאן. אבל אם אתה רק רוצה לקרוא הקובץ, שהוא מסתכל על זה ולקרוא אותו בזיכרון, אתה פשוט להשתמש סוף ציטוט ציטוט "R". אם אתה רוצה לכתוב ל קובץ, אתה משתמש בציטוט סוף ציטוט "W". גם יש לצרף ו כמה דברים אחרים אם אתה רוצה לשנות את הקבצים קיימים. עכשיו אנחנו הולכים לשמור רואים את זה דבר, אז אנחנו נחזור לקו 24. NULL, מתברר, הוא ערך מיוחד ש ניתן להחזיר ידי פונקציות מסוימות אם משהו הלך wrong-- אם הקובץ לא קיים, אם אתה כבר נגמר זיכרון, או חבורה של טעויות אחרות. אבל לעת עתה, בואו פשוט להניח שזה היא בדיקת שגיאות פשוט קונבנציונלית. כאן בקו 26, אני iterating 0-3 על כל התלמידים שלי. וזה סוג של סוג של פונקציה חדשה, fprintf, אבל רק לקחת ניחוש. אם printf הוא רק הדפסה מחרוזת מעוצבת, מה fprintf כנראה מתכוונת? קהל: הדפסה לקובץ. דוד י מלאן: הדפסה מחרוזת מעוצבת לקובץ. זה מה נוסף אמצעי F הוא קובץ. והטיעון הראשון החדש צריך להיות משתנה המייצג את הקובץ שלך. אז פשוט יש לנו פורמט מחרוזת בדיוק כמו printf. ולמרות שזה תחביר הוא חדש, זה פשוט הפירוש לחבר את שמו של הסטודנט, התוספת מעונות סטודנטים, ולאחר מכן עם fclose, לסגור את התיק. ולאחר מכן lastly-- זה חדש ואנחנו נחזור לזה לפני long-- אני משחרר סטודנט מסיבות שקרה למעלה שם. אבל אנחנו נחזור שללפני long-- זה בגלל איך GetString הוא למעשה עובד מתחת למכסת המנוע. אז בואו ניקח מבט מהיר כאן. אם אני מקליד LS בספרייה שלי, שם לב שאני לא יש קובץ שנקרא students.csv, פשוט לא שם, לא קיימות. אז אם אני עכשיו ללקט תכנית זו, להפוך structs-1,. / Structs-1, ואני הולך קדימה ולהקליד אנדי, שחי בברקלי באוניברסיטת ייל. אנחנו הולכים יש רוב ש גר ביאיירו בימים אלה. ובואו לבוא עם שם הוא, אני חושב, מריה היא במאת'ר, אם אני זוכר נכון. אז שום דבר לא נראה לקרות. אבל אם אני מקליד ls עכשיו, יש students.csv. בואו נלך קדימה וstudents.csv הפתוח. זה שוב מאוד קובץ בפורמט קל. אבל אני כבר פשוט אימצתי ועידה כי יש לי שתי שורות ועמודות כאן. העמודה הראשונה היא כל השמות של אנשים. העמודה השנייה היא של התלמיד מעונות, או במכללה, או בית, או מה שלא. ועכשיו אני כבר הצלתי זה באופן קבוע בקובץ. אז זה לא כל כך מעניין. אבל זה רק קרש קפיצה עכשיו כדי להיות מסוגל להתמיד מידע באופן קבוע. אז בואו לראות עכשיו מה שאנחנו יכולים יותר לעשות עם תכונות אלו ואחרות. אבל קודם, כל שאלות? זה היה הרבה, וזה היה מהיר. אבל אתה תראה הרבה יותר בPSet 4, כמו גם. כן? קהל: האם יש דרך ל להמשיך ולהוסיף שמות לקובץ זה? דוד י מלאן: שאלה טובה. האם יש דרך להמשיך הוספת שמות לקובץ זה? כן. ואכן, אם בסופו עד מחדש לפתוח את הקובץ, היית משתמש ציטוט סוף ציטוט "" לצרף, אשר תוסיף רק בשורה חדשה, קו חדש שוב ושוב, בדיוק. שאלה טובה. שאלות אחרות? כן? קהל: אם אתה רץ תכנית שוב עכשיו, היה זה לשמור על הוספת שמות ל להגיש או שזה לפתוח את קובץ חדש? דוד י מלאן: אה, שאלה טובה. אם אתה רץ שוב את התכנית נכונה עכשיו, אולי הקליד בשמות חדשים, היה זה כדי להוסיף את הקובץ או להחליף את הקובץ? האחרון, כי אני לא משתמש במצב צרף. ובגלל שאני רק באופן עיוור פתיחת הקובץ לכתיבה, זה פשוט הולך להחליף את הקובץ. אז אכן הייתי צריך לעשות הוא להוסיף, אם אני רוצה להיות למעשה לטווח ארוך מאגר מידע. עכשיו CSV שימושי, בכנות, אפילו עבור כמו אם אתה writing-- וסופו של דבר יראו את זה מאוחר יותר בסמסטר שבו אנו משתמשים בקובצי CSV למטרות אחרות. אם אתה רוצה לאחסן את כל האנשים שנרשמו לאירוע כלשהו, או נרשם לתלמיד שלך קבוצה, או משהו כזה, אחסון הנתונים בסוג זה פורמט של סופר נוח. בגלל פשוטו כמשמעו, אם אני היו להוריד קובץ זה. אני יכול double-- ו בואו ננסה בעצם זה אם יש לי Excel או מספרים כאן. אני הולך לחיצה ימנית או לחץ שליטת הקובץ שלי. אופס. לחץ לחיצה ימנית או קש Control הקובץ שלי. יאללה, העכבר שלי לא משתף פעולה. Download-- אני הולך להוריד את כל הקבצים כאן כל כך רק אז אני יכול לתפוס את זה. ובואו נראה אם ​​זה עובד פעם הראשונה students.csv-- אני כבר הופעל. עכשיו הם רוצים לראות את אנשי הקשר שלי. עכשיו, אני צריך להירשם. ראה כמה זה קל לשימוש קובצי CSV? כן, לשמור אותו מעודכן. אוקיי, עכשיו אנחנו מוכנים לכיתה. אישור, הו, מה חדש? אישור, קרוב. זה היה קסום. אוקיי, עכשיו אנחנו צריכים לעדכן. ועכשיו, זה מה ששכח להגיש פתחתי במקור, אבל מה זה-- שם אנחנו הולכים. אוקיי, אז עכשיו יש לנו קובץ Excel. תודה. אוקיי, אז מה שעשיתי היה החלק קל. כמובן שאני יכול היה מותקן מראש Excel, או מספרים, או מה תכנית. אבל זה נחמד, כי עכשיו אני יכול לתפעל הנתונים בפורמט סטנדרטי. הקשר אז עכשיו בואו לעבור למקום שבו הפסקנו הפעם האחרונה, שהייתה להתחיל להמריא גלגלי עזר. אבל קודם, אתה לא לראות צהריים מוקדם יותר קורה כאן שוב באש ו קרח בקיימברידג ', סיטאר בניו הייבן. הרשמה באתר האינטרנט של CS50s בהקדם האפשרי להצטרף תלמידי CS50 וצוות. אז לקחנו גלגלים עזר את ביום שני כfollows-- מחרוזת הוכרזה ב ספריית CS50s לכמה זמן. וזה נחמד, כי זה מאפשר לי שלנו לדבר על משתנים כ מילות ומשפטים שלמים ועוד. אבל מתברר מחרוזת לא קיימת. זה פשוט מילה נרדפת, או כינוי, שיצרנו משהו ש למעשה הוא קצת יותר טכני נקרא char *. ואכן, ראינו דוגמא של תכנית ביום שני שלא התנהג ממש כמו שציפינו. זה היה הקובץ, להשוות-0. ולזכור כי להשוות-0, אם אני הידור מחדש התכנית של יום שני ולהפעיל להשוות-0 והקלד באמא ב אותיות קטנות, ואמא באותיות קטנה שוב. התכנית התעקשה ש הקלד דברים שונים, למרות שאמא, את כל ב אותיות קטנות, זהה מבחינה ויזואלית. אז מה הייתה התשובה הקצרה למה המחשב חושב שני המיתרים הללו הם שונים? כן? קהל: [לא ברור] דוד י מלאן: ימין. אז, אמא, בפעם הראשונה אני מקליד את זה ב, הוא להיות מאוחסן במקום כלשהו במחשב שלי זיכרון אך במיקום שונה מהפעם השנייה שאני מקליד באמא. עכשיו זה בהחלט יכול להיות מותאם. המחשב יכול להיות חכם ו מבין שתי מחרוזות אלה, היי, הם זהים. תן לי לא מיותר לאחסן אותו. אבל מחשבים לא עושים את זה אופטימיזציה אלא אם כן אתה אומר להם. אז, כברירת מחדל, הם רק הולך בסופו של בשני מקומות שונים בזיכרון. וכך להיות יותר ברור, כאשר השווינו שתי מחרוזות, ים הראשון נקרא, השני נקרא לא, מה שדווקא היה לי השוואה כאן על קו 13? כן. קהל: זה המקום בזיכרון שהמשתנה יצביע. דוד י מלאן: בדיוק, אני היה השוואת המקום בזיכרון שהמשתנים אלה הצביעו על. אז במיוחד, אם אמא הייתה ב מספר הבתים 1 ו -2, ו -3, ו4-- כי זוכרים את הקו הנטוי 0 צריך להיות כל הדרך בסוף. והדוגמא אחרת של אמא, M-o-מ ', היה בכתובת 10, 11, 12, ו -13. אני משווה 1, כתובת ש, מיקום שבזיכרון, נגד 10, שהוא ברור שלא אותו הדבר. 1 הוא לא 10. אז זה נחמד שב זה די פשוט. אבל זה בעייתי ככל ש אנו לא מצליחים להשוות מחרוזות. אז fundamentally-- וברמה נמוכה זו, אם אתה רוצה ליישם תכנית כדי להשוות שתי מילות נפרדות ש משתמש שהוקלד לאיכות, האם הם בשורה char ל char, רק באופן כללי, מה שאנחנו צריכים לעשות, כנראה? זה לא מספיק רק ל תסתכל על שתי כתובות אלה. מה אנחנו צריכים לעשות? כן? קהל: לחזר דרך המחרוזת [לא ברור]. דוד י מלאן: כן, בואו איטרציות במחרוזת. בואו להשתמש ללולאה, לולאה בזמן, או כל מה שאתה הכי נוח עם. ואם יש לנו שתי מחרוזות איפשהו בזיכרון, בואו נסתכל על כל תו ראשון, ולאחר מכן כל זה שני אופי, אז שלישי, והרביעי, וחמישי, עד שפגענו מה ערך זקיף מיוחד? קהל: [לא ברור] דוד י מלאן: כן, הקו הנטוי אפס, ובשלב זה באו מחרוזת אנחנו יכולים להחליט שזה זה. יש לנו התאמה בכל דמות? אם לא, תחזיר שקר. אם כן, תחזרו אמיתי. וכך זה בדיוק מה שגרסה זו התכנית להשוות-1.c עושה. זה זהה למה שאנו הסתכל בתאריך Monday פרט לכך שיש לי למרות שנפטר ממילת string-- שאין לי impact-- פונקציונלי כל אני עושה עכשיו הסרת כמה גלגלים עזר חזותיים, אבל לראות בבירור ש ים ולא הם כתובות. וזה מה שהכוכב, הכוכבית, מייצגת היא כתובת, הידוע יותר מבחינה טכנית כמצביע. לכן, כאשר אני מצהיר ים ב קו 9 ואומרים char * s, זה לא אומר שנותן לי מחרוזת. כלומר, לתת לי משתנה ש מטרה בחיים היא לאחסן את כתובת. מכיוון שאני עומד לשים את כתובת של מחרוזת לתוכו. ואכן, GetString, להיות ברור, לא מחזיר מחרוזת. זה לא יחזור אמא קו נטוי אפס, כשלעצמה. מה GetString במיוחד ולחזור בדיוק? קהל: [לא ברור] דוד י מלאן: כתובת, כתובת של התו הראשון בחלק המחרוזת זה קיבל. אז עכשיו אנחנו רואים מילות מפתח מיוחדת שוב. ו, רמזתי לזה מוקדם יותר. זה הולך להיות כנס טוב שנראה שוב ושוב עכשיו. אני בודק כדי לוודא ש ים הוא לא בטל ולא הוא לא null. בגלל המבוסס עליי באמת אזכור מהיר קודם לכן, מה שאולי אומר אם GetString חוזר לא כתובת אבל N-U-L-L, אשר שוב, כמה ערך מיוחד? קהל: שגיאה. דוד י מלאן: זה טעות. משהו השתבש. ומה בדרך כלל עלול לקרות, במיוחד עם מייתרים: אשר עשוי להיות אורך לא ידוע בadvance-- אולי המחשבים ' מתוך זיכרון, אולי הקלדת בכזה מילה או משפט ארוך או להדביק מאמר כזה ענק יש פשוט לא מספיק זיכרון. וכך GetString לא יכול לחזור הכתובת של כל הדבר, אז זה פשוט מחזיר שום דבר. וזה אומר שגיאה קרה על ידי החזרת ערך NULL המיוחד. זה כתובת אפס, אם אפשר לומר כך. עכשיו מתברר C מגיע עם פונקציה שעושה איטרציה ש. אנחנו לא צריכים ליישם את זה עם ללולאה או תוך לולאה על עצמנו. אנחנו יכולים להשתמש בפונקציה, נקרא באופן תמציתי, מערבבים comp, או מחרוזת להשוות, ש מטרה בחיים היא לעשות בדיוק את זה. אתה נותן לו שני מצביעים, שתי כתובות, וזה ילך לכתובות אלה ולאחר מכן להשוות מכתב ל מכתב למכתב לאיכות, עוצר רק כאשר מה נכון? כאשר באופן אינטואיטיבי צריך לעורר comp מפסיק חוזרת ונשנה, רק כדי להיות ברור? כאשר הוא יגיע קו נטוי 0 בשני מחרוזת, ובשלב זה יכול להחליט יש כל מה שתאם, או לא הייתה שם אי התאמה? לכן, אם אנחנו רצים עכשיו זה ולנסות משחק היוון הקטן שלנו, כך להפוך להשוות-1, ./compare-1, ו הקלד אמא באותיות קטנה בשתי פעמים. עכשיו זה אותו הדבר. ואם אני עושה את זה שוב עם אותיות קטנות ואותיות גדולות אז אולי. עכשיו זה אכן מבדיל בין גדול והקטן. אז לא כל כך קשה או קסום, אבל זה עכשיו להסביר מה קורה מתחת למכסת המנוע. אז מה יותר אנחנו יכולים לחלץ משל שיעור מסוג זה? אז בואו נסתכל על זה. אני הולך קדימה ולכתוב תכנית מהירה כאן בשם עותק-0. ועכשיו בואו נלך קדימה ולמעשה בואו נעשה את זה-- עם עותק-0, תסתכל על מה שיש לי כאן. אני אומר לי המשתמש ראשון, לומר משהו. ואז אני מקבל מחרוזת ואני מאוחסן אותו בים. אז אני בודק אם ים שווה שווה NULL, רק לחזור 1. אז זה רק בדיקת שגיאות סטנדרטית. שום דבר מעניין לא קרה. ולמעשה, אם אנחנו להיפטר השגיאה בדיקה, זה נראה כמו קוד השבוע 1 ברגע זה. אבל אני כבר התחלתי לקבל קצת יותר טוב על זה. עכשיו בקו 16, לפני כשבוע, אולי אפילו לפני כמה ימים או דקות, אפשר לומר קו 16 הוא יצירת לא משתנה בשם והעתקה זה לזה. וזה בצורה מושלמת ממסעדה סבירה. אבל להיות מדויק יותר עכשיו. מה שקורה בקו 16? מה הוא מקבל העתיק מימין לשמאל? כן? קהל: האם לא מקבל כתובת של ים? דוד י מלאן: בדיוק, לא הוא מקבל את הכתובת של ים. אז כדי להיות ברור עכשיו, אם אני הולך בחזרה שלדוגמה הקודמת ואני מצייר את הדבר שהקלדתי ב. ומה שהקלדתי in-- הנה ים, וכאן הוא מה שהקלדתי במקום כלשהו ב זיכרון, אמא ואז קו נטוי 0 זה הוסיף לי. מה אני מאוחסן בכאן, זוכר, זה במיקום 1, 2, 3, 4, זה מה שכרגע בים. אז אם בקו 16, אני אומר תן לי לא משתנה בשם אחר וחנות בשווי של ים, מה ש מקבל מאוחסן כאן לא יהיה אמא אלא רק את המספר 1. אז אם אנחנו מסתכלים קדימה בתכנית זו עכשיו, מה יקרה? אז שם לב שיש פונקציה זו אולי אתה השתמשתי זה לפני כמה זמן לקיסר, או Vigenere, או אולי בכלל לא. אני טוען עם printf שלי, אני הולך לנצל את העותק לא. הראשונה בקו 19, שפיות מהירה לבדוק, בדיקות strlen האורך של t. כי אני לא רוצה אנסה לנצל משהו אם אין מחרוזת שם. אם המשתמש פשוט לחץ על Enter, אין מה לנצל. אז אני לא רוצה לעשות את הקו 21. אז קו 21 הוא ניצול שמכתב, ככל הנראה, בt? קהל: מ '? דוד י מלאן: זה נראה כמו זה שהעתקה אחד? קהל: מ '. דוד י מלאן: אה, מ '. אוקיי, אז מ 'הראשון, בגלל הודעה שאני עובר לtoupper, ש אם אתה אף פעם לא ראית אותו זה רק פונקציה ל לנצל כקלט שלה. הסוגר T אפס הפירוש לתת שלי האופי של אפס לא. ואז איך עושה את זה שינוי תמונה, שיהיה ברור? מה צריך לעשות כדי לקבל מחדש או כתוב השתנו ביחס לים ולא ואמא אפס קו נטוי. קהל: [לא ברור] דוד י מלאן: כן, אז זה אחד כאן פשוט צריך לקבל השתנה צריכה-- לתקן זה-- צריך לקבל שונה למ 'הון. אבל עכשיו, נראה בהמשך תכנית, אם אני להדפיס T S וכמו שאני מנקה כאן, לצפות מה הולך לקרות להדפיס את ים ולא. אז להפוך את העותק-0, ./copy-0. תן לי ללכת קדימה והקלידו באמא בכל האותיות הקטנות. שים לב שני ומקורי העותק מהוון. למה? ובכן, זה לא ושניהם מצביעים ל, אם תרצה, את אותו הנתח של זיכרון. ולמען אמת, זה הוא מקבל באמת uninteresting-- העובדה שבו אנו משתמשים אפס כתובת כאן. אני מתכוון, לא ממש אכפת לי שבו דברים הוא בזיכרון. מצטער שאני מוחק קצת יותר מדי. אבל לא ממש אכפת לי שבו דברים נמצאים בזיכרון. וכך, אכן מה ש מתכנתים נוטים לחשוב על הוא שכאשר אתה מדבר על כתובת, או מצביע, למי אכפת שבו הוא נמצא בזיכרון. לא אכפת לי אם זה ב בית אחד או מליארד. אני פשוט אכפת שזה משתנה הוא ביעילות מצביע על נתח זה של זיכרון. וכך, מעתה ואילך, ולא להתפלפל על כתובות זיכרון שרירותיות, בואו פשוט להתחיל לצייר מצביעים כמצביעים, כחצים. אז מה זה ולא באמת, על פי תכנית זו, בגלל איך אני יצרתי לא, זה רק שני משתנים נפרדים מצביע באותו הנתח של זיכרון. ולא אכפת לנו היכן הם נמצאים. כדי שנוכל מופשט משם את הפרט הזה. אז איך אני יכול לתקן את זה? אם אני רוצה לכתוב גרסה של העותק תכנית שבעצם מעתיקה את המחרוזת ומנצל רק עותק, רק באופן אינטואיטיבי, מה צריך להיות מרכיב לפתרון שלנו? קהל: [לא ברור] דוד י מלאן: אנחנו צריכים מה? קהל: נתח של זיכרון. דוד י מלאן: אנחנו צריכים עוד נתח של זיכרון, נכון? אנחנו לא יודעים איך לעשות את זה עדיין, בהכרח. אבל אני צריך סוג של שזה יקרה כל כך שאמא המקורית באותיות קטנות בסופו של שנתח נוסף של זיכרון. ואז כשאני משנה את העותק, אני לא רוצה לשנות את העותק הזה כאן. אני במקום רוצה לשנות רק את זה עותק כך שמקורי יישאר ללא שינוי. אז, בואו לראות איך אנחנו יכולים לעשות את זה. בעותק-1, שבו יש כבר הופשט מתגובה, אבל הוא הגיב באינטרנט. אנחנו במקום לעשות following-- אלה קווים זהים, תקבל אותי מחרוזת וקורא לזה זה. אבל עכשיו בואו נסתכל על אחד של רובנו מורכב אך האחרון של המורכבות לזמן מה, קו 16 עושה בדיוק את זה. אז אם נוח עם תמונה אנחנו רק drew-- תן לי נתח חדש של זיכרון, להעתיק את הכל לתוך זה, בואו לראות איך אנחנו מתרגמים את זה לקוד. אז קו 16, בצד שמאל, char * t נותן לי תיבה זו כאן. זה כל מה שהיא עושה. בצד ימין, alloc מ ', או malloc, היא הקצאת זיכרון, סופר מפואר, דרך מסתורית של רק אומר תן לי נתח של זיכרון. כמה זיכרון אנחנו צריכים? ובכן, הוא סוג של ביטוי גדול. אבל בואו יראו את מה שכתוב כאן. אז זה, כמובן, הוא לתת לי שלי אורך המחרוזת של ים. אז, אמא שלו צריכה להיות מה? אז רק שלוש, נכון? אמא היא שלוש דמויות. אתה לא סופר קו נטוי אפס כאשר אתה מדבר על האורך של מחרוזת זה למעשה מכתבים גלויים האנושיים. אז אמא, אז זה נותן לי 3. אבל חכה רגע, אני עכשיו מוסיף 1. למה אני באמת רוצה להקצות 4 בתים ולא רק 3? כן? קהל: לערך הזקיף? דוד י מלאן: בדיוק, לכי ערך זקיף. ללוכסן אפס, אני צריך כולל 4 בתים. אז אני צריך את האורך של המחרוזת בתוספת 1. ואז פשוט לmeasure-- טוב למרות שעל מערכת זו, זה תמיד הולך להיות 1-- אני אומר להכפיל את זה על ידי הגודל של char. מתברר sizeof הוא מפעיל בC ש רק אומר לך מספר הבתים זה הנדרש לסוג נתונים מסוים. זה לא עובד עבור מערכים, בדרך כלל, לפעמים היא עושה. אבל במקרה הכללי, לא. אבל זה אומר לי כמה ביטים char הוא, שמתברר הוא תמיד 1. אז זה כמו הכפלה ב 1. קו מחפש אז סופר מסתורי של קוד. אבל כל שהיא עושה הוא נותנת שלי נתח של זיכרון. אבל האם זה נראה העתקה שום דבר לזיכרון ש? עדיין לא. ואז מה לעשות אני על קו 22, ו 23, 24, 25, טוב, אני פשוט עושה את זה. וזה סוג של דברים בית ספר ישנים עכשיו. זה כמו PSet 2, שבו אתה רק להזיז דברים סביב בזיכרון, או לייתר דיוק במחרוזות. אז אני iterating בין 0 ל אורכו של מחרוזת s. ואני מעתיק את אופי i-ה בים לאופי i-ה בt. ומכיוון שאני, מתכנת, עשה הקפד להקצות בתים בדיוק כמו רבים כמו שאני צריך, זה מושלם אחד-על-אחד יחסים. ואני מעתיק את אמא ב אותיות קטנות לאחד החדש. ואז לבסוף, אני עושה את הקו הזה. ולכן ההשפעה היא רק לנצל t זה כאן. כל כך הרבה לקלוט, אבל אם אתה רק רואה מה באמת קורה במתחת למכסת המנוע הוא פשוט זז אלה ביטים מסביב, כל מה ש יש צורך לפתור את הבעיה הזו היא רק כדי לתת לנו נתח זה של זיכרון. עכשיו בסיכון מכריע, תן לי להראות דוגמא אחרת שכמעט זהה, למעט זה אחד שורת קוד. אז זה גרסת ההאקר של תכנית זו, אם תרצה. אבל בואו רק לזקק אותו למה שקורה. קו 24 היה אמור להיות לא זה הסוגר אני מקבל של הסוגר אני. עכשיו, אני משנה את זה ל לא כוכב הרבה יותר מסתורי בתוספת שווה כוכב של תוספת 1 1. אז מה קורה ולמה יש לנו אופי כוכב? ראינו את כוכב העבר, ו הוא נמצא בשימוש בצורה שונה כאן. ראינו בעבר * char, עכשיו אני רואה כוכב בתחילת, וזה בסדר. כי מתברר ש סוג יכול להסיק מרק מאלו הראשונים עקרונות מה קורה. אז רק שיהיה ברור, מה הוא? של בשבוע שעבר, זה היה מחרוזת. זה לא יספיק יותר. מה הוא S, במיוחד? קהל: [לא ברור] דוד י מלאן: זה מצביע. זה הכתובת של הדמות הראשונה שהקלדנו ב. אישור, מה הוא לא? קהל: [לא ברור] דוד י מלאן: כתובת של הבית הראשון בt, נתח זה של זיכרון מוקם מחדש. אז מתברר שכאשר אנו לחזר בין 0 ועד למחרוזת length-- קודם כל, אני מתחיל ב 0, משום ש של בית ספר ישן זה דבר לולאה. אז רק לפשטות, בואו תניח שהשורה הראשונה של קוד הוא באמת רק זה, נכון. אם הוא אפס, אפס הוספה למשהו יש להניח הוא לא הולך להיות להם השפעה. אז מה זה אומר? מתברר שהכוכב מפעיל בהקשר זה הוא dereference מפעיל, שהוא רק דרך מפוארת של אומר ללכת לכתובת הבאה. אז אם זה הוא הכתובת של הראשון דמות בנתח זה של זיכרון, * s אמצעים ללכת לשם. ומפני שנמשכים התמונה בדרך זו, אתה יכול לאמץ הבא מודל המנטלי. אם זה של, ואתה אומר של *, * S כמו סוג של מצנחים וסולמות, אם אתה זוכר את המשחק מהילדות, זה כמו לעקוב אחרי החץ וללכת לכתובת. * לא הוא אותו הדבר. אז להתחיל כאן, ללכת לנתח שלה. אני לא יכול פשוט לצייר על מסך זה ככה. * לא אומר ללכת כאן. ולאחר מכן, ללולאה הוא פשוט אומר להזיז את הדמות של זה כאן, להזיז את הדמות של זה כאן, להזיז את הדמות של זה כאן. אבל איך אני עושה את incrementation ש? אני צריך לבטל את מה שאני פשוט נמחק. זה מה שנקרא בדרך כלל חשבון מצביע, ש פירוש מתמטיקה עם כתובות. אם, בזה ללולאה, אני כל הזמן הגדלה אני, והים הוא כתובת ולא הוא כתובת, אם אני רק לשמור על הוספת 1, זה רק אומר להמשיך לנוע קדימה, וקדימה, וקדימה בזיכרון. זה כמו רחוב אוקספורד, רחוב שבניין מדעי המחשב הוא על. בנייני CS הוא ברחוב אוקספורד 33. אז אם היו לך לעשות 33 רחוב אוקספורד בתוספת 1, שמביא אותך לאוקספורד 34 רחוב, רחוב אוקספורד 35 אז, אז רחוב אוקספורד 36, מה אלה בניינים הם למעשה - אם הם קיימים. וכך, זה כל מה שאנחנו עושים כאן עם חשבון מצביע. אז זה דרך סופר מסתורי לבטא את עצמנו. אבל כל מה שקורה מתחת למכסת המנוע רק לאחר כתובות אלה, כמו הבא מפה, אם תרצה, או הבא חצים כמו אנחנו נמשכים על המסך. אישור, הרבה לעכל. כל שאלה בתחביר, מושגים, מצביעים, malloc, או משהו דומה. כן, כאן ראשון. קהל: אז איפה ש אומר * לא * שווה toupper t, הוא שהולך לנצל כל האותיות או פשוט-- דוד י מלאן: אה, שאלה ממש טובה. אז בקו הזה כאן, 31, זה הולך לנצל המכתב הראשון או כל האותיות. אז בואו לענות על זה על ידי הולך בחזרה לעקרונות הראשונים. והעקרונות הראשונים כאן אני מתכוון פשוט ללכת להגדרות הבסיסיות של מה שכרוך בכך. אז toupper זה פונקציה שמנצל char. זה הכל. * לא אומר ללכת לfirst-- גש לכתובת בt. אז, בתמונה, אם זה הנתח זיכרון שהוקצינו עם malloc, וזה לא, * לא אומר ללכת כאן. בינתיים, אתה עובר כי הערך, מ 'אותיות קטנות לtoupper, אתה מקבל בחזרה ההון M, שבו אתה מכניס אותו? אתה שם את זה באותו מיקום. וזאת על ידי היגיון זה של אלה הגדרות בסיסיות זה רק ניצול המכתב הראשון אלא אם כן אתה לחזר עם אני או ללולאה או לולאה בזמן, זה לא הולך לעשות משהו יותר ממה שאתה שואל את זה. שאלה טובה. כן? קהל: מדוע אתה משתמש ב dereference שיטה ולא המערך? דוד י מלאן: אה, שאלה טובה. למה אתה משתמש dereference שיטה במקום שיטת המערך? אין סיבה מיוחדת, אם להיות כנה. ואכן, לזה סוג של דוגמא, תקין, אני רק טוען שהופך את תכנית מורכבת יותר, יותר עיניים מזוגגות, אנשים בודקים את כי זה נראה סופר מסתורי, אבל למרות שזה עושה את אותו הדבר. וכך, בכנות, זה פתרון שלא לצורך חזותי מורכב לבעיה. זה עדיין עיצוב טוב, חמש מתוך חמישה לעיצוב, בין אם זה במסגרת סימון או סימון המצביע. But-- במיוחד כאשר אנו מקבלים מאוחר יותר בקורס בPSet 5 כאשר אנו מיישמים מילון ש אני כבר ציינו כמה times-- אנחנו בעצם אכפת כתובות זיכרון ברמה נמוכה כי אנחנו באמת מבינים מה הולך. אבל, לעת עתה, מתברר שזה קו של סוגריים מרובעים כאן קוד לא קיימים באמת. הם מה שנקראו סוכר תחבירי, ש הוא רק דרך מוזרה מגניב לומר מהדר ממיר סוגריים מרובעים להיות שביטוי מתמטי. אז זה כנס אנושי כדי להיות מסוגל רק כדי לכתוב סוגריים אלה מאוד ידידותי למשתמש. אבל מה מהדר, צלצול, הוא באמת עושה כל זמן אתה כותב מה שמודגש בקו 24, מתחת למכסת המנוע זה באמת המיר אותו לזה. זה פשוט יותר מהנה כאדם לקרוא ולכתוב קוד כמו קו 24. אבל סופו של דבר אלה גלגלי עזר גם יורדים כאשר הנוחות של האדם עצמו מתחזקת. בסדר, אז זוכרים אז שזה היה הסוג של הבעיה הגדולה ביותר נתקלנו ב. וזה מה שעורר את כל זה שיחה אכפת מצביעים, וכתובות, ודברים העתקה. זה היה בגלל שאנחנו מעד הנושא הטיפש, הטיפש הזה, לפי אני מיושם logically-- עם לורן עד כאן על ההדגמה ומיץ התפוזים בmilk-- מושלם פונקציה נכונה אלגוריתמי להעברת שני משתנים " ערכים, אבל הדבר הארור לא היה לי שום מתמשך, או קבועה, השפעה על הקוד שלי. ולמה זה היה? בקליפת אגוז, למה זה יישום של החלפה מבחינה לוגית נכון, אבל אין לו השפעה על המשתנים שמועברים אליו, כמו x ו- y לעיקרי? מה היה עיקר הבעיה? כן? קהל: כי משתנה עשה עותקים של משתנה במעבר באמצעות פונקציה. דוד י מלאן: בדיוק, כאשר אתה עובר משתנים לפונקציה, או טיעונים לפונקציה, הם עבר על ידי העתקה, ש אומר שאתה מקבל זהה מחפש דפוס של ביטים לשני x ו- y, נקרא כאן וב. ואתה יכול לעשות כל דבר אתה רוצה עם עותקים אלה, אבל הם הולכים אין לי השפעה על תפקוד הקורא. ואכן, אנו ציירנו ש תמונה על המסך, כזכור הפעם האחרונה, לפיה אם באמת חושבים על מה קורה מתחת hood-- אם זה הזיכרון של המחשב שלך, וכאן למטה הוא הנתח של זיכרון בשימוש עבור עיקרי, זה הנתח של זיכרון בשימוש להחלפה, ויש לו כל כך, גם אם עיקרי שני משתנים, x ו- y, החלפה שאולי יש לי מחפש זהה ערכים, אשר שניהם 1 ו- 2, אבל הם לגמרי נתחים שונים של זיכרון. אז אנחנו צריכים פתרון לזה. ולמען אמת, זה היה נראה שאנחנו עכשיו יש פתרון לבעיה זו, נכון. אם עכשיו יש לנו את היכולת לתפעל דברים בדרך של כתובות ו, סוג של מצנחים וסולמות סגנון, בצע את החצים אלה וללכת לכל מקום שאנחנו רוצים בזיכרון, לא יכולתי ש לפתור בעיה זו על ידי עובר מראשי להחליף לא הערכים שאנחנו רוצים החלפה, אבל רק באופן אינטואיטיבי מה שאנחנו יכולים לעבור להחליף במקום? [חציצת קולות] דוד י מלאן: למה אנחנו לא פשוט להעביר אותו הכתובות, נכון? למה אנחנו לא נותנים החלפה מפת אוצר, אם תרצה, שמוביל אותו ל x בפועל ערכים ו- y. ההחלפה בואו, למעשה לשנות ביטים מקוריים אלה, ולא רק עובר עותקים של הביטים. וכך, למעשה, זה מה ש הולך להיות הפתרון. גרסה זו היא כאן ברור רע ופגום. ועכשיו, במבט ראשון, זה פשוט נראה כמו שהוספנו חבורה של כוכבים באופן אקראי וחצה את האצבעות שלנו שזה יהיה לקמפל. אבל, זה היה עכשיו לקמפל. אבל בואו נראה מה הדברים האלה אומר. ולמרבה הצער, מחברי C יכל לבחור סמל אחר כדי להפוך את זה קצת , אבל מפעיל הכוכב ברור יותר יש משמעות שונה ב שני הקשרים שונים. ושראינו את שניהם, אבל בואו להבחין. אז למעלה בחלק העליון יש, כשהשתניתי וב מלהיות int של ברע גרסה לint כוכבים, A ו- B, בעבר, היו שלמים. מה הם A ו- B עכשיו ב הגרסה טובה, ירוקה? הם כתובות. כתובות של מה, שתהיינה ברורות? כתובות של מספרים שלמים. אז העובדה שאני אומר אמצעי כוכב int זו הכתובת של שלם, באופן ספציפי. אז עכשיו שמו לב בשורות קוד, משהו אחר השתנה מדי. tmp נשאר זהה, משום ש זה רק המספר השלם הזמני, אין קסם זיכרון יש. אבל עכשיו צריך כוכב. ואכן, בכל אזכור נוסף של A ו- B, שם לב שכל זה שינוי מאדום לירוק הוא שאני קידומת אלה משתנים עם כוכבים. כי אני לא רוצה להעתיק וב. כי אם אני פשוט להעתיק וב והחלפה A ו- B, מה אני למעשה להחליף? רק כתובות, אני רוצה להחליף מה בכתובות אלה. אני רוצה ללכת לשם. וכך מפעיל הכוכב בתוך הפונקציה שלי, לא בתוך רשימת הפרמטרים, משמעו שאתה הולך לכתובות אלה ולמעשה לשנות ערכים אלה. אז מה עושה את התמונה עכשיו נראה כמו במקום. ובכן, אם במקום שאני עובר לA ו- B לא ו2-- 1 אני באמת צריך להוסיף הגדרה אחרת כאן. אז נניח שנתח זה זיכרון הוא במיקום 10. זה במיקום 11, אבל זה זה קצת פישוט, עכשיו יש לי שתי אפשרויות לעשות אני עובר x ו- y או שאני עובר את הכתובות שלהם? אם אני עובר את הכתובות שלהם כמו זה, אני רק עכשיו צריך ליישם החלפה לקוד הירוק כך שכאשר הוא רואה וכש רואה ב, זה לא פשוט להעתיק וב ולהעביר את חלב ומיץ תפוזים. מיץ חלב ותפוז מטפורה עכשיו נשברת, כי אלה הן כוסות מפות נוזליים ולא. אנחנו במקום צריכים ללכת כדי לטפל 10 ואנחנו צריך ללכת לכתובת 11, ו לאחר מכן לבצע שהיגיון ההחלפה. אז ההיגיון הוא אותו, אבל אנו זקוקים לדרך מעט שונה לגישה למשתנים אלו. וכך בסופו של הדבר, מה ש תכנית צריכה להיראות כמו זה. בswap.c להעתיק, פשוטו כמשמעו, ולהדביק את הגרסה הירוקה. אבל אני צריך לעשות שינוי אחד. זה לא מספיק רק כדי לשנות את ההחלפה. מה קו אחר של קוד אני צריך לעשות כדי לשנות? כן? קהל: איפה זה לוקח את הטענות. דוד י מלאן: איפה זה לוקח הטיעון שלה. אז אם אני לגלול עד עיקרי, אני לא יכול פשוט לעבור בx ו- y, ו, אני מבטיח, שעבר חתיכת התחביר החדש היום. אני צריך לעבור בלא x ו y אבל הכתובת של x ו- y. ומתברר, סמל כי מחברי C בחרו הוא אם אתה משתמש באמפרסנד כאן, לא ל להתבלבל עם האמפרסנד הסיבי האופרטור, אם אתה משתמש באמפרסנד כאן וכאן אמפרסנד, זה דמויות בשבילך, מה הכתובת של x, אולי זה 10, מה כתובת של y, אולי זה 11, ועובר אותם במקום. כל כך הרבה לקלוט בבת אחת. אבל בואו נראה עכשיו במהירות ב ארבע דקות שנותרו לנו שבו דברים יכולים להשתבש. וכמו בצד, למעשה לקחתי את התמונה הזאת, TF צלם את זה לפני שנה או שנים. אז זה הפינה האחורית של חדר אוכל אליוט. מצביעים הם אולי הכי הקשים נושא שאנו מכסים בCS50. אז אם אתה דואג מהסוג מדרון הוא כמו אולי זה יותר של מקל הוקי כמו זה, מבין אנחנו סוג של מתקרבים לשיאו ב מבחינת המורכבות הרעיונית. ואני מביא את זה תמונה, כי אני נשבע לאלוהים, בסתיו 1996, כאשר לקחתי CS50 עם בחור ההוראה שלי, Nishat מהטה, הוא הושיב אותי ב פינה של ד הול אליוט בארוחת צהריים, או ארוחת ערב, או משהו כדי לנסות כדי לעזור לי להבין מצביעים. וזה המקום שבו אני היה שבועות אחרי זה הוצג בהרצאה כש אני סוף סוף הבנתי מצביעים. ואני מקווה שזה יהיה לחץ כה מוקדם בשבילך. אבל מבין את זה לחלוטין בין הנושאים מתוחכמים יותר בדקנו. אבל זה בין החזק ביותר. וכאשר אתה מקבל את זה, זה באמת כל רק הולך סוף סוף הגיע יחד. אז היה סמוך ובטוח שזה לא צריך את כל הכיור בהיום. אז הנה התכנית האחרונה אנחנו הולכים להסתכל. ואנחנו הולכים לסיים עם שלוש דקות מהירות של אולפן שנעשה על ידי ידידנו, ניק Parlante. הנה תכנית, שעל שני העליונים קווים מצהיר x ו- y משתנה. שניהם כתובות של מספרים שלמים, מצביעי AKA. לאחר מכן, אנו להקצות מספיק זיכרון לאחסון int ולאחסן את כתובת זיכרון שבx. אז, זה אפילו פשוט יותר מהדוגמא קודמת. תן לי ארבעה בתים של זיכרון, זה הגודל של int, ולשים את כתובת שבx. קו זה כאן אומר גש לכתובת בx ולשים את המשמעות של חיים, המספר 42 שם. אבל הקו הזה מדאיג אותי. כוכב y אומר ללכת לכתובת בy, ולשים את מספר מזל 13 שם. למה זה מסוכן, בשלב זה בstory-- אם כי אמר לי מהירות בדקות האחרונות שלנו כאן-- למה זה רע לי לומר, ללכת לכתובת בy? קהל: יש לך לא [לא ברור]. דוד י מלאן: יש לי לא לשים שום דבר בy. אז מה הוא הערך של y, בנקודה זו בסיפור הזה? אין לנו מושג. זה קצת ערך זבל וגם לא יודע בינקי. אם אנחנו יכולים בסופו על הפתק הזה. [וידאו השמעה] היי, בינקי, להתעורר. זה זמן בשביל כיף מצביע. -מה זה? למד על מצביעים? אה, סוכריה. "טוב, כדי להתחיל, אני מניח שאנחנו הולך צריך כמה עצות. -אוקיי. קוד זה מקצה שני מצביעים אשר יכול להצביע על מספרים שלמים. או קיי, גם אני רואה שני מצביעים, אבל הם לא נראה שלא יהיה הצבעה לכל דבר. -זה נכון. בתחילה pointers אינו מצביע על שום דבר. הדברים שהם מצביעים עליהם נקרא pointees והקמתם הוא צעד נפרד. אה, נכון, נכון. ידעתי את זה. Pointees הם נפרדים. אז איך אתה להקצות pointee? או קיי, גם מקצה את הקוד הזה pointee השלם חדש, וx סטי חלק זה כדי להצביע על זה. היי, זה נראה טוב יותר. אז לעשות את זה לעשות משהו. או קיי, אני dereference x המצביע ל לאחסן את המספר 42 לpointee. על הטריק הזה, אני צריך שרביט קסם של ביטול הפניה. שרביט קסם -Your של ביטול הפניה? אה, זה, זה נהדר. 'זה מה הקוד נראה. אני רק להגדיר את המספר and-- [POP SOUND] היי, נראה שם זה הולך. אז, עושה dereference על x כדלקמן החצים כדי לגשת pointee. במקרה זה, לאחסון 42 שם. היי, נסה להשתמש בו כדי לאחסן המספר 13 דרך המצביע האחר, y. -אוקיי. אני פשוט אלך לכאן כדי y, ולקבל להגדיר מספר 13. ואז לקחת את השרביט של ביטול הפניה ופשוט-- [הזמזם SOUND] אה, היי זה לא עבד. אומר, אה, בינקי, אני לא חושב ביטול הפניה y הוא רעיון טוב, כי הגדרה עד pointee הוא צעד נפרד. ואני לא חושב שאי פעם עשינו את זה. -Hmm, נקודה טובה. 'כן, אנחנו הוקצו המצביע, y, אבל אנחנו אף פעם לא להגדיר אותו כדי להצביע על pointee. -Hmm, מאוד דתי. היי, אתה נראה טוב שם, בינקי. האם אתה יכול לתקן את זה, כך שנקודות y לאותו pointee כx. -Sure, אני משתמש בשרביט הקסם שלי של משימת מצביע. -זה גם הולך להיות בעיה, כמו לפני? -לא, זה לא נוגע pointees. זה רק משנה מצביע אחד כדי להצביע על אותו thing-- [קולות נפץ] --as אחר. -אני מבין. עכשיו נקודות y לאותו המקום כמו x. אז, לחכות, עכשיו y הוא קבוע. יש לו pointee. אז אתה יכול לנסות את השרביט של ביטול הפניה שוב לשלוח מעל 13. אה, אוקיי, הנה זה בא. היי, תראה את זה. עכשיו ביטול הפנית עבודות על y. ומכיוון שהמצביעים משתפים שpointee אחד, שניהם לראות את 13. 'כן, שיתוף, אה, לא משנה מה. אז, אנחנו הולכים לעבור מקומות עכשיו? אה, נראה שאנחנו מחוץ לזמן. -But-- פשוס לזכור שלושה כללי מצביע. מספר 1, את המבנה הבסיסי הוא שיש לך מצביע, והוא מצביע אל pointee. אבל והמצביע pointee הם נפרדים. והטעות הנפוצה הוא להגדיר מצביע אבל לשכוח לתת לו pointee. מספר 2, ביטול הפנית מצביע מתחיל במצביע ולהלן חיצו מעל כדי לגשת לpointee. כפי שכולנו יודעים, זה עובד רק אם יש הוא pointee, איזה סוג של מקבל בחזרה לפסוק מספר 1. מספר 3, מצביע משימה לוקחת מצביע אחד ומשנה אותו כדי להצביע על אותו pointee כמצביע אחר. אז אחרי המשימה, שני מצביעים יצביע לאותו pointee, לפעמים זה נקרא שיתוף. וזה כל מה שיש בו, באמת. ביי ביי עכשיו. [סוף ההשמעה] דוד י מלאן: זהו זה לCS50. תודה לפרופסור ניק Parlante. נתראה בשבוע הבא. [השמעת מוסיקה אלקטרונית]