דוד Malan: שלום, ו ברוך שובך לCS50. אז זהו סוף השבוע ארבעה. רק אחד הודעה ראשונה. אז מה שנקרא החמישי יום שני הוא מתקרב ליום השנייה הקרוב. זו ההזדמנות לשנות מ SAT / UNSAT לכיתת מכתב, או מ מכתב כיתה SAT / UNSAT. מעצבן, כי תהליך דורש חתימה, כי אתה צריך למלא את אחת מהצורות להוסיף / טיפה הוורודות האלה. כי מבחינה טכנית, SAT / UNSAT גרסה וגרסת כיתה המכתב יש מק"טים שונים. אבל לא עניין גדול. פשוט לבוא אליי או לRob או ללורן בכל נקודה. או שלח לנו דוא"ל אם אין לך את הסוג ניירת שאתה צריך היום, ואנחנו יהיה בטוח שתעזרו לך לקחת טיפול שלפני יום שני. בסדר, אז היום - למעשה, יש קצת הד. אנחנו יכולים למתן אותי קצת? אישור. אז היום, אנחנו מציגים את נושא ידוע כמצביעים. ואני מודה שזו אחת נושאים מורכבים יותר שאנו נוטים לכסות במעמד הזה, או בעצם כל קורס מבוא המשתמש ג אבל תסמוך על המילה שלי בשביל זה, במיוחד אם המוח שלך מרגיש קצת יותר מכופף היום ובשבועות הבאים. זה לא נציג שלך מקבל יותר גרוע בזה זה רק אומר ש זה נושא מתוחכם במיוחד שאני מבטיח, כמה שבועות לכן, ייראה כל מדי בולט פשוט במבט לאחור. אני עדיין זוכר עד עצם היום הזה. אני ישבתי באולם אוכל אליוט, ישב ליד TF Nishat מהטה, מי שהיה תושב אליוט הבית. ומשום מה, זה נושא פשוט לוחץ. וזה אומר שגם אני נאבקתי עם זה לכמות מסוימת של זמן, אבל אני יעשה כמיטב יכולתי לסייע להימנע מכל כגון מאבק עם נושא שסופו של דבר הוא די חזק. למעשה, אחד הנושאים נדון בשבועות הבאים הוא כי של ביטחון, ואיך אתה יכול באמת לנצל את המכונות בדרכים שלא התכוונו אליו. וexploitations אלה הם בדרך כלל התוצאה של חרקים, טעויות שאנחנו אנשים עושים בכך שלא הבין חלק של היישום הבסיסי פרטים באמצעות תוכניות שהם עשו. עכשיו כדי להפוך את זה נראה כל המשתמש יותר ידידותי, חשבתי שאני רוצה לשחק 10 תצוגה מקדימה שנייה של אולפן קטן דמות בשם בינקי שהובא ל חיים על ידי חבר שלנו בסטנפורד, פרופסור ניק Parlante. אז הרשה לי לתת לך את זה טיזר של בינקי כאן. [השמעת וידאו] -היי, בינקי. להתעורר. זה זמן בשביל כיף מצביע. , מה זה? למד על מצביעים? אה, יופי. [השמעת וידאו הסוף] מלאן דוד: זה הוא סטנפורד מדעי מחשב. אז עוד על כך לבוא. [מחיאות כפות] דוד Malan: מצטער, ניק. אז זוכר שהפעם האחרונה שנסתיימו ביום סחרור מסוכן באמת זה מרגש לפי פונקציה זו פשוט לא עבד. לפחות באופן אינטואיטיבי, זה הרגיש כמו שזה צריך לעבוד. פשוט להחליף את הערכים של שני מספרים שלמים. אבל זוכר שכאשר אנו הדפסנו ערכים מקוריים בראשי, ואחד שתיים, הם עדיין הייתם אחד ו שתיים ולא שתיים ואחד. אז תן לי בעצם לעבור מעל למכשיר. ואני כתבתי קצת קוד של שלד ב לקדם כאן, שבו אני טוען שX יהיה 1, y יהיה 2. אני מכן להדפיס את שניהם ערכים עם F ההדפסה. אז אני טוען כאן כי אנחנו הולכים להחליף אותם. עזבתי את מקום ריק כאן בשבילנו מלא היום ברגע. לאחר מכן, אני הולך לטעון כי שני משתנים כבר החליפו. ואז אני הולך להדפיס אותם שוב. וכך אני מקווה, אני צריך לראות 1, 2. 2, 1. זה פשוט הסופר מטרה עכשיו. אז איך אנחנו הולכים על החלפה שני משתנים? ובכן, אם אני מציע כאן שהכוסות הללו עשוי לייצג בזכרון מחשב. זה כמה נגיסות, זה הוא עוד כמה נגיסות. אפשר שיש לנו מתנדבים לבוא בעד ו לערבב אותנו כמה משקאות, אם מוכר? בואו נעלה. מה שמך? JESS: ג'ס. דוד Malan: ג'ס? בואו למעלה, ג'ס. אם לא אכפת לך, אנחנו צריכים לשים את זכוכית גוגל עליך כדי שנוכל להנציח את זה. אוקיי, זכוכית. להקליט וידאו. ובסדר, אנחנו טוב ללכת עם ג'ס כאן. בסדר. נע מאוד. אז מה אני רוצה שאתם עושים כאן - אם אתה יכול, די מהר - פשוט שופך לנו חצי כוס התפוזים מיץ וחצי כוס חלב, מייצג למעשה את המספרים 1 בכוס אחת ו -2 בגביע האחר. זה הולך להיות סרט טוב. JESS: מצטער. מלאן דוד: לא, לא. זה בסדר. נחמד. בסדר, אז יש לנו ארבעה בתים שווה של מיץ תפוזים. אנחנו קראנו לזה את הערך 1. עכשיו ארבעה בתים אחרים שווים של חלב. האם לקרוא לו ערך 2. אז X ו-Y, בהתאמה. בסדר, אז עכשיו אם את המשימה בהישג יד - בשבילך, ג'ס, מול כל מהכיתה שלך - הוא להחליף את ערכי X ו-Y, כגון כי אנחנו רוצים את מיץ התפוזים ב כוס השנייה ואת החלב בכוס הזאת, איך אולי אתה - לפני שאתה בעצם עושה זה - ללכת על עושה את זה? מניח את הדעת, חכם החלטה. אז אתה צריך קצת יותר זיכרון. אז בואו נקצה זמני גביע, אם תרצה. ועכשיו להמשיך להחליף X ו-Y. מצוין. אז עשה טוב מאוד. תודה רבה לך, ג'ס. הנה בבקשה. מזכרת קטנה. אוקיי, אז כמובן, רעיון פשוט סופר. אינטואיטיבי לחלוטין שאנחנו צריכים קצת שטח אחסון נוסף - בצורה זו, כוס - אם אנחנו באמת רוצים להחליף את שני המשתנים הללו. אז בואו לעשות בדיוק את זה. עד כאן בין שבו אני טוען שאני הולך לעשות קצת החלפה, אני יהיה קדימה ולהכריז זמני. ואני מגדיר את זה שווה, יניח, x. ואז אני הולך לשנות את הערך של X בדיוק כמו ג'ס עשה כאן עם חלב ומיץ תפוזים להיות שווה ל-Y. ואני הולך לשנות את y להיות שווה כדי לא X, כי עכשיו אנחנו יהיו תקוע במעגל, אלא זמני. איפה אני באופן זמני - או היכן ג'ס באופן זמני את מיץ התפוזים לפני שמחץ כוס עם החלב. אז תן לי ללכת קדימה ולעשות את זה עכשיו. זה נקרא noswap.c. ועכשיו תן לי לרוץ ללא החלפה. ואכן אני רואה, אם אני מרחיב חלון קצת, כי X הוא 1, y הוא 2. ואז X הוא 2, y הוא 1. אבל תזכור כי ביום שני שעשינו דברים קצת אחר שבו אני במקום ליישם פונקציה עוזרת, אם תרצה, שהיה למעשה מבוטל. אני קראתי לה להחליף. אני נתתי לו שני פרמטרים, ואני קראתי שלהם וקראתי להם ב. בכנות, אני יכול לקרוא להם X ו-Y. אין שום דבר שמונע אותי מלעשות את זה. אבל אני טוען שזה אז קצת מעורפל. בגלל החזרה ליום השני שאנחנו טען כי פרמטרים אלה היו עותקים של הערכים עברו פנימה אז זה פשוט מתעסק עימך מוח, אני חושב, אם אתה משתמש בדיוק באותם משתנה. אז אני במקום אתקשר אליהם ו-B, רק בשביל בהירות. אבל אנחנו יכולים לקרוא להם ביותר כל דבר שאנחנו רוצים. ואני מתכוון להעתיק ולהדביק ביעילות את הקוד הזה מלמעלה למטה לתוך כאן. כי אני פשוט ראיתי שזה עובד. אז זה בצורה די טובה. ואני תשנה X שלי, שלי X ל, y שלי ל-B ו-y שלי ל-B. אז במילים אחרות, בדיוק באותו היגיון. בדיוק את אותו הדבר שעשתה ג'ס. ואז הדבר היחיד שאני צריך לעשות את כאן, כמובן, עכשיו זה לעורר פונקציה, או להתקשר בפונקציה זו. אז אני אקרא בפונקציה זו עם שתיים תשומות, X ו-Y, ולהיט 'שמור'. בסדר, כל כך בסיסי את אותו הדבר. למעשה, אני כנראה כבר עשיתי את התכנית שלא לצורך על ידי קומפלקס כתיבת פונקציה שרק לוקח כשש שורות של קוד ואילו אני בעבר היה מיושם בדיוק את זה בשלוש. אז תן לי ללכת קדימה עכשיו ולעצב מחדש זה, לא עושה שום החלפה. בסדר, אני דפוק כאן. זו צריכה להיות שגיאה שתוכל רואה יותר ויותר בכינוי שלך תוכניות מורכבות יותר ויותר. אבל יש תיקון קל. תן לי לגלול חזרה לכאן. ומה השגיאה הראשונה שאני רואה? הצהרה המרומזת. מה זה מצביע בדרך כלל? אה, שכחתי את האבטיפוס. שכחתי ללמד את המהדר שהחלפה הולך להתקיים למרות שהוא לא קיימת ממש בהתחלה של התכנית. אז אני פשוט הולך להגיד חלל, החלפה, int, int b, פסיק. אז אני לא הולך לreimplement את זה. אבל עכשיו זה תואם את מה שכאן למטה. ושים לב, העדר פסיק כאן, שאין צורך בי יישום. אז תן לי לסדר את זה, לא עושה שום החלפה. מצב הרבה יותר טוב. הפעלה לא החלפה. ולעזאזל. עכשיו אנחנו שוב איפה שהיינו ביום שני, שבו הדבר לא להחליף. ומהו ההסבר הסביר אינטואיטיבית למה זה המקרה? כן? תלמיד: [לא ברור]. דוד Malan: בדיוק. אז A ו-B הם עותקים של X ו-Y. ולמעשה, בכל זמן שהיית קורא לפונקציה שעד כה עובר משתנים כמו ints - בדיוק כמו החלפה מצפה כאן - אתם כבר עוברים בעותקים. עכשיו זה אומר שזה לוקח קצת של זמן, שבריר שני, עבור מחשב כדי להעתיק את הקטעים מאחד משתנה לפיסות אחרת. אבל זה לא כזה ביג דיל. אבל הם בכל זאת העתקה. וכך עכשיו, בהקשר של עסקת ההחלף, אני למעשה בהצלחה שינוי A ו-B. למעשה, בואו נעשה מהיר שפיות לבדוק. F ההדפסה הוא% אני, שורה חדשה. והתקע בואו ב. עכשיו בואו נעשה את אותו דבר עם b. ובואו נעשה את אותו דבר כאן. ועכשיו, תן לי להעתיק את אותם קווים שוב בחלק התחתון של הפונקציה אחרי שלוש השורות שלי מעניין היה יכול להיות מוצא להורג, ו להדפיס ושוב ב. אז עכשיו בואו נעשה את זה, לא עושה שום החלפה. תן לי לעשות את חלון המסוף קצת יותר גבוה, כך שאנו יכולים לראות יותר מזה בבת אחת. ולהפעיל שום החלפה. X הוא 1, y הוא 2. הוא 1, B הוא 2. ואז, הוא 2, B הוא 1. אז הוא פועל, בדיוק כמו ג'ס עשה כאן בפנים של החלפה. אבל כמובן, זה שאין לו השפעה על המשתנים העיקריים ב. אז ראינו את טריק לפיו אנו אפשר לתקן את זה, נכון? כאשר אתה מתמודד עם זה בטווחים בעיה, אתה יכול פשוט להפוך את הדוגית וX ו-y איזה סוג של משתנים במקום? אתה יכול להפוך אותם לעולמי. שימו אותם בחלקו העליון של הקובץ כפי שעשינו, אפילו במשחק של 15. אנו משתמשים במשתנה גלובלית. אבל בהקשר של המשחק 15, זה הגיוני שיהיה לי גלובלי משתנה המייצגת את המועצה, כי מכלול 15.c הוא כל על יישום את המשחק הזה. זה מה שהקובץ קיים לעשות. אבל במקרה הזה כאן, אני קורא החלפת פונקציה. אני רוצה להחליף את שני משתנים. וזה צריך להתחיל להרגיש פשוט מרושל אם הפתרון לכולנו בעיות כאשר אנחנו נתקלים בהיקף בעיות היא לעשות את זה בעולם. כי מהר מאוד התכנית שלנו היא הולך להיות די בלגן. ואנחנו עשינו את זה מאוד במשורה כתוצאה מכך ב15.c. אבל מתברר שיש דרך טובה יותר לגמרי. תן לי בעצם לחזור ולמחוק את להדפיס F של, רק כדי לפשט את הקוד הזה. ותרשו לי להציע כי זו, אכן, היא רעה. אבל אם אני במקום להוסיף כמה כוכביות וכוכבים, אני יכול במקום להפוך את זה פונקציה לאחד זה מבצעי בפועל. אז תן לי לחזור לכאן ולהודות לומר כוכביות היא תמיד קשה, אז אני אגיד את הכוכבים. אני רק אודה לזה. בסדר. ועכשיו, מה אני הולך לעשות במקום? אז קודם כל, אני הולך כדי לציין כי במקום עובר לתוך int פונקצית swap, אני במקום מהולך להגיד כוכב int. עכשיו, מה עושה הכוכב עולה? זה רעיון ששל מצביע כי בינקי, דמות האולפן, הייתה בהתייחסו לרגע לפני. אז אם אנחנו אומרים כוכב int, את המשמעות של זה עכשיו הוא שהוא לא הולך להיות עבר על ידי הערך שלו. זה לא הולך להיות מועתק פנימה במקום זאת, את הכתובת שלו הולך להיות מועבר פנימה אז זוכר שבתוך המחשב שלך היא חבורה שלמה של זיכרון, אחרת ידוע כזכרון RAM. וזכרון RAM שהוא רק חבורה שלמה של בתים. אז אם יש לך MAC או למחשב שתי ג'יגה, יש לך 2 מליארד בייטים של זיכרון. עכשיו בואו רק נניח שרק כדי לשמור על דברים נחמדים ומסודרים, אנחנו להקצות כתובת - מספר - לכל בייט של זיכרון RAM במחשב שלך. הבתים הראשון של 2 אלה מיליארדים הוא מספר באפס. הקטע הבא הוא מספר הבתים מספר אחד, שתיים, כל הדרך למעלה, נקודת נקודה נקודה, לכ -2 מליארד דולרים. אז אתה יכול כמה מהבתים זיכרון במחשב שלך. אז בואו נניח שזה מה אנו מתכוונים בכתובת. אז כשאני רואה כוכב int, מה קורה כדי להיות מועבר להחלפה כרגע הוא כתובת של. לא את הערך שלו, אבל מהו דואר כתובת היא, אם אפשר לומר כך - מיקומו בזכרון RAM. ובאופן דומה עבור b, אני הולך לומר את אותו דבר. Int, כוכב, ב. במאמר מוסגר, מבחינה טכנית כוכבים יכל ללכת במקומות אחרים. אבל אנחנו סטנדרטיזציה על הכוכב להיות ממש בסמוך לסוג הנתונים. אז להחליף חתימה עכשיו אומרת, תן לי הכתובת של int, ושיחה כי כתובת. ותן לי כתובת אחרת של int ולקרוא ב כתובת זו. אבל עכשיו הקוד שלי כאן חייב להשתנות. כי אם אני מצהיר טמפ int - שהוא עדיין מסוג int - אבל אני מאחסן בזה, איזה סוג של ערך? כדי להיות ברור, אני מניח עם הקוד כפי שנכתב ממש עכשיו? אני שם את המיקום ב. אבל לא אכפת לי מיקום עכשיו, נכון? טמפ 'קיים רק הגביע השלישי "ג'ס קיים, לאיזו מטרה? כדי לאחסן את ערך. חלב או מיץ תפוזים. לא ממש לאחסן את הכתובת של אף אחד מהדברים האלה, שמרגיש קצת שטותי בזה אמיתי הקשר עולם בכל מקרה. אז באמת, מה שאני רוצה לשים בטמפ לא את הכתובת של, אבל תוכן. אז אם הוא מספר כמו 123, זו היא הבתים של זיכרון 123 שרק קורה להיות כובש, כי הערך בקורה להיות כובש. אם אני רוצה ללכת לכתובת ש, אני צריך להגיד את הכוכב. בדומה לכך, אם הייתי משנה את מה בכתובת, אני משנה זה כדי להתחיל. אם אני רוצה לאחסן במה ב מיקום עם מה במיקום ב-B, B כוכב כוכב. אז בקיצור, גם אם זה לא די שוקע בעדיין - ואני לא הייתי מצפה כי זה היית כל כך מהר - להבין שכל מה שאני עושה הוא קידומת כוכבים אלה למשתנים שלי, אומרים שאין לתפוס את הערכים. אין לשנות את הערכים. אלא, הולכים לכתובות אלה ולקבל את התמורה. מעבר לכתובת ושינוי ש הערך שם. אז עכשיו תן לי לגלול חזרה לפסגה, רק כדי לתקן את הקו הזה כאן, כדי לשנות את אב הטיפוס כדי להתאים. אבל עכשיו אני צריך לעשות עוד דבר אחד. באופן אינטואיטיבי, אם אני כבר שיניתי את הסוגים טיעונים של החלפה שהוא מצפה, מה עוד אני צריך לעשות כדי שינוי בקוד שלי? כאשר אני קורא ההחלף. כי כרגע, מה אני אני עובר להחליף עדיין? X הערך והערך של y, או חלב ומיץ התפוזים. אבל אני לא רוצה לעשות את זה. אני רוצה להעביר במקום במה? המיקום של X ו המיקום של y. מה הן כתובות הדואר שלהם, אם אפשר לומר כך. אז כדי לעשות את זה, יש אמפרסנד. סוג של אמפרסנד נשמע כמו כתובת. כך n, אמפרסנד, הכתובת של x, ואת הכתובת של y. אז זה מכוון שאנו משתמשים אמפרסנד כאשר הקריאה לפונקציה, וכוכבים כשהכריזו ומתי יישום הפונקציה. ורק לחשוב על אמפרסנד כ כתובת של מפעיל, וכוכב כמו ללכת לשם מפעיל - או, יותר נכון, מפעיל dereference. אז זה המון מילים רק כדי אומרים את זה עכשיו, בתקווה, ההחלפה הולכת כדי להיות נכון. תן לי להמשיך ולעשות - בואו באמת לשנות את שם הקובץ, פן תכנית זו עדיין להיקרא לא החלפה. אני טוען שאנחנו קוראים לזה swap.c עכשיו. אז לעשות, להחליף. נקודה, לוכסן, להחליף. ועכשיו אכן, x הוא 1, y הוא 2. ואז, הוא x 2, y הוא אחד. ובכן בואו תראו אם אנחנו לא יכולים לעשות את זה קצת אחר על מה זה קורה כאן. ראשית, הרשו לי להתמקד עלינו ציור מסך כאן. ותרשו לי להציע לרגע - ו בכל פעם שאני מצייר כאן יהיה שיקוף עד לשם עכשיו - תנו לי להציע כי הנה חבורה שלמה של זיכרון, או זיכרון RAM, חלק פנימי של המחשב שלי. וזה יהיה מספר ביס, נניח, 1. זה יהיה בתים מספר 2. ואני אעשה את כל חבורה יותר, ו לאחר מכן חבורה של נקודות נקודת נקודה כדי מצביע על כך שיש 2 מליארד מהדברים האלה. 4, 5, וכן הלאה. אז יש חמשת הבתים הראשונים מהזיכרון של המחשב שלי. בסדר? מעטים מאוד מתוך 2 מליארד דולרים. אבל עכשיו אני הולך להציע את הדברים הבאים. אני הולך להציע כי X הולך לאחסן את המספר 1, והוא הולך y כדי לאחסן את המספר 2. ותנו לי ללכת קדימה עכשיו ומייצג ערכים אלה באופן הבא. בואו לעשות את זה באופן הבא. תן לי רק שני אחת. שנייה אחת. אישור. אני רוצה לעשות את זה קצת - בואו נעשינו את זה שוב. אחרת אני הולך ולשימוש אותם מספרים, שלא בכוונה, מספר רב של פעמים. אז פשוט כל כך שיש לנו מספרים שונים לדבר עליו, בואו נקראים לזה בתים מספר 123, 124, 125, 126, ונקודת נקודת נקודה. ותנו לי טוען עכשיו שאני הולך לשים את ערך 1 כאן, ואת הערך 2 כאן, הידוע גם בX ו-Y. אז זה פשוט כל כך קורה כי זה הוא x, y זה. ורק על ידי כמה סיכוי אקראי, מחשב, מערכת ההפעלה, קרה לשים X במיקום מספר 123. ו-y בסופו במיקום 124 - לעזאזל. אני הייתי אמור לתקן את זה. אה גבר, האם אני באמת רוצה לעשות את זה? כן, אני רוצה לתקן את זה ו ב נכון על זה היום. מצטער, חדש בזה. 127, 131, ואני לא רוצה שזה יהיה מורכב, אבל למה שאני משנה מספרים שם? כי אני רוצה את ints ל למעשה יהיה ארבעה בתים. אז בואו להיות סופר אנאלי על זה. כך שאם קורה 1 יש לטפל 123, 2 הולכים להיות בכתובת 127 בגלל שזה רק 4 פרידות משם. זה הכול. ואנו לשכוח את כל כתובות אחרות בעולם. אז x הוא במיקום 123, y הוא במיקום 127. ועכשיו, מה לעשות אני ממש רוצה לעשות? כאשר אני קורא להחליף עכשיו, מה בעצם קורה פה? ובכן, כאשר אני קורא להחלפה, אני מעביר ב הכתובת של X ואת הכתובת של y. כך למשל, אם שני חלקים אלה נייר עכשיו מייצגים את שני טיעונים וB להחליף, מה אני הולך לכתוב על הראשונה שבן, שאני הולך להתקשר מתייחס כאל? בדיוק, 123. אז זה שאני טוען הוא. זהו הפרמטר. אני מכניס את הכתובת של x לשם. מה זה? מה זה? לא, לא. זה בסדר. עדיין טוב, עדיין טוב. אז זהו. ועכשיו בקטע השני של נייר, זה הולך להיות ב ', ומה אני הולך לכתוב על הנייר הזה? 127. אז דבר היחיד שהשתנה מאז המאלף הקודם שלנו של הסיפור הזה הוא, ולא, פשוטו כמשמעו, 1 ו -2, אני הולך לעבור ב123 ו -127. ועכשיו אני הולך לשים אותם בתוך של תיבה זו, בסדר? כך שהקופסה שחורה מייצגת כיום פונקצית swap. בינתיים, בואו עכשיו יש לי של מישהו מיישם את פונקצית swap. האם מישהו כאן למעלה רוצה להתנדב? בואו נעלה. מה שמך? צ'רלי. בסדר, צ'רלי. בואו נעלה. אז צ'ארלי הולך לשחק תפקידה של הקופסה השחורה שלנו. וצ'רלי, מה שהייתי רוצה שתעשה כעת הוא ליישם את ההחלפה באופן כזה כי, בהתחשב בשתי הכתובות האלה, אתה בעצם הולך כדי לשנות את הערכים. ואני אלחש לך באוזן כיצד להפעיל את טלוויזיה כאן. אז קדימה, ואתה את הקופסה השחורה. להגיע לשם. מה ערכים שאתה רואה ל, ו מה ערכים שאתה רואה לב? צ'ארלי: הוא 123 ו-B הוא 127. דוד Malan: בסדר, בדיוק. עכשיו יש להשהות לרגע. הדבר הראשון שאתה הולך לעשות עכשיו, על פי הקוד - אשר אני עכשיו אצטרך להרים על המסך - הולך להיות להקצות קטנה קצת זיכרון בשם זמני. אז אני הולך קדימה לתת לך את הזיכרון. אז זה הולך להיות משתנה שלישי שיש לך נגיש ל אתה נקרא זמני. ומה אתה הולך לכתוב על פיסת נייר הזמנית? צ'ארלי: מצביעים, נכון? דוד Malan: בסדר, גם לא דווקא מצביעים. אז שורת קוד שיש לי מודגש בצד ימין, בואו נתחיל שם. זה אומר כוכב. אז שומר כעת מספר 123. ורק באופן אינטואיטיבי, מה לא כוכב 123 אומר? אבל באופן ספציפי, אם הוא 123, כוכב מה זה אומר? הערך. או יותר כבדרך אגב, ללכת לשם. אז הרשה לי להציע את זה, מחזיק ב היד שלך, קדימה ולטפל בזה כאילו זה מפה. וללכת על עצמך למחשב של זיכרון, ולמצוא לנו מה היא במיקום 123. בדיוק. כך אנו רואים במיקום 123 מה, ברור? אוקיי, עכשיו, אז מה ערכך הולך להכניס זמני? בדיוק. אז קדימה, לעשות את זה. ולכתוב את המספר 1 בפיסה נייר שכרגע זה שכותרתו זמנית. ועכשיו השלב הבא ש אתה הולך ליישם הולך להיות מה. ובכן, בצד של הזכות השורה הבאה של קוד היא כוכב ב. ב ', של כמובן, מאחסן את כתובת. כי כתובות 127. כוכב B מתכוון למה, כבדרך אגב מדבר? עבור למיקום זה. אז קדימה, תמצא אותנו מה במיקום 127. אישור. כמובן, במיקום 127, עדיין הערך 2. אז מה אתה הולך עכשיו בחנות כל מה שהוא במיקום ב? אז כוכבים אמצעי ללכת למיקום. מהו המיקום? בדיוק. אז עכשיו, אם אתה רוצה לשנות מה במיקום זה - אני אלך קדימה ולרוץ המחק נמצא כאן. ועכשיו החזיר אותו על המברשת. מה מספר שאתה הולך לכתוב שבתיבה הריקה עכשיו? בדיוק. אז הקו הזה של קוד, כדי שיהיה ברור - תן שלי להשהות את מה שעושה צ'רלי ו תציין כאן, מה שהוא עשה הוא פשוט לכתוב שלתיבה במיקום 123 הערך שהיה בעבר ב-B. ולכן אנחנו עכשיו כבר מיושמים אכן קו שני זה של קוד. עכשיו למרבה הצער, יש עדיין שורה אחת שנותרה. עכשיו מה שנמצא בטמפ ', פשוטו כמשמעו? זה ללא ספק מספר אחד. זה לא כתובת. זה רק מספר, סוג של משתנה משבוע אחד. ועכשיו כשאתה אומר הכוכב B, שפירושו ללכת לב הכתובת, שהוא של כמובן כאן. אז ברגע שאתה מגיע לשם - אני אלך קדימה ולמחוק את מה בעצם שם - ומה אתה הולך לכתוב עכשיו ב127 מיקום? צ'ארלי: בטמפ ', שהוא אחד. דוד Malan: טמפ ', שהוא אחד. ומה קורה לטמפ 'בסופו של הדבר? ובכן, אנחנו לא באמת יודעים. אנחנו לא ממש אכפת לי. בכל פעם שיש לנו מיושמת פונקציה עד כה, כל משתנים מקומיים שיש לך אכן מקומי. והם פשוט נעלמים. הם נתבעו על ידי ההפעלה מערכת סופו של דבר. אז העובדה שעדיין יש לו זמני ערך 1 הוא סוג של היסוד לא מעניין לנו. בסדר, אז מחיאות כפות אם היינו יכול לצ'רלי. עשה טוב מאוד. בסדר, אז מה עוד עושה זה אומר שאנחנו יכולים לעשות? אז מתברר שאנחנו כבר לספר כמה שקרים לבנים די הרבה זמן. ואכן, מתברר כי מחרוזת, כל הזמן הזה, הוא לא באמת רצף של תווים כשלעצמה. זה סוג של שהוא באופן אינטואיטיבי. אבל מבחינה טכנית, היא מחרוזת סוג הנתונים שאנו הכריזו פנימיים של ספריית CS50 כדי לפשט את העולם בשבועות הראשונים של כיתה. מה באמת היא מחרוזת היא הכתובת של דמות במקום כלשהו בזכרון RAM. מחרוזת היא באמת מספר, כמו 123 או 127, זה קורה לתיחום שבו מתחילה במחרוזת זכרון המחשב שלך. אבל זה לא מייצג מחרוזת, כשלעצמה, את עצמו. ואנחנו יכולים לראות את זה באופן הבא. תן לי ללכת קדימה ולפתוח את איזה קוד זה בקרב דוגמאות קוד המקור של היום. ואני הולך קדימה, לפתוח עד, נניח, להשוות-0.c. זוהי תכנית מרכבה, כי הוא הולך לייעשה באופן הבא. ראשון. אני הולך להגיד משהו. ואז אני הולך קדימה, מקבל מחרוזת מהמשתמש שבשורה הבאה. ואז אני הולך להגיד את זה שוב. ואז אני הולך לקבל עוד מחרוזת מהמשתמש. ושים לב, אני מראה אחד מחרוזות במשתנה בשם S, ו נוסף של מחרוזות אלה במשתנה בשם t. ועכשיו אני הולך לתבוע, מאוד סביר, שאם זה לא שווה שווה, המיתרים הם אותו הדבר. אתה מקליד את אותו דבר. אחר, בחוטים הם לא אותו הדבר. אחרי הכל, אם אנחנו שני קלט ints, שתי תווים, שני מצופים, שני זוגות, כל אחד את סוגי הנתונים שדברנו על עד כה להשוות אותם - זוכרים שעשינו מאוד ברור לפני כמה זמן כי אתה לא עושה את זה, כי סימן שוויון יחיד הוא כמובן אופרטור ההשמה. כך שיהיה באג. אנו משתמשים בסימן השוויון שווה, שאכן משווה דברים לשוויון אמיתי. אבל אני טוען שזה הוא מרכבה. אם אני הולך קדימה ולהפוך להשוות לאפס, ולאחר מכן נקודת לוכסן אין להשוות לאפס. ואני מקליד ב, בואו נגיד, הלו. ואז בואו להגיד שלום שוב. פשוטו כמשמעו, את אותו דבר, מחשב תביעות הקלדתי את הדברים שונים. עכשיו אולי אני רק הוקלדתי בטעות משהו. אני הקלד את השם שלי הפעם. אני אומר, הלו. שלום. זה שונה בכל פעם. ובכן, מדוע זה כך? מה באמת קורה מתחת למכסת המנוע? ובכן, מה באמת קורה מתחת מכסה המנוע הוא מחרוזת אז אני הקלדתי שבפעם הראשונה למשל שלום היא המילה, כמובן. אבל אם אנחנו מייצגים את זה מתחת מכסה המנוע, זוכר כי מחרוזת היא במערך. ואנחנו כבר אמרו כל כך הרבה בעבר. אז אם אני מצייר כמו שמערך הזה, אני הולך לייצג משהו די בדומה למה שעשינו לפני רגע. ויש באמת משהו מדי מיוחד כאן,. מה אנו קובעים שעל סופו של כל מחרוזת? כן, אפס הקו הנטוי הזה, שהוא רק דרך לייצג, פשוטו כמשמעו, 00000000. שמונה 0 ביטים ברציפות. אני לא יודע, בכנות, מה אחרי זה. זה פשוט יותר זיכרון RAM חבורה חלק פנימי של המחשב שלי. אבל זה מערך. דיברנו על מערכים בעבר. ואנחנו בדרך כלל מדברים על מערכים כמיקום אפס, אז אחת, ואז שתיים. אבל זה רק מטעמי נוחות. וזה יחסי לחלוטין. כאשר אתה בעצם מקבל מזיכרון מחשב, שזה כמובן כל 2 מיליארדים כמה בתים מוזרים, באופן פוטנציאלי. אז באמת מתחת למכסת המנוע, כל הזמן הזה, כן. זה עשוי להיות טוב מאוד אפס סוגר. אבל אם אתה חופר עמוק יותר מתחת את מכסה המנוע, זה ממש לטפל במספר 123. זוהי כתובת 124. זוהי כתובת 125. ואני לא אפשל הפעם. אלה הם כיום אחד בתים מלבד מה סיבה? מה גודלו של char? Char הוא רק בית אחד. Int הוא בדרך כלל ארבעה בתים. אז בגלל זה אני עשיתי את זה 123, 127, 131 וכן הלאה. עכשיו אני יכול לשמור את המתמטיקה פשוטה ופשוט לעשות 1 ועוד. וזה עכשיו מה באמת קורה על מתחת למכסת המנוע. לכן, כאשר אתה מצהיר משהו כזה, מחרוזת של, זה בעצם - מתברר - כוכב char. כוכב, כמובן, משמעות הדבר היא כתובת, מצביע aka. אז זה הכתובת של משהו. מהו אותו את הכתובת של? ובכן - אני יחיד שיכול לראות את הטוב נקודה חשובה שאני עושה, או חושב אני עושה. אז מחרוזת - הדבר העצוב הוא שיש לי מסך ממש שם איפה אני יכל לראות את זה. בסדר, אז מחרוזת של מה אני הצהיר בעבר. אבל מתברר, הודות למעט קסם בספרייה CS50, כל זה יש מחרוזת זמן, פשוטו כמשמעו, היה כוכב char. הכוכבים אומר שוב מצביע או כתובת. עובדה שזה איגוף המילה char אומר שזה כתובת של אופי. אז אם תקבל מחרוזת נקראת, ואני מקליד בH-E-L-L-O, מציע כעת את מה שיקבל מחרוזת, פשוטו כמשמעו, הייתה חוזר כל הפעם, למרות שיש לנו ולא פשטני בעולם? מה בעצם מקבל מחרוזת תחזור כערך ההחזרה שלה? 123 במקרה זה, למשל. אנחנו כבר אמרו בעבר כי תקבלו מחרוזת פשוט מחזירה מחרוזת, רצף של תווים. אבל זה קצת שקר לבן. הדרך לקבל מחרוזת באמת עובדת מתחת למכסת המנוע הוא שהוא מקבל מחרוזת מהמשתמש. זה שומט את התווים הוא או הוא בסוגי זיכרון. זה מעמיד אותך בסופו של הדבר אפס קו נטוי של אלה רצף של תווים. אבל אז מה מקבל מחרוזת פשוטו כמשמעו לחזור? זה ממש מחזיר את הכתובת של הבתים הראשונים בזכרון ה-RAM זה משמש לכוח זה. ומתברר, כי רק על ידי החזרת כתובת יחידה של התו הראשון במחרוזת, כלומר מספיק למציאת מכלול המחרוזת. במילים אחרות, לקבל את המחרוזת אין כדי לחזור ו123 124 ו 125. זה לא חייב לתת לי עוד רשימה של כל הבתים ש המחרוזת שלי משתמשת בו. בגלל אחד, הם כולם הגב אל הגב. ושתיים, המבוסס על הכתובת הראשונה, אני ניתן להבין איפה המחרוזת מסתיימת. איך? אופי null המיוחד, קו נטוי אפס בסוף. אז במילים אחרות, אם אתה עובר בסביבה - חלק פנימי של משתנים - הכתובת של char, ואתה מניח כי בסוף כל מחרוזת, כל רצף של תווים כפי שאנו בני האדם חושב על המיתרים, אם אתה מניח כי בסוף כל מחרוזת כזו יש אפס קו נטוי הפוך, אתה זהב. כי אתה תמיד יכול למצוא קצה חוט. עכשיו מה באמת קורה אז בתכנית זו? מדוע תכנית זו, להשוות-0.c, עגלה? מה הוא בעצם השוואה? כן? תלמיד: [לא ברור]. דוד Malan: בדיוק. זה השוואת בין המקומות של המיתרים. אז אם המשתמש הקליד בשלום פעם אחת, כפי שאני עשיתי, זיכרון עלול בסופו נראה כמו זה. אם המשתמש אז בסוגים שלום שוב, אבל על ידי קורא מקבל מחרוזת שוב, הוא ג לא חכם במיוחד, אלא אם אתה מלמד זה להיות חכם על ידי כתיבת קוד. ג - ומחשבים באופן כללי - אם תקליד שוב שלום במילה, אתה יודע מה אתה הולך לקבל. אתה פשוט הולך לקבל מערך שני של זיכרון שכן, קורה להיות אחסון H-E-L-L-O וכן הלאה. זה הולך להיראות אותו הדבר ל שלנו, בני אדם, אך הכתובת לא יכול להיות 123. זה יכול לקרות, כי רק כך יש מערכת הפעלה מסוימת זמינה שטח למשל במיקום - בואו נגיד משהו שרירותי, כזה הוא מיקום 200. ואת זה הוא מיקום 201. ואת זה הוא מיקום 202. אין לנו מושג איפה זה הולך להיות בזיכרון. אבל מה זה אומר זה מה שהוא הולך להיות מאוחסן בסופו של דבר זה? מספר 123. מה הולך להיות מאוחסן בT, בדוגמה שרירותית זו? מספר 200. וכל זה אומר שלאחר מכן הוא ללא ספק, 123 לא שווה 200. וכך זה אם מצב לא מוערך נכון. בגלל מחרוזת גט באמצעות אחרת נתחי זיכרון בכל פעם. עכשיו אנחנו יכולים לראות את זה שוב בדוגמה נוספת. תן לי ללכת קדימה ולפתוח את העותק-0.c. אני טוען שדוגמה זו הולכת מנסה - אבל לא מצליח - להעתיק שתי מחרוזות כדלקמן. אני הולך להגיד משהו למשתמש. אז אני הולך לקבל מחרוזת וקורא לזה ש. ועכשיו, אני עושה את הבדיקה הזאת כאן. הזכרנו אחורה בזמן הזה. אבל כאשר עלול לקבל אפס תשואת מחרוזת, תו מיוחד אחר, או מיוחד הסמל נניח. אם זה מתוך זיכרון. לדוגמה, אם המשתמש הוא באמת להיות קשה וסוגים זוועתיים מספר התווים ב מקלדת ולהיטים Enter. אם מספר תווים שפשוט לא יכול תתאים בזכרון RAM לכל מה משוגע סיבה, אולי גם לקבל מחרוזת טוב מאוד תחזיר null. או אם התכנית שלך עצמו הוא עושה הרבה של דברים אחרים ויש רק לא מספיק זיכרון עבור מחרוזת גט כדי להצליח, זה עלול בסופו עד חוזר ריקה. אבל בואו נהיה מדויק יותר על מה זה. מהו הסוג של נתונים של ממש? כוכב צ'אר. אז מתברר עכשיו אנחנו יכולים לקלף לגבות את שכבה ריקה. מתברר, null הוא - כן, ברור סמל מיוחד. אבל מה זה באמת? באמת, null הוא רק סמל שאנחנו בני אדם משתמשים כדי לייצג אפס גם כן. אז המחברים של C, והמחשבים באופן כללי יותר, החליט לפני שנים כי, אתם יודעים מה. למה שלא להבטיח שאף משתמש הנתונים הוא אי פעם, אף פעם, אף פעם מאוחסן באפס שלום? למעשה, אפילו בדוגמא השרירותית שלי בעבר, אני לא התחלתי את המספור בתים באפס. התחלתי בשעה אחת. כי ידעתי שאנשים בעולם החליט להזמין אפס בתים בזכרון RAM של מישהו כמו משהו מיוחד. להיות הסיבה לכך, בכל עת שתרצה סימן שמשהו השתבש בנוגע לכתובות, חזר לך null - הידוע גם אפס - וכי אתה יודע שאין שום נתונים חוקיים בכתובת אפס, באופן ברור זה אומר שגיאה. וזו הסיבה שאנו, על ידי אמנה, לבדוק לבטלה ולחזור משהו כמו אחד במקרים אלה. אז אם אנחנו לגלול למטה עכשיו, זה רק אז איזה בדיקת שגיאות, רק במקרה משהו השתבש עם [? ערבות?] לגמרי וסיימתי את התכנית על ידי חזרה מוקדם. קו זה יכול עכשיו להיות משוכתב כמו זה, שפירושו מה? בצד השמאל, תן לי עוד מצביע לתו, וקורא לזה לא. מה אני אחסון פנימי של T, המבוסס בשורה אחת של הקוד הזה? אני אחסון מיקום. באופן ספציפי את המיקום שהיה בים. אז אם המשתמש הקליד בשלום, ו כי שלום הראשון שקורה בסופו של כאן, ולאחר מכן את המספר 123 היא אחזור מלקבל מחרוזת ולהיות מאוחסן - כמו שאמרנו קודם - בים. כשאני מצהיר עכשיו מצביע אחר לא להשחיר וקוראים לזה, מהו מספר פשוטו כמשמעו, הולך בסופו של דבר לא על פי הסיפור? אז 123. אז מבחינה טכנית עכשיו גם ים ו לא מצביעים על מדויק אותם גושים של זיכרון. אז שים לב למה שאני הולך לעשות עכשיו כדי להוכיח כי תכנית זו היא מרכבה. ראשית אני הולך לתבוע, עם F הדפסה, ניצול העותק של המחרוזת. ואז אני הולך לעשות קצת בדיקת שגיאות. אני הולך כדי לוודא. בואו נוודא שלא נמצא במחרוזת לפחות גדול מאפס באורך, כך שיש איזו דמות שיש כדי לנצל באמת. ואז אתה יכול להיזכר בזה מדוגמאות קודמות. 2 עליון - שהוא ב קובץ ctype.h. T סוגר אפס נותן לי אפס דמותו של לא המחרוזת. ו2 העליונות של אותו ערך, של כמובן, ממיר אותו לאותיות גדולות. אז באופן אינטואיטיבי, זה מודגש קו של קוד הוא ניצול הראשון מכתב לא. אבל זה לא ניצול, באופן אינטואיטיבי, האות הראשונה בים. אבל אם אתה חושב קדימה, מה אני עומד לראות כאשר אני מפעיל את התכנית ולהדפיס את שניהם המקורי, ים, והעותק מה שנקרא, לא? הם באמת הולכים להיות אותו הדבר. ולמה הם הולכים להיות אותו הדבר? הם גם מצביעים על בדיוק אותו הדבר. אז בואו לעשות את זה. הפוך אפס עותק. זה הידור אישור. תן לי להפעיל את העותק אפס. תן לי להקליד משהו כמו שלום ב כל אותיות קטנות ולאחר מכן על Enter. והיא טוענת שהן של מקורית והעותק הם אכן זהה. אז מה באמת קרה כאן? תן לי לצייר מחדש את התמונה הזאת רק לספר את הסיפור ב דרך שונה במקצת. מה באמת קורה מתחת מכסה המנוע, כאשר אני מצהיר משהו כמו התחלה של char, או מחרוזת של, אני מקבל מצביע - אשר קורה להיות ארבעה בתים במכשיר CS50 ובהרבה מחשבים. ואני הולך לקרוא לים זה. ואת זה יש כרגע ערך כלשהו לא ידוע. כאשר אתה מצהיר על משתנה, אלא אם כן אתה את עצמך את ערך שם, ה יודע מה יש שם. זה יכול להיות רצף אקראי כמה פיסות מביצוע הקודם. לכן, כאשר אני, בשורת הקוד שלי מקבל מחרוזת ולאחר מכן לאחסן את התשואה ערך בים מקבל מחרוזת איכשהו - וסופו של דבר אנו יהיו לקלף איך להגיע עבודות מחרוזת, איכשהו מקצה מערך שכנראה נראה קצת כמו זה. H-E-L-L-O, קו נטוי אפס. בואו נניח שזה הוא כתובת רק 123 עקביות ראשונה. אז לקבל את מחרוזת תשואות, ב קו מודגש שם, זה מחזיר את מספר שאמרנו, 123. אז מה באמת עובר בתוך ים כאן? ובכן, מה באמת קורה בתוך שעות היא 123. אבל בכנות, אני קצת מקבל מבולבל מכל הכתובות האלה, כל מספרים השרירותיים אלה. 123, 124, 127. אז בואו באמת לפשט העולם קצת. כאשר אנו מדברים על מצביעים, בכנות, ל שלנו, בני אדם, מי לעזאזל אכפת איפה דברים הם בזיכרון? זה שרירותי לחלוטין. זה הולך להיות תלוי באופן הרבה רם המשתמש. זה הולך להיות תלוי בכאשר ביום אתה מפעיל את התכנית, אולי, ו מה קלט המשתמש נותן לך. אנחנו להתעכב על פרטים לא חשובים. אז בואו משם מופשט ואומרים את זה, כשאתה מפעיל את שורת קוד כזה, char כוכב ים יקבל את התמורה ערך של מחרוזת גט. למה שלא במקום רק לצייר את מה שאנחנו להמשיך לקרוא מצביע כאילו זה מצביע על משהו? אז אני טוען שעכשיו זה עד יש מצביע - מתחת למכסת המנוע זה כתובת. אבל זה רק מצביע על הבית הראשון ב מחרוזת שהוחזרה. אם אני עכשיו אחזור לקוד כאן, מה קורה בתחום הזה? ובכן, בשורה מודגשת זה עכשיו, אני מכריז כנראה אחר משתנה בשם t. אבל זה גם מצביע, אז אני הולך לצייר אותו כ, בתאוריה, המדויק אותה תיבת גודל. ואני הולך לקרוא לזה לא. ועכשיו אם נחזור לקוד שוב, כשאני של החנות בתוך t, מה אני טכני לשים את החלק פנימי של t? גם מבחינה טכנית, זה היה מספר 123. אז באמת שאני צריך לכתוב מספר 123 שם. אבל בואו ניקח את זה ברמה גבוהה יותר. לא, אם זה רק מצביע, באופן אינטואיטיבי, הוא בדיוק את זה. זה כל מה שזה להיות מאוחסן שם. אז עכשיו בשורות המעניינות האחרונות של קוד, כשאני באמת ללכת על ניצול האופי אפס בT, מה קורה? ובכן, לא אפס סוגר מצביע כעת למה אופי, אני מניח? זה מצביע על שעות. כי לא סוגר אפס - זוכר, זה תחביר ישן. לא סוגר אפס רק אומר שאם לא הוא מחרוזת, לא סוגר אפס פירושו מקבל אפס דמות בכוח זה. אז מה זה באמת אומר זה ללכת למערך זה - וכן, זה יכול להיות 123, זה יכול להיות 124. אבל זה הכול יחסי, זכור. בכל פעם שמדבר על מערך, שיש לנו היתרון של מדבר על מדדים יחסיים. ואז עכשיו אנחנו יכולים רק להניח אפס כי לא סוגר הוא שעות. אז אם אני קורא 2 עליון עליו, מה זה באמת עושה הוא ניצול שעות אותיות קטנות לאותיות הגדולות ח אבל כמובן, מה היא שעות? זה מצביע לאותה המחרוזת המעצבן הזה. אז זה כל מה שהיה קורה בקוד זה עד כה. אז מה אז המשמעות? איך אפשר לתקן את שתי הבעיות האלה? איך אפשר להשוות מחרוזות בפועל? גם באופן אינטואיטיבי, איך היית אתה הולך על השוואת שתי מחרוזות לשוויון אמיתי? מה זה אומר אם שני המיתרים שווים? ברור שלא, כי הכתובות שלהם הן שווה בזיכרון, כי זה נמוך יישום רמת פירוט. כל הדמויות הן אותו הדבר. אז הרשה לי להציע, והרשה לי להציג בגרסה אחת של compare.c כאן, כדי להשוות-1.c. הרשו לי להציע שאנחנו עדיין מקבלים מצביע הנקרא ים, וחנות בה להחזיר ערך של מחרוזת גט. בואו נעשה את אותו דבר עם לא. אז אף אחד מהקוד הוא שונה. אני הולך להוסיף קצת עוד בדיקת שגיאות עכשיו. אז עכשיו שאנחנו סוג של פילינג גב זה שכבות של מה בCS50 מחרוזת היא למעשה, אנחנו צריכים להיות יותר אנאליים לגבי לוודא שאנחנו לא נתעלל ערכים לא חוקיים כמו null. אז אני פשוט הולך לבדוק. אם זה לא עושה null שווה ולא לא עושה null שווה, זה אומר שאנחנו בסדר. קבל מחרוזת לא לפשל מקבלת אחת מהמחרוזות האלה. ואתה אולי יכול לנחש עכשיו, מה אין STR CMP לעשות מן הסתם? מחרוזת להשוות. אז אם יש לך תכנית ב-Java לפני, זה כמו בשיטת שווים ב כיתת מחרוזת. אבל לאלה מכם שיש לי לא לתכנת לפני, זה רק פונקצית ג. זה קורה לבוא קובץ שנקרא string.h. זה מקום שבו הוא הכריז. ולהשוות את המחרוזת - אני בעצם שוכח השימוש בו, אבל יעזוב את זה. נזכיר כי אנחנו יכולים לעשות גבר, מערבבים להשוות. וזה הולך להעלות את מדריך למתכנתי לינוקס. וזה, למען האמת, לא ברור מספיק. אבל אני יכול לראות כאן ש, כן. אני חייב לכלול string.h. וזה אומר כאן תחת תיאור " פונקציה להשוות מחרוזת משווה שתי המחרוזות S1 ו S2. "וS1 וS2 הם ככל הנראה שתיים טיעונים עברו פנימה אני לא ממש זוכר מה const הוא, אבל עכשיו שם לב - ואולי ראה את זה כבר כש שיש לך להשתמש בדפים אם אתה הגבר יש את כל זה - שהכוכבים הוא רק שם נרדף char עם מחרוזת. אז הוא משווה את שתי המחרוזות, S1 ו S2, והיא מחזירה מספר שלם פחות או שווה או גדול מאפס אם S1 נמצא, בהתאמה, כדי להיות פחות מ, או להתאים, או להיות גדול מ S2. זה פשוט דרך מורכבת מאוד לומר שהמחרוזת להשוות תשואות אפס אם שתי מחרוזות הן באופן אינטואיטיבי זהים, תווים תו לתו. זה מחזיר מספר שלילי אם ים, לפי סדר אלפביתי, אמור לבוא לפני לא. או מחזיר מספר חיובי אם ים אמור לבוא אחרי לא לפי סדר אלפביתי. אז עם פונקציה פשוטה זו, יכולה אתה, למשל, למיין חבורה שלמה של מילים? אז בגרסה חדשה זו, אני הולך ללכת קדימה ולעשות compare1. נקודת לוכסן להשוות אחד. אני אקליד בשלום בכל המקרה נמוך יותר. אני הולך להקליד בשלום בכל אותיות קטנות שוב. ותודה לאל עכשיו הוא מבין אני הקלדתי את אותו דבר. בינתיים, אם אני מקליד בשלום בתחתון מקרה ושלום במקרה העליון ו להשוות אותם, אני הקלדתי דברים שונים. כי לא רק את הכתובות שונה, אבל אנחנו משווים דמויות שונות שוב ושוב. ובכן בואו נלך ולתקן אחד בעיה אחרת עכשיו. בואו לפתוח את הגרסה אחת שלי עותק, שעכשיו מטפל סוגיה זו כדלקמן. וזה אחד הולך להיראות קצת יותר מורכב. אבל אם אתה חושב על מה שאנחנו בעיה צריך לפתור, אני מקווה שזה יהיה לנקות ברגע עכשיו. אז השורה ראשונה זה, char התחלה לא, ב המונחים של הדיוט מישהו יכול להציע מה הקו הזה כאן אומר? תו לא כוכב, מה זה עושה? טוב. ליצור מצביע לחלק מקום בזיכרון. והרשו לי לחדד את זה קצת. מצהיר על משתנה שיאחסן כתובת של איזה דמות בזיכרון, רק כדי להיות קצת יותר ראוי. אוקיי, אז עכשיו בצד ימין, יש לי מעולם לא ראה את אחת מהפונקציות הללו בעבר, malloc. אבל מה שאולי אומר? הקצאת הזיכרון. הקצאת זיכרון. אז מתברר, עד עכשיו, אנחנו לא באמת הייתה לי דרך רב עוצמה של שואל את מערכת ההפעלה, תן לי קצת את זיכרון. במקום זאת, עכשיו יש לנו פונקציה שנקראת malloc שעושה בדיוק את זה. למרות שזה קצת הסחת דעת עכשיו, שים לב כי ב בין שני הסוגריים הוא פשוט הולך להיות מספר. איפה אני כבר הקלדתי בשאלה סימנים יכולים להיות מספר. ומספר זה אומר, תן לי 10 בתים. תן לי 20 בתים. תן לי 100 בתים. וmalloc יעשה כמיטב יכולתה תשאל את מערכת ההפעלה - לינוקס, במקרה זה - היי, הם 100 בתיהם של זיכרון RAM הפנוי? אם כן, תחזור הבתים האלה לי על ידי חוזר שהכתובת של אלה בתים, אולי? הראשון אחד. אז גם כאן - ואת זה הוא דומיננטי ב-C, בכל פעם שאתה התמודדות עם כתובות? אתה כמעט תמיד מתעסק עם הכתובת ראשונה מסוגו, לא משנה כמה גדול נתח של זיכרון שאתה להיות החזיר, אם אפשר לומר כך. אז בואו לצלול כאן. אני מנסה להקצות כמה בתים רבים, בדיוק? כן. מחרוזת באורך של שעות - בואו לעשות דוגמה קונקרטית. אם ים הוא שלום, H-E-L-L-O, מה מחרוזת באורך של שעות, ברור? אז זה חמש. אבל אני עושה את 1 בתוספת על זה, למה? למה אני רוצה שישה בתים במקום חמש? אופי null. אני לא רוצה לעזוב את זה אופי null מיוחד. כי אם אני עושה עותק של שלום ו פשוט לעשות את H-E-L-L-O, אבל אני לא שמתי את שאופי מיוחד, המחשב ייתכן שאין לי, במקרה, קו נטוי לאפס שם בשבילי. ולכן אם אני מנסה להבין אורכו של ההעתק, אני עשוי לחשוב כי זה עוד 20 תווים, או מיליון תווים אם אני פשוט אף פעם לא יקרה לרמה של אפס קו נטוי. אז אנחנו צריכים שישה בתים כדי לאחסן H-E-L-L-O, קו נטוי אפס. ואז זה פשוט להיות סופר אנאלי. נניח שאני לא זוכר מה גודלו של char הוא. אנחנו כל זמן אומרים שזה אחד בתים. וזה בדרך כלל. בתאוריה, זה יכול להיות משהו שונה, במקינטוש או אחרים מחשב שונה. אז מסתבר שיש זה למפעיל קרא sizeof שאם אתה עובר אותו שמו של סוג נתוני - כמו char או int, או לצוף - הוא יגיד לך, באופן דינמי, כמה הבתים char תופס על זה מחשב מסוים. אז זה רק בצורה יעילה כמו לומר 1 פעמים או פעמים שום דבר בכלל. אבל אני עושה את זה רק כדי להיות סופר אנאלי, כי רק במקרה char שונה במחשב שלך לעומת שלי, בדרך זו המתמטיקה הוא תמיד הולכת לבדוק. לבסוף, כאן למטה אני בודק לריק, וזה תמיד טוב להתאמן - שוב, כל זמן יש לנו עסק עם מצביעים. אם malloc לא היה מסוגל לתת לי לי שש פרידות - וזה לא סביר, אבל רק במקרה - להחזיר אחת באופן מיידי. ועכשיו, קדימה, ולהעתיק המחרוזת כדלקמן. ואת זה הוא תחביר מוכר, אם כי בתפקיד אחר. אני הולך קדימה, לקבל את המחרוזת אורכו של ים ולאחסן אותו בn. אז אני הולך כדי לעבור מאני שווה אפס עד וכולל n, גדול או שווה ל. כך שעל כל איטרציה, שמתי תו ה-i של S ב- i דמותו של t. אז מה באמת קורה מתחת מכסה המנוע כאן? ובכן, אם זה, למשל, הוא ים - ואני הקלדתי את מילת H-E-L-L-O ויש אפס קו נטוי. ושוב, זה של ההצבעה כאן. והנה עכשיו הוא לא. ואת זה הוא מצביע כעת ל עותק של זיכרון, נכון? Malloc נתן לי כל נתח של זיכרון. אני לא יודע בתחילה מה באף אחד מהמקומות האלה. אז אני הולך לחשוב על אלה כ חבורה שלמה של סימני שאלה. אבל ברגע שאני מתחיל מאפס לולאה על דרך באורך של S, T סוגר אפס ולא 1 סוגר - ואני אשים את זה עכשיו על תקורה - לא סוגר אפס ואפס של סוגר מתכוונים שאני הולך להיות העתקה שעות iteratively כאן, E-L-L-O. בנוסף, בגלל שעשיתי בתוספת 1, קו נטוי אפס. אז עכשיו במקרה של להשוות-1.c, בסופו של הדבר, אם אני מדפיס את היוון לא, אנחנו צריכים רואה שהים הוא ללא שינוי. תן לי ללכת קדימה ולעשות את זה עכשיו. אז להפוך את COPY1. נקודת הלוכסן COPY1. אני הולך להקליד בשלום, על Enter. ועכשיו שם לב, רק העותק כבר באותיות גדולות. כי אני באמת צריך שתיים נתחי הזיכרון. למרבה הצער, אתה יכול לעשות כמה יפה דברים רעים ודי מסוכנים כאן. תן לי למשוך את דוגמה כאן עכשיו, זה נותן לנו דוגמה לכמה קווים שונים. אז רק באופן אינטואיטיבי כאן, השורה הראשונה של קוד, int x הכוכב, מכריז משתנה בשם x. ומה סוג הנתונים של משתנה זה? מה סוג הנתונים של משתנה זה? זה לא היה הסחרור המסוכן. סוג הנתונים הוא כוכב int. אז מה זה אומר? X יהיה לאחסן את הכתובת של int. פשוט עד כדי כך. Y הולך לאחסון כתובת של int. מהי השורה השלישית של קוד עושה שם? זה הקצאה כמה בתים, ככל הנראה? ארבע. בשל גודלו של int הוא בדרך כלל ארבעה, malloc של ארבעה נותן לי לי את כתובתו של נתח של זיכרון, הראשון מבתיהם הוא מאוחסן כעת בx. עכשיו אנחנו עוברים קטן במהירות. כוכב X מה זה אומר? זה אומר ללכת לכתובת ש ולשים את מה שיש מספר? לשים את המספר 42 שם. כוכב Y אומר ללכת למה בy ולשים את המספר 13 שם. אבל חכה רגע. מהו בY ברגע? מה הוא כתובת Y אחסון? אנחנו לא יודעים, נכון? אנחנו מעולם לא להשתמש פעם אחת את המשימה מפעיל מעורב y. אז y כהכריז על הקו השני של קוד הוא רק חלק ערך אשפה, גדול סימן שאלה אם אפשר לומר כך. הוא היה יכול להצביע באופן אקראי לכל דבר בזיכרון, אשר הוא בדרך כלל רע. אז ברגע שפגענו בקו שיש, כוכב Y שווה 13, משהו רע, משהו רע מאוד עומד לקרות לינקי. אז בואו נראה מה קורה בסופו של קורה לינקי כאן ברגע זה או כך לפחות נראה. [השמעת וידאו] -היי, בינקי. להתעורר. זה זמן בשביל כיף מצביע. , מה זה? למד על מצביעים? אה, יופי. -ובכן, כדי להתחיל בעבודה, אני מניח שאנחנו הולך צריך כמה עצות. -אישור. קוד זה מקצה שני מצביעים אשר יכול להצביע על מספרים שלמים. -OK, טוב, אני רואה את שני מצביעים. אבל נראה שהם לא להיות הצבעה לכל דבר. -נכון. בתחילה, מצביעים לא להצביע על כל דבר. את הדברים שהם יצביעו לנקראים pointees, ומקים אותם הוא צעד נפרד. -אה, נכון, נכון. ידעתי את זה. את pointees הם נפרדים. אז איך אתה להקצות pointee? -אישור. ובכן, את הקוד הזה מקצה מספרים שלמים חדשים pointee, וחלק זה מגדיר X כדי להצביע על זה. -היי, זה נראה טוב יותר. אז להפוך אותו לעשות משהו. -אישור. אני dereference x המצביע לאחסון המספר 42 לpointee שלה. על הטריק הזה, ואני צריך את הקסם שלי שרביט של ביטול הפניה. -שרביט הקסם של ביטול הפניה למבנה? אה, זה נהדר. -זה מה שנראה כמו קוד. אני רק להגדיר את המספר, ו-- -היי, תראה. שם זה הולך. אז עושה dereference על X כדלקמן החץ לגשת pointee שלה. במקרה זה, כדי לאחסן 42 שם. היי, נסה להשתמש בו כדי לאחסן את המספר 13 דרך המצביע האחר, y. -אישור. אני פשוט אלך לכאן ולy לקבל את המספר 13 להגדיר. ואז לקחת את השרביט של ביטול הפניה למבנה ורק - וואו! -הו, היי. זה לא עבד. תגידו, בינקי, אני לא חושב ביטול הפניה למבנה Y הוא רעיון טוב, בגלל הגדרת pointee הוא צעד נפרד. ואני לא חושב שאי פעם עשינו את זה. -הממ. נקודה טובה. 'כן, אנחנו מוקצים y המצביע. אבל אנחנו אף פעם לא להגדיר אותו להצביע על pointee. -הממ. דתי מאוד. היי-, שאתה מחפש טוב שיש, בינקי. האם אתה יכול לתקן אותו כך שנקודות y לאותו pointee כX? -בטח. אני אשתמש בשרביט הקסמים שלי מצביע משימה. -האם זה הולך להיות בעיה כמו בעבר? -No. זה לא לגעת בpointees. זה פשוט משנה את מצביע אחד שיצביע לאותו דבר כמו אחר. -אה, אני מבין. עכשיו נקודות y לאותו המקום כמו x. אז תחכה. עכשיו Y הוא קבוע. יש לו pointee. אז אתה יכול לנסות את השרביט של ביטול הפניה למבנה שוב לשלוח 13 נגמר. -אישור. הנה זה בא. -היי, תראה את זה. ביטול הפניה למבנה החברה עובד על y. ומכיוון שאת המצביעים משתפים שpointee אחד, הם שניהם רואים 13. -כן. שיתוף. לא משנה מה. אז אנחנו הולכים להחליף מקומות עם החברה? -הו, תראה. נגמר לנו זמן. -אבל - רק תזכרו-שלוש כללי מצביע. מספר אחד, את המבנה הבסיסי הוא שיש לך מצביע. והוא מצביע על לpointee. אבל המצביע וpointee הם נפרדים. והטעות הנפוצה היא להגדיר את מצביע, אלא תשכח ניתנה pointee. מספר שתיים, ביטול הפנית המצביע מתחילה במצביע ועוקב חץ מעל לגשת pointee שלה. כפי שכולנו יודעים, זה עובד רק אם יש הוא pointee, שחוזר ל כלל מספר אחת. מספר שלוש, הקצאת מצביע לוקח מצביע אחד ושינויים בו כדי להצביע על אותו pointee כמצביע אחר. אז אחרי המשימה, שני המצביעים יהיו להצביע לאותו pointee. לפעמים זה נקרא שיתוף. וזה כל מה שיש בו, באמת. ביי ביי עכשיו. [השמעת וידאו הסוף] דוד Malan: אז עוד על מצביעים, נוסף על השבוע הבא בינקי. נתראה ביום שני.