[Powered by Google Translate] [סעיף 4] [פחות נוח]
[נייט Hardison] [אוניברסיטת הרווארד]
[זה CS50.] [CS50.TV]
>> בסדר, ברוך שובי לסעיף.
בסעיף של השבוע הזה אנחנו הולכים לעשות כמה דברים.
אנחנו הולכים על ערכת בעיה לסכם 1 2,
המהווה את סדרת בעית קיסר וVigenère.
ואז אנחנו הולכים לצלול לביקורת 0 חידון
ולבלות קצת הזמן recapping מה שדברנו עליו
בכל אחת מההרצאות עד כה, ואנחנו גם עושים כמה בעיות
מהבחנים של השנה הקודמת.
בדרך זו יש לכם דרך טובה להתכונן לזה.
>> כדי להתחיל, אני כבר מאותחל כמה פתרונות טובים
לקבוצת הבעיה הקודמת, בעית ההגדרה 2, בשטח זה.
אם אתם כל פגעתם על קישור זה,
ואם תלחץ על השם שלי ולחץ על הגרסה הראשונה שלי
תראה caesar.c, וזה בדיוק מה שאני מחפש ב.
בואו נדבר על זה ממש במהירות.
זה רק פתרון מדגם.
זה לא בהכרח הפתרון המושלם.
ישנן דרכים רבות ושונות כדי לכתוב את זה,
אבל יש כמה דברים שאני רוצה להדגיש
כי ראיתי שאני היה דירוג, טעויות נפוצות שאני חושב
הפתרון הזה עושה עבודה טובה מאוד של טיפול.
>> הראשון הוא שיש סוג מסוים של הערת הכותרת בחלקו העליון.
ביום 1 בקווים עד 7 אתה רואה את הפרטים,
מה בדיוק הוא עושה בתכנית זו.
מקובל טוב כשאתה כותב קוד C
ללא קשר אם התכנית שלך כלולה בתוך קובץ או בודד
בין אם היא מפוצלת על פני מספר קבצים הוא שיש סוג מסוים של
orienting הערה בחלק העליון.
זה גם לאנשים שיוצאים ולכתוב קוד בעולם האמיתי.
זה המקום בו נשים את המידע על זכויות יוצרים.
להלן # כולל.
בקו 16 יש את זה # להגדיר, שאנחנו נחזור ל, רק קצת.
ואז ברגע שהפונקציה מתחילה, מתחילה ברגע עיקרי,
כי תכנית זו כבר כלולה בכל פונקציה אחת
הדבר הראשון שקרה, וזה מאוד האידיומטיים וטיפוסי של תכנית C
שלוקח בשורת פקודת טיעונים-הוא שהוא בודק באופן מיידי
>> לספירת הוויכוח, argc.
כאן אנו רואים כי תכנית זו היא מצפה 2 טענות בדיוק.
זכור שיש הטענה הראשונה זה אחד מיוחד
זה תמיד השם של התכנית המתנהלת,
את השם של קובץ ההפעלה.
ואז מה שזה עושה זה מונע מהמשתמש להפעיל את התכנית
עם יותר או פחות ויכוחים.
הסיבה שאנחנו רוצים לבדוק את זה מייד היא משום
אנחנו לא ממש יכולים לגשת למערך argv זה ממש כאן אמין
עד שבדקנו לראות כמה הוא גדול.
>> אחת השגיאות הנפוצות שראיתי היה אנשים היינו הולכים מייד
ולתפוס argv [1].
הם היו תופסים את טיעון המפתח מהמערך ואין לי לבדוק את זה,
ואז הם היינו עושים את הבדיקה לargc, כמו גם את המבחן הבא,
אם הטיעון הראשון אכן היה שלם באותו הזמן,
וזה לא עובד כי במקרה שאין ויכוחים סופקו
אתה תהיה תופס טענה שהוא לא שם או מנסה לתפוס אחד שהוא לא שם.
>> הדבר הגדול האחר, כי אתה צריך לשים לב הוא ש
אתה תמיד רוצה להדפיס איזה הודעת שגיאה מועילה
למשתמש לכוון אותם.
אני בטוח שיש לך את כל התוכניות שהופעלה בו פתאום שהוא מתרסק,
ואתה מקבל את השיח הזה המגוחך הקטן שקופץ ואומר
משהו נורא מסתורי ואולי נותן לך קוד שגיאה או משהו כזה
שלא הגיוני.
זה המקום בו אתה באמת רוצה לספק משהו מועיל
וממוקד למשתמש, כך שכאשר הם מפעילים את זה הם הולכים "אה," כף פנים.
"אני יודע בדיוק מה לעשות. אני יודע איך לתקן את זה."
>> אם לא יפרסם הודעה, אז אתה בסופו של ממש
משאיר את המשתמש ללכת לבדוק את קוד המקור שלך
כדי להבין מה השתבש.
יש גם כמה פעמים שאתה משתמש בקודי שגיאה שונים.
כאן אנחנו פשוט השתמשנו באחד אומרים שיש שגיאה,
הייתה טעות, הייתה טעות.
תוכניות גדולות יותר, לעתים קרובות תוכניות שנקראות על ידי תוכניות אחרות,
יחזור איזה קודי שגיאה מיוחדות בתרחישים שונים
תכנותי כדי לתקשר את מה שהיית עושה אחרת
פשוט להשתמש בהודעה אנגלית נחמדה ל.
מגניב.
כפי שאנו פועלים למטה, אתה יכול לראות שאנחנו מוציאים את המפתח.
אנחנו בודקים אם המפתח מתאים.
אנחנו מקבלים הודעה מהמשתמש.
הסיבה שאנחנו עושים את זה בזה לעשות בעוד לולאה וזה משהו שאנחנו נכסה
בקצת, אבל מתברר שאם תקליד השליטה D
כאשר אתה מקבל GetString שפקודה במסוף
מה שבעצם עושה זה שולח תו מיוחד
לתכנית.
זה נקרא ELF או סוף אופי קובץ.
ובמקרה כזה, מחרוזת המסר שלנו תהיה ריקה,
אז זה לא היה משהו שבדקנו בבעיה להגדיר את עצמו.
>> אבל כמו שאנחנו הולכים, עכשיו שאנחנו כבר התחלנו לדבר על מצביעים
והקצאת זיכרון דינמית על הערימה,
בדיקת null בכל פעם שיש לך פונקציה שאולי
תחזיר null כערך הוא משהו שאתה רוצה להשיג בנוהג לעשות.
זה כאן בעיקר לאיור.
אבל כשאתה רואה את GetString בעתיד,
כל כך מבעית הגדרה 4 ב, אתה רוצה לשמור את זה בחשבון.
שוב, זה לא בעיה בשביל בעית Set 3 או כיוון שעדיין לא כיסו אותו עדיין.
לבסוף, אנחנו מגיעים לחלק הזה שבו אנחנו מגיעים ללולאת ההצפנה הראשית,
ויש כמה דברים שעובד כאן.
ראשית, שנעמיק את המחרוזת כל הודעה עצם.
כאן אנו שמרנו strlen שיחה במצב,
שמספר שציין הוא לא דרך מצוינת ללכת.
מתברר שבמקרה זה זה גם לא גדול,
גם בגלל שאנחנו משנים את התוכן של ההודעה עצם
בתוך ללולאה, כך שאם יש לנו הודעה באורך 10 תווים,
הפעם הראשונה שאנחנו מתחילים ללולאת strlen יחזיר מה?
10.
>> אבל אם לאחר מכן לשנות את ההודעה, אומרים לנו לשנות אופייה 5,
ואנחנו זורקים ב\ 0 דמות בעמדת 5,
באיטרציה באה strlen (הודעה) לא יחזיר את מה שעשה
בפעם הראשונה שאנו איטרטיבי
אבל זה יחזור במקום 5 כי זרק שבnull terminator,
והאורך של המחרוזת מוגדר
לפי עמדתו של ש\ 0.
במקרה זה, זו היא דרך מצוינת ללכת כי אנחנו משנים אותו במקום.
אבל שמתם לב שזה בעצם פשוט מפתיע להצפין
אם אתה יכול להשיג את המתמטיקה נכונה.
כל מה שנדרש הוא לבדוק האם המכתב שאתה מסתכל
הוא רישיות או קטן.
>> הסיבה שיש לנו רק כדי לבדוק את זה ואין לנו לבדוק
מקרה אלפא הוא משום
אם דמות היא אותיות גדולה או אם זה אותיות קטן
אז זה בהחלט תו אלפביתי,
משום שאין לנו ספרות גדולה וקטנה.
הדבר ולעשות את זה הוא קצת מסובך, אחר אנחנו
אנחנו שונים קיסר צופן הנוסחא הסטנדרטית
שנתנו במפרט סט הבעיה.
מה ששונה כאן הוא שאנחנו נגרענו
במקרה הון אותיות הגדול, ולאחר מכן הוספנו הון
לגבות בסוף.
>> אני יודע כמה שעשיתי את זה בקוד שלך.
האם מישהו מכם לעשות את זה בהגשות שלך?
אתה עשית את זה. אתה יכול להסביר מה זה עושה, Sahb?
על ידי הפחתה אותו החוצה, כי אתה עשית mod מייד אחריו,
אתה צריך לקחת אותו החוצה, ולכן אופן שבו אתה מקבל [שיעול] עמדה.
ולאחר מכן על ידי הוספתו שוב מאוחר יותר העביר מעליך אחד שאתה רוצה.
כן, בדיוק.
מה Sahb אמר היה שכאשר אנחנו רוצים להוסיף
המסר שלנו והמפתח שלנו יחד
ואז mod mod ש, כי על ידי NUM_LETTERS,
אם אנחנו לא בקנה מידה שלנו להודעת 0-25 הטווח המתאים ראשון,
אז אולי בסופו של דבר מקבל מספר ממש מוזר
משום שהערכים שאנחנו מחפשים בכאשר אנו מסתכלים בהודעה [i],
כאשר אנו מתבוננים בדמות ה-i של הודעת הטקסט הרגיל שלנו,
הוא ערך אי שם ב65-122 טווח זה
המבוסס על ערכי ASCII לאותיות גדולות באמצעות z אותיות הקטנים.
ולכן כאשר אנו mod על ידי 26 או על ידי NUM_LETTERS,
מאז שהיה שלנו # להגדיר בפינה הימנית העליונה עד כאן,
זה הולך לתת לנו ערך זה בטווח 0-25,
ואנחנו צריכים דרך ואז לקנה המידה שגבתה את
ולקבל את זה בטווח ASCII המתאים.
הדרך הקלה ביותר לעשות זאת היא פשוט לקצץ הכל
לטווח 0-25 כדי להתחיל עם,
ולאחר מכן להעביר את הכל בחזרה עד בסוף.
>> טעות נפוצה נוספת שראיתי אנשים שנתקלו בהיא
אם אתה לא באמת לעשות שינוי קנה מידה זה מייד
ואתה מוסיף הודעה ומפתח ביחד ואתה מוסיף להם, למשל,
למשתנת char, בעיה עם זה
מאז הודעה היא [i] הוא מספר גדול יחסית להתחיל עם
זוכר את זה לפחות 65 אם זה אותיות גדולות תווים
אם יש לך מפתח גדול, יניח, משהו כמו 100,
ואתה מוסיף אלה 2 ביחד לתוך char חתם אתה הולך לקבל בגלישה.
אתה הולך לקבל את הערך שהוא גדול מ127,
המהווה את הערך הגדול ביותר שמשתנה char יכול להחזיק.
שוב, זה למה שהיית רוצה לעשות דברים מסוג הזה מלכתחילה.
יש אנשים שעקפו את זה במקרה על ידי עושה אם אחר ובודקים
כדי לראות אם זה היית הצפה לפני עושה את זה,
אבל בדרך זו מקבלת סביב זה.
ואז בפתרון זה שהדפסנו את כל המחרוזת בסוף מאוד.
אנשים אחרים הדפיסו אופי בכל פעם. שניהם מדהימים.
בשלב זה, לעשות יש לכם שאלות, הערות כלשהן על זה?
דברים שאתה אוהב, דברים שאתה לא אוהב?
>> היה לי שאלה.
אולי פספסתי את זה בהסבר שלך, אבל איך עושה תכנית זו
דלג על המרחבים לחיבור המפתח לאורכו של הטקסט?
זה רק קיסר צופן. >> אה, סליחה, כן.
כן, אנחנו נראה את זה.
בצופן הקיסר ממש הספקנו כי בגלל
אנחנו התהפכנו תווים בלבד.
אנחנו מסובבים אותם רק אם הם היו רישיות או קטנים.
אתם מרגישים די טובים בזה?
תרגיש חופשי להעתיק את זה הביתה, קח אותה,
להשוות את זה למה שאתם כתבתם.
בהחלט אל תהסס לשלוח שאלות על זה יותר מדי.
ושוב, מבין שהמטרה כאן עם הבעיה שלך קובעת
לא לקבל אתכם לכתוב קוד מושלם לסטי הבעיה שלך.
זה חוויה לימודית. כן.
>> חזור לעשות בזמן לולאה, אם זה שווה אפס,
כל כך ריק פשוט לא אומר כלום, הם פשוט פגעו להיכנס?
Null הוא ערך מצביע מיוחד,
ואנחנו משתמשים באפס כאשר אנו רוצים לומר
יש לנו משתנה מצביע שמצביע על כלום.
וכך בדרך כלל זה אומר שזה משתנה, משתנה הודעה זו
הוא ריק, וכאן, מכיוון שאנחנו משתמשים בסוג מחרוזת CS50 המיוחד,
מה הוא סוג המחרוזת CS50?
ראית מה זה כאשר הדוד משך את הברדס בהרצאה?
זה פאנקי-זה מצביע, נכון?
בסדר, כן. >> זה * char.
וכך באמת היינו יכול להחליף את זה
ממש כאן בהודעה * char,
וכן פונקצית GetString, אם הוא לא מקבל מחרוזת בהצלחה מהמשתמש,
זה לא יכול לנתח מחרוזת, ומקרה אחד שבו לא ניתן לנתח את המחרוזת
הוא אם המשתמש מקליד הקצה של אופי קובץ, שליטת D,
וזה לא משהו שאתה בדרך כלל עושה, אבל אם זה קורה
אז הפונקציה תחזיר ערך ריק זה כדרך של אמירה
"היי, אני לא מקבל מחרוזת".
מה היה קורה אם לא יכניס את ההודעה = null,
וזה משהו שאנחנו לא היו עושים זאת?
למה שזה יהיה בעיה כאן?
כי אני יודע שדברנו קצת בהרצאה על דליפות זיכרון.
כן, בואו נעשה את זה, ובואו נראים מה יקרה.
>> שאלתו של באסל היא מה קורה אם אנחנו לא ממש צריכים
הודעה זו = מבחן ריק?
בואו לגלול עד למעלה.
אתם יכולים להגיב על זה.
למעשה, אני אשמור אותו במהדורה.
זו תהיה גרסה 3.
מה שתצטרך לעשות כדי להפעיל תכנית זו הוא שאתה צריך ללחוץ על סמל גלגל השיניים הזה כאן,
ואתה תצטרך להוסיף טיעון אליו.
אתה צריך לתת לו הנימוק המכריע מכיוון שאנחנו רוצים להעביר בארגומנט שורת פקודה.
הנה אני הולך לתת לו את המספר 3. אני אוהב 3.
עכשיו טס חזרה החוצה, להפעיל את התכנית.
זה פועל, קומפילציה, בנייה.
הנה אנחנו מתחילים. הוא מחכה שליתבקש.
אם אני מקליד במשהו כמו שלום, להיכן שתלך?
אה, התכנית שלי לקחה יותר מדי זמן כדי לרוץ. אני אפטפט יותר מדי זמן.
הנה זה מתחיל.
עכשיו אני מקליד בשלום.
אנו רואים כי היא מצפינה כראוי.
עכשיו מה קורה אם אנחנו עושים GetString פקודה להחזיר null?
זכרו, אמרתי שעשינו את זה על ידי לחיצה על השלט D באותו הזמן.
אני לגלול עד כאן. אנחנו נפעיל אותו שוב.
בניין. הנה זה מתחיל.
עכשיו כשאני מכה שליטה D
יש לי את הקו הזה שאומר opt/sandbox50/bin/run.sh, אשמת פילוח.
האם אתם ראיתם את זה קודם?
>> [סטודנטים] מדוע אין->> מצטער?
[סטודנטים] מדוע אין מזבלת ליבה במקרה זה?
מזבלת הליבה היא השאלה מדוע אין מזבלת ליבה כאן?
השאלה היא כי ייתכן שיש, אבל מזבלת הליבה היא קובץ
שמאוחסן בכונן הקשיח.
במקרה זה השבתנו מרוקן ליבה
בשרת הטווח כך שאין לנו אנשי צינוק העתקים גיאולוגיים
ובניית טונות של מצבורי ליבה.
אבל אתה יכול לקבל אחד.
מרוקן ליבה הוא מסוג דברים שלעתים קרובות אתה יכול לבטל,
ולפעמים אתה עושה.
אשמת הפילוח, כדי לענות על שאלתך, בזיל,
הוא אומר שניסינו לגשת מצביע
שלא הוקם כדי להצביע על שום דבר.
זכור ינקי בוידאו כשהינקי מנסה
ללכת לגשת מצביע שלא מצביע על שום דבר?
במקרה זה אני מניח שטכני המצביע מצביע על משהו.
זה מצביע על אפס, שהוא טכני 0,
אבל זה מוגדר להיות בקטע שאינו נגיש
לפי התכנית שלך, כך שאתה מקבל אשמת פילוח
כי אתה לא גישה לזיכרון שהוא בקטע חוקי
כמו קטע הערימה או מחסנית או קטע קטע הנתונים.
מגניב.
עוד שאלות על קיסר?
>> בואו נעבור הלאה. בואו נסתכל על גרסה 2 ממש במהירות.
זה Vigenère.
כאן בVigenère
נדריך אותו דרך האתר הזה די מהר כי, שוב,
Vigenère וקיסר הם די דומים.
תגובת הכותרת היא לפני,
# Define הוא לפני להימנע משימוש במספרי הקסם האלה.
דבר הנחמד הוא לומר שאנחנו רוצים לעבור ל
האלפבית שונה או משהו כזה.
במקום שיש ללכת לשנות באופן ידני את כל 26 של בקוד
אנחנו יכולים לשנות את זה ל 27 או לשלשל אותה
אם הייתי משתמשים באותיות שונות, בשפות שונות.
שוב, יש לנו סימון זו של ספירת הוויכוח,
ובאמת אתה כמעט יכול לקחת את זה כתבנית.
די הרבה בכל תכנית שאתה כותב צריכה-
אם זה לוקח שורת פקודת טיעונים-רצף כלשהו של קווים
שקורא את זה כמו בהתחלה.
זה אחד מבחני השפיות הראשונות שאתה רוצה לעשות.
>> הנה מה שעשינו אנחנו בטוחים ש
מילת המפתח הייתה בתוקף, וכי היה הבדיקה השנייה שעשינו.
שים לב שוב שנפרדנו זה מargc ו 2.
שים לב כי במקרה זה דבר אחד שיש לנו לעשות היה במקום
של השימוש שלאנחנו רוצים לאמת את כל המחרוזת,
וכדי לעשות את זה אתה באמת צריך ללכת תו אחר תו
על המחרוזת.
אין דרך טובה לקרוא משהו על זה
כי גם, למשל, שלאחזיר 0
אם הוא לא יכול לנתח מספר שלם, כך שגם זה לא עובד.
שוב, הודעה נחמדה לספר למשתמש בדיוק מה שקרתה.
אז הנה, שוב, אנחנו מטפלים גם במקרה שבו
המשתמש מקליד באופי אקראי שליטת ד.
>> ואז שארלוט הייתה קודם על שאלה איך אנחנו מצליחין לדלג חללים
במחרוזת שלנו כאן.
זה היה די דומה למה שעשינו עם תכנית Myspace
שעשינו בסעיף, והדרך זה עבדה
הוא שאנחנו אתרנו את מספר המכתבים שעדיין לא ראו.
כשהלכנו על מחרוזת ההודעה, בלכתי על אופי של דמות,
אנחנו אתרנו את המדד כחלקנו מלולאה, ואז גם במעקב
מספר האותיות, כך תווים שאינם מיוחדים,-ספרות עישון, חלל שאינו לבן
שאנחנו ראינו במשתנה הנפרדת.
ואז פתרון זה משנה את המפתח
כדי לקבל מספר שלם מפתח בפועל, והוא עושה את זה במהירות הבזק,
ממש לפני שהתחיל אז ממשיך להצפין את אופי ההודעה בפועל.
יש כמה פתרונות שהיו מושלם מדי גדולים
שיהיה לשנות את המפתח כאשר בוחנים את תקפותו של המפתח.
בנוסף לוודא שאופי ואת מילת המפתח
היה תו אלפביתי זה גם הפך את זה למספר שלם
ב0-25 לטווח אז לדלג על התהליך לעשות את זה בשלב מאוחר יותר בזה ללולאה.
שוב, אתה רואה כאן זה באמת אותו הקוד המדויק
שהשתמשנו בקיסר בשלב זה.
אתה עושה בדיוק את אותו דבר, ולכן הטריק האמיתי הוא להבין
איך להפוך את מילת המפתח במספר שלם.
>> דבר אחד שעשינו כאן שהוא קצת צפוף
הוא חזרנו על המשפט הזה, אני מניח שאפשר לקרוא לזה,
3 פעמים נפרדות בקווים 58, 59, ו 61.
מישהו יכול להסביר מה בדיוק עושה בביטוי הזה?
זה גישה לאופי, כמו שאמרת.
כן, זה [לא ברור] דמות במילת המפתח,
ואז זה מספר המכתבים ראו כי אתה רק זזת יחד
מילת המפתח ברגע שראית את המכתב,
כך זה הולך בצורה יעילה כדי לדלג רווחים ודברים כאלה.
כן, בדיוק.
ואז ברגע שראית את חסר מילת המפתח אתה פשוט mod כך חזרת לגור בסביבה.
בדיוק. זה הסבר מושלם.
מה אמר קווין הוא שאנחנו רוצים ליצור אינדקס למילת המפתח.
אנחנו רוצים לקבל את תו num_letters_seen, אם נרצה,
אם num_letters_seen חורג מהאורך של מילת המפתח, אבל,
הדרך בה אנו מקבלים בחזרה לתוך הטווח המתאים היא שאנו משתמשים במפעיל mod
ביעילות כדי לעטוף.
לדוגמה, כמו בבקיצור, מילת המפתח שלנו היא בייקון,
וזה עוד 5 אותיות.
אבל ראו כבר 6 אותיות בטקסט הרגיל שלנו בשלב זה
ומוצפן 6.
אנחנו בסופו של גישת num_letters_seen,
שעומדים על 6, mod האורך של מילת המפתח, 5,
ולכן אנחנו מקבלים 1, ואז מה שנעשינו הוא שנהיה
לגשת בתוך התו הראשון של מילות המפתח שלנו בשלב זה.
>> בסדר, כל שאלה על Vigenère
לפני שנמשיך הלאה?
אתם מרגישים די טובים בזה?
מגניב, נהדר.
אני רוצה לוודא שאתם מקבלים את ההזדמנות לראות את הקוד
כי אנחנו חושבים שנראים טוב ויש לי את ההזדמנות ללמוד ממנו.
זה הולך להיות אחרון שאנחנו משתמשים בי רווחים לעת עתה,
ואנחנו הולכים למעבר עכשיו, ואני הולך לcs50.net/lectures
כדי שנוכל לעשות קצת ביקורת חידון.
הדרך הטובה ביותר שאני חושב להתחיל לעשות חידון ביקורת
הוא להגיע לדף הרצאות זו, cs50.net/lectures,
ומתחת לכל אחת מהכותרות בשבוע, כך שאם אני מסתכל כאן בשבוע 0,
אני רואה שיש לנו רשימה של נושאים שכיסינו בשבוע 0.
>> אם כל אחד מהנושאים האלה נראים זר לך
אתה בהחלט רוצה לחזור ולסרוק את סיכומי הרצאות ואולי
אפילו לרחף באמצעות הרצאות, לצפות בם שוב אם אתה רוצה
כדי לקבל תחושה לגבי מה שקורה עם כל אחד מהנושאים האלה.
אני אומר את זה שנה אחת של משאבים המגניבים שיש לנו בנוסף
מכנסיים קצרים הוא אלה שיצרנו, ואם אתה מסתכל על שבוע 0,
אין לנו כל הנושאים המכוסים, אבל יש לנו לא מעט מהם,
כמה מאלה שהכי הממולחים, כך צופים המכנסים האלה שוב
היא דרך טובה כדי להביא לך עד המהירות.
בפרט, אני הולך לשים בתקע ל3 בתחתית, מאז שעשיתי אותם.
אבל אם אתה נאבק עם בינארי, ביטים, hex, דברים כאלה,
בינארי הוא מקום מצוין להתחיל בו.
ASCII הוא עוד אחד זה טוב כדי להציג מדי.
אתה יכול אפילו לצפות לי במהירות 1.5x אם אני מתקדם לאט מדי בשבילך.
מאחר שהסקירה של זה, תרגיש חופשי לעשות את זה.
>> רק כדי להתחיל ממש מהר, אנחנו הולכים לעבור כמה בעיות בחנים אלו
רק כדי נטישה במהירות באמצעות אלה.
לדוגמה, בואו נסתכל על בעיה 16 שיש לי חברים כאן בלוח.
יש לנו חישוב הבא זה בינארי,
ואנחנו רוצים להראות לכל עבודה.
אוקיי, אני הולך לתת את זה זריקה.
אתם צריכים לבצע יחד עם נייר,
ואנחנו נעשה את זה ממש מהר.
אנחנו רוצים לבצע את החישוב הבא בינארי.
יש לי 00110010.
ואני מתכוון להוסיף לזה 00110010.
למתמטיקת גאונים הבאים יחד בבית,
זאת ביעילות היא הכפלה פי 2.
בואו נתחיל.
אנחנו הולכים לבצע את אותו האלגוריתם בנוסף שאנחנו עושים
כאשר מוסיפים מספרים עשרוניים יחד.
באמת ההבדל היחיד כאן הוא שאנחנו לולאה סביב גב
פעם אחת יש לנו 1 + 1 במקום ברגע שאנחנו מקבלים עד 10.
>> אם תתחילו מימין, ממש מהר, מה הספרה ראשונה?
[סטודנטים] 0. >> [נייט ח] 0.
גדול, הספרה השנייה?
[סטודנטים] 1.
[נייט ח'] האם זה 1? 1 + 1 הוא?
[סטודנטים] 10.
[נייט ח] בדיוק, אז מה היא הספרות שאני כותב ממש מתחת ל2 אלה נוספו ביחד?
[סטודנטים] 1, 0, או 0 ולאחר מכן לבצע 1.
[נייט ח] 0 ולבצע 1, בדיוק.
עד אחד, הזיל הבא, אתה למעלה.
מה השלישי? >> [זיל] 1.
[נייט ח] 1, מושלם. קווין?
[קווין] 0. >> [נייט ח] 0, שרלוט?
[שארלוט] 0. >> [נייט ח] כן, ומה עליי לעשות?
[סטודנטים] 1.
[נייט ח] ומה עליי לעשות? ואז אני נושא 1.
מושלם, Sahb? >> [Sahb] עכשיו יש לך 1.
[נייט ח] ועליי לעשות פה משהו?
[Sahb] ואז לאחד הבא יש לך 1 בגלל שנשאת מעל 1.
[נייט ח'] גדול, אז הנה אנחנו יכולים לגמור אותו.
מגניב.
[סטודנטים] האם 0 + 0 = 0?
0 + 0 = 0.
1 + 1, כמו שאמרת, הוא 10 או 1, 0, ולא.
10 הן שם מטעים, כי אליי 10 אומרים את המספר 10,
וזה השיגיון של איך אנחנו מייצגים את זה כאשר אנחנו כותבים את זה.
אנחנו מייצגים את המספר 2 על ידי 1, 0, והמספר 10 הוא שונה במקצת.
>> מה סוג של נחמד על בינארי הוא שבאמת אין כל כך הרבה
מקרים שאתה צריך ללמוד.
יש 0 + 0 = 0, 0 + 1 = 1,
1 + 1 הוא 0, ולאחר מכן לבצע 1,
ואז אתה יכול לראות כאן בטור השלישי מימין
היו לנו זה 1, 1, ו 1.
ו1 + 1 + 1 הוא 1,
ואתה נושא עוד 1.
כשאתה עושה בנוסף ינארי, די פשוט.
הייתי עושה עוד כמה מאלה לשפיות לבדוק את עצמכם
לפני שאתה הולך בכי זה
כנראה משהו שנראה בחידון.
עכשיו בואו נעשה הבא זה גם כן.
בואו נעשה את הבעיה 17.
אנחנו הולכים להמיר את המספר הבינארי הבא לעשרוניים.
יש לי 10100111001.
זכור בוידאו בינארי שאני עשיתי
הלכתי דרך כמה דוגמאות, והראיתי כיצד
הכל עובד כשאתה עושה את זה בנקודה עשרונית.
כשאתה עובד בייצוג עשרוני אני חושב שאנחנו
בנקודה זו בחיינו כל כך מומחה בזה כי
זה די קל לחפות על המכניקה של איך זה עובד בפועל.
>> אבל כדי לעשות סיכום מהיר, אם יש לי מספר 137
זה באמת אומר, ושוב, זה בייצוג עשרוני-
המספר 137 בעשרוני פירושו שיש לי 100 + 1 x 3 x 10 + 7 x 1.
כל זה נשאר על המסך.
ואז אם אתה מסתכל על המספרים האלה ממש כאן,
100, 10 ו 1, אתה רואים שהם למעשה כל הסמכויות של 10.
יש לי 10 מ"ר, 10 ¹, ו 10 לאפס.
יש לנו סוג דומה של דבר בינארי,
חוץ מזה שהבסיס שלנו, כפי שאנו מכנים אותו, 2 במקום 10.
10s אלה שכתבתי כאן למטה בתחתית,
10 ² זה, 10 ¹, 10 לאפס, 10 הוא הבסיס שלנו,
והמעריך, 0, 1 או 2,
משתמע מהמיקום של הספרה במספר שאנחנו כותבים.
1, אם אנחנו מסתכלים על זה, זה 1 הוא בעמדת 2.
3 הם בעמדת 1, ו7 הם בעמדת 0.
ככה אנחנו מקבלים את המעריכים השונים מתחת לבסיס שלנו.
>> בעקבות כל להכין מ- למעשה זה, אתה יודע מה?
אנחנו נעשה-איפה כפתורי לבטל ללכת?
הנה זה מתחיל.
אני אוהב את זה לבטל דבר.
בעקבות זאת אני חושב שבשבילי לפחות
הדרך הקלה ביותר להתחיל המרת מספר בינארי
או מספר הקסדצימלי בו הבסיס הוא 16
ולא 10 או 2 הם להמשיך ולכתוב את
הבסיסים ופרשנים לכל המספרים במספר בינארי בראש.
אם נתחיל משמאל לימין שוב,
וזה די מנוגד,
אני אשנה בחזרה לשחור כאן, יש לנו 2 לעמדת 0,
ואז יש לנו 2 ¹, 2 ²,
ולאחר מכן 2 עד 3, 2 ל4, 2 עד 5, 6,
7, 8, 9, 10.
מספרים אלה שכתבתי את כל את המעריכים.
אני כתבתי רק את הבסיסים כאן ב3 ראשונים רק בשביל רווח.
>> בשלב זה אני הולך קדימה, ובעצם אני הולך למחוק
הדברים שעשינו בעשרוני, אם זה בסדר.
כל שיש לך את זה.
אלה מכם צופים באינטרנט אני בטוח שנוכל להחזיר לאחור אותי אם תרצה.
מעבר בחזרה למכלאה.
עכשיו, מה שאנחנו יכולים לעשות, אם אתם לא לגמרי עד מהירות על הכוחות שלך של 2,
זה מגניב לגמרי.
זה קורה. אני מבין.
פעם הייתה לי ראיון עבודה שבו נאמרתי לי שאני צריך לדעת את כל הסמכויות של 2
דרך 2 עד 30.
זה לא היה תפקיד שקבלתי.
בכל מקרה, אתם יכולים ללכת ולעשות את המתמטיקה כאן,
אבל עם ינארי זה לא ממש הגיוני,
וגם לא הגיוני עם עשרוני או הקסדצימאלי או,
כדי לעשות את החשבון שבו אתה צריך אפסים.
אתה יכול לראות שיש לי 0 כאן, כאן 0, 0 כאן, 0 כאן, 0 כאן, 0 כאן.
למה אולי זה לא הגיוני לעשות את המתמטיקה בפועל
כדי לחשב את הכח המתאים של 2 עבור אותה העמדה?
בדיוק כמו שרלוט אמרה, זה יהיה 0.
גם זה עשוי לחסוך לעצמך את הזמן אם חישוב חזק של 2 הוא לא הצד החזק שלך.
במקרה זה אנו רק צריכים לחשב את זה עבור 2 עד 0 שהם?
[סטודנטים] 1.
[נייט ח] 1, 2 ל3 שהם?
[סטודנטים] 8. >> [נייט ח] 8.
2 עד 4?
[סטודנטים] 2. אני מצטער, 1.
[נייט ח] 2 עד 4 הוא 16, בדיוק.
2 עד 5, קווין? >> 32.
[נייט ח] 32, 2 עד 8?
[סטודנטים] 32 x 8, 256.
[נייט ח] מושלם.
ו2 עד 10?
[סטודנטים] 1024.
[נייט ח] כן, 1024.
>> ברגע שיש לנו את המספרים האלה נוכל לסכם את כולם.
וזה המקום שבו באמת חשוב לעשות כמה דברים.
אחד הולך להאט ולבדוק את העבודה שלך.
אתה יכול להגיד שיש 1 בסוף של מספר זה,
אז אני בהחלט צריך לקבל מספר אי זוגי כתוצאה שלי,
משום שכל האחרים הולכים להיות אפילו מספרים
בהתחשב בעובדה שמדובר במספר בינארי.
הדבר השני הוא לעשות אם אתה להגיע לנקודה הזאת במבחן
ואתה כתבת את זה כל כך רחוק
ואתה הולך ואוזל הזמן
מסתכל על מספר הנקודות שבעיה זו היא שווה.
בעיה זו, כפי שאתה יכול לראות, אם אני מדפדף חזרה למחשב הנייד שלי ממש מהר,
בעיה זו היא שווה 2 נקודות, אז זה לא מהסוג בנוסף
אתה צריך ללכת דרך אם אתה באמת לחוץ בזמן.
אבל אנחנו לחזור לאייפד, ואנחנו נעבור את זה ממש מהר.
>> אני אוהב לעשות את המספרים הקטנים 1
משום שאני מוצא שיותר קל.
אני אוהב את 32 ו 8 כי הם הולכים ביחד די בקלות, ואנחנו מקבלים 50.
16 ו 1 מקבלים 17.
יש לנו לקבל 57,
ואז אנחנו יכולים לעשות את השאר לכך, ולכן אנחנו יכולים לעשות 57, 156.
נו באמת.
גבר, טוב, בואו נראים.
היו לנו 57, 256, ו1024.
בשלב זה, אני מעדיף לעבור.
אין לי מושג. הייתי לי ברור שאצטרך לקרוא על זה.
7, 6, 4, אתה מקבלים 17.
1, 5, 5, 2, 13.
ואז אנחנו מקבלים 3, ואז אנחנו מקבלים 1.
1337.
ביצת פסחא, מישהו?
מישהו זיהה את המספר הזה?
כריס מזהה את המספר. מה זה אומר, כריס?
[כריס] לאת.
לאת, כך שאם אתה מסתכל על זה, זה נראה כמו leet.
דברי האקר. היזהר מסוג הזה במבחן מחצית או החידון, ולא.
אם אתה רואה דברים כאלה ואתה תוהה "אה,"
שאולי בעצם אומר משהו.
אני לא יודע. דוד אוהב לשים אותו פנימה
זוהי דרך טובה לשפיות לבדוק את זה.
כמו בסדר, אני יכול לראות מה קורה.
>> זה שבוע דברי 0/Week 1.
אם לחזור למחשב הנייד שלנו עכשיו,
להתרחק, וכמה דברים אחרים.
יש ASCII, שאנחנו כבר עושים הרבה עם קבוצות הבעייתיות.
רעיון זה של ההון א 'מה זה באמת?
לדעת שזה המספר העשרוני השלם.
65 הם מה זה ממופה בטבלת ASCII,
וזה כן איך המחשב כותב אותו,
וככה אנחנו כבר מקבלים משם עם הכתיבה ממש
הון הדמות ודמות אותיות קטנות
בחלק מהפתרונים הללו וערכות בעיה שאתה כבר עושה.
כמה דברים אחרים.
יש לנו הצהרות, הבעות וליאניות, תנאים, לולאות, משתנה וחוטים.
>> כל אלו נראים הגיוניים ברוב המקרים?
חלק ממינוח זה קצת מסריח בזמנים.
אני אוהב לחשוב על הדברים כעל משהו החלק ביותר שמסתיים בנקודת פסיק.
הצהרות כמו x = 7, אשר קובעה משתנית,
קרא כנראה x = 7.
יש להניח x הוא גם סוג שיכול לאחסן המספר 7,
כך שזה int או אולי לצוף או קצר או char,
משהו כזה.
ביטוי הבוליאני משתמש כפול אלה שווים
והמפץ שווה או לא שווה, פחות מ, גדול מ,
קטן או שווה לכל סוג כזה של דברים.
תנאים אז הם הצהרות אם אחרות.
אני זוכר שאתה לא יכול להיות אחר, בלי מקביל אם.
כמו כן, אתה לא יכול להיות אחר אם ללא אם מקביל.
לולאות, זוכרות את 3 סוגים של לולאות אנחנו כבר מכים בך
לזוג האחרון של קטעים וערכות בעייתיות.
שימוש לעשות בשעה שכאשר אתה מקבל קלט משתמש,
באמצעות לולאות בזמן עד מצב מסוים הן אמיתיות,
ולאחר מכן באמצעות אלה ללולאות אם אתה צריך
יודע שאיטרציה של הלולאה אתה כרגע על הדרך בה אני חושב על זה.
או אם אתה עושה עבור כל תו במחרוזת שאני רוצה לעשות משהו,
לכל רכיב במערך שאני רוצה לעשות משהו כדי שהאלמנט.
>> נושאים ואירועים.
אנחנו אלה שאינם מכוסים על כך במפורש ב-C,
אבל זוכר את זה מהתחלה.
זה הרעיון שיש תסריטים שונים.
זהו גם רעיון זה של שידור אירוע.
יש אנשים שלא השתמש בשידור בפרויקטים שלהם בתחילה,
שהוא מגניב לגמרי,
אבל אלה הם 2 דרכים שונות לטיפול בנושא הגדול הזה שנקראים מקביליות,
אשר הוא איך אתה מקבל תוכניות לביצוע
לכאורה או לבצע באותו הזמן?
משימות שונות פועלות בזמן משימות אחרות גם פועלות.
כך מערכת ההפעלה שלך נראית עבודה.
זו הסיבה שלמרות ש, למשל,
אני כבר הלכתי לדפדפן שלי פועל, אני יכול גם להפעיל את Spotify ולנגן שיר.
זה יותר עניין רעיוני להבנה.
הייתי אסתכל על אשכולות הקצרים
אם אתה רוצה ללמוד יותר על זה.
>> בואו נראים, אני מאמין שאולי היה
בעיה בזה באחד מאלה.
שוב, אני חושב שנושאים ואירועים הם לא משהו שאנחנו נכסה ב-C
רק בגלל שזה הרבה יותר קשה מאשר בהתחלה.
אתה לא צריך לדאוג בקשר לזה שם, אבל בהחלט מבין את המושגים,
להבין מה קורה.
לפני שנמשיך הלאה, כל שאלות בשבוע 0 חומריות?
כולם מרגישים די טובים?
משתני הבנה ומה שמשתנה הם?
>> ימשיך הלאה. שבוע 1.
כמה דברים כאן שלא היו מכוסים במיוחד
בביקורת החידון בהכרח וגם דברים רעיוניים יותר לחשוב עליהם.
הראשון הוא זה מושג מה קוד מקור, מהדרים וקוד אובייקט נמצאים.
מישהו? זיל.
האם אובייקט קוד אני מתכוון קוד המקור הוא מה שאתה מכניס את הצלצול,
וגם קוד אובייקט הוא מה שמוציא צלצול, כך שהמחשב שלך יכול לקרוא את התכנית.
בדיוק.
קוד המקור הוא קוד C שאתה בעצם מקליד את.
קוד יעד הוא מה שאתה מקבל מצלצול.
זה 0s ו 1s שבתבנית בינארית.
ואז מה שקורה הוא כאשר יש לך חבורה של קבצי אובייקט,
אומר אתה קומפילצית פרויקט או תכנית שמשתמשת בקוד מקור קבצים מרובים,
אשר לפי אמנה ניתנת. סיומת קובץ ג.
זו הסיבה שיש לנו caesar.c, vigenère.c.
אם אתה כותב תוכניות Java אתה נותן להם את הסיומת. Java.
תוכניות פייתון יש סיומת. py לעתים קרובות.
>> ברגע שיש לך קבצים מרובים ג., אתה לקמפל אותם.
קלאנג יורק את כל זבל בינארי זה.
אז בגלל שאתה רוצה תכנית 1 בלבד
יש לך קישור המקשר כל אובייקט אלה קבצים יחד
לקובץ הפעלה 1.
זה גם מה שקורה כאשר אתה משתמש בספריית CS50, למשל.
ספריית CS50 היא גם ש. קובץ כותרת h
שאתה קורא, ש# includecs50.h.
ואז זה גם קובץ בינארי ספרייה מיוחד
זה שנאסף היא 0s ו 1s,
וש- l דגל, אז אם אנחנו חוזרים למקומות שלנו ואנחנו נראים ממש מהר
במה שקורה כאן כאשר אנו מסתכלים בפקודת הצלצול שלנו,
מה שיש לנו הוא זה קובץ קוד המקור שלנו כאן.
אלה הם חבורה של דגלי מהדר.
ואז ממש בסוף, אלה-l קישור בדגלים
את הקבצים בינאריים בפועל עבור 2 ספריות אלה, CS50 ספרייה ואז ספריית המתמטיקה.
>> הבנה כל סוג של המטרה 'קבצים
בתהליך ההידור הוא משהו שאתה רוצה להיות מסוגל
לתת לפחות סקירת רמה גבוהה של.
קוד המקור נכנס קוד אובייקט שיוצא.
קבצי קוד אובייקט לקשר יחד, ואתה מקבל קובץ יפה, הפעלה.
מגניב.
זהו גם איפה אתה יכול לקבל טעויות בנקודות מרובות
בתהליך ההידור.
זה המקום בו, למשל, אם אתה לוקח את דגל הקישור הזה,
CS50 הדגל, ואתה משמיט אותו בחדרים או כאשר אתה מפעיל את הקוד שלך,
זה שבו יקבל שגיאה בשלב הקישור,
והמקשר יגידו, "היי, אתה נקרא GetString פונקציה
זה בCS50 הספרייה. "
"אתה אמרת לי שזה היה בCS50 הספרייה, ואני לא מצליח למצוא את הקוד שלו."
זה שבו אתה צריך לקשר אותו ב, וזה נפרד
משגיאת מהדר כי המהדר הוא מחפש בתחביר ובסוג כזה של דברים.
זה טוב לדעת מה קורה מתי.
>> דברים אחרים כדי לדעת.
הייתי אומר שאתה בהחלט רוצה להעיף מבט הקצר על ליהוק שחקנים נעשה על ידי ירדן
כדי להבין מה ints הוא מתחת למכסת המנוע,
מה תווים הם מתחת למכסת המנוע.
כאשר אנו מדברים על ASCII ואנחנו באמת מסתכלים על טבלת ASCII,
מה שהוא עושה הוא נותן לנו תחת מבט הברדס
כיצד המחשב מייצג הון בפועל ו7 ספרות
ופסיק וסימן שאלה.
המחשב יש גם דרכים מיוחדות כדי לייצג
המספר 7 כמספר שלם.
יש לו דרך מיוחדת כדי לייצג את המספר 7 כמספר עשרוני,
ואלה הם שונים מאוד.
ליהוק שחקנים הוא איך אתה מספר למחשב "היי, אני רוצה להמיר
מייצוג אחד לייצוג אחר. "
למה שלא נסתכל על זה.
>> הייתי גם להעיף מבט הקצר על ספריות והקצרות על מהדרים.
מי מדבר על התהליך של לקט,
מה היא ספרייה, ולעבור על חלק מהשאלות הללו, כי ייתכן ששואלים.
שאלות על חומר 1 שבוע?
האם יש נושאים כלשהם בכאן שנראים מרתיעים אתה רוצה לכסות?
אני מנסה לפוצץ דרך רוב הנושאים אלה קודם לכן, כדי שנוכל להגיע ל
מצביעים ועושים מעט סיבי של רקורסיה.
מחשבות?
עיקר לכסות?
הגיע זמן לקצת שוקולד אולי?
אתם עובדים דרכו.
אני הולך לשמור על לוגם את הקפה שלי.
שבוע 2.
שיחה טובה, שיחה טובה.
בשבוע 2 שדברנו קצת יותר על פונקציות.
>> בכמה סטי הבעיה הראשונות לא באמת לכתוב כל פונקציות בכל
מלבד איזה תפקיד?
[סטודנטים] ראשי. >> ראשי, בדיוק.
וכך אנו רואים את התלבושות השונות שעיקריים לובשת.
יש אחד שבו לא לוקח טיעונים,
ואנחנו רק אומרים בחלל בין הסוגריים,
ואז יש את האחר שבו אנחנו רוצים לקחת את הארגומנטים בשורת פקודה,
וכפי שראינו, זה שבו יש לך int argc ומערך argv מחרוזת
עכשיו או שבעצם אנחנו נחשפים מחרוזת להיות * char שזה
אנחנו הולכים להתחיל לכתוב אותו כchar * argv ואז סוגריים.
בסט הבעיה 3, אתם ראיתם חבורה של פונקציות,
ואתה יישמת חבורה של פונקציות, לצייר, להסתכל למעלה, לטפס.
אבות הטיפוס כולם כתובים שם בשבילך.
>> מה שאני רוצה לדבר עליו כאן עם פונקציות ממש מהר
הם שיש 3 חלקים אליהם בכל פעם שאתה כותב פונקציה.
אתה צריך לציין את סוג ההחזרה של הפונקציה.
אתה חייב לציין שם לפונקציה, ואז אתה צריך לציין
רשימת הטיעון או רשימת הפרמטרים.
לדוגמה, אם אני הייתי צריך לכתוב פונקציה לסכם חבורה של מספרים שלמים
ואז תחזור אליי הסכום מה יהיה סוג החזרה שלי
אם אני רוצה לסכם מספרים שלמים ולאחר מכן להחזיר את הסכום?
ואז את השם של הפונקציה.
אם אני ממשיך וכותב בירוק, החלק הזה הוא סוג התמורה.
חלק זה הוא שם.
ואז בסוגריים
מקום שבו אני נותן את הטיעונים,
לעתים קרובות מקוצר כמו ארגומנטים, הנקראים לפעמים params לפרמטרים.
ואם יש לך אחד, אתה פשוט לציין את אחד.
אם יש לך מספר רב לך להפריד כל אחד מהם בפסיק.
ולכל טיעון שאתה נותן לו 2 דברים שהם, קווין?
[קווין] אתה צריך לתת את הסוג ולאחר מכן את השם.
ואז את השם, והשם הוא השם שאתה הולך להשתמש
כדי להתייחס לטענה שבתוך פונקצית הסכום,
בתוך הפונקציה שכרגע אתה כותב.
>> אתה לא צריך, למשל, אם אני הולך לסיכום,
אומרים, מערך של מספרים שלמים להכין מלעשות מערך int,
ואני אתן לעצמי כמה סוגריים מסולסלים שם,
אז כשאני עובר על מערך לפונקצית הסכום
אני מעביר אותו במקום הראשון של רשימת הוויכוח.
אבל המערך שאני עובר באינו צריך את השם arr.
Arr הולך להיות איך אני מתייחס לטענה שבתוך הגוף של הפונקציה.
הדבר השני שאנחנו צריכים לקחת בחשבון,
וזה קצת שונה מפונקציות, אבל אני חושב שזה נקודה חשובה,
הוא כי ב-C כאשר אני כותב בפונקציה כמו זו
איך אני יודע כמה אלמנטים במערך הזה?
זה במידה מסוימת של שאלה מכשילה.
דברנו על זה קצת בקטע של השבוע שעבר.
איך אני יודע את המספר של אלמנטים בתוך מערך ב-C?
האם יש דרך?
>> מתברר שאין שום דרך לדעת.
אתה צריך לעבור אותו בנפרד.
יש טריק שאתה יכול לעשות
אם אתה נמצא באותה הפונקציה שבמערך הוכרז,
ואתה עובד עם מערך מחסנית.
אבל זה עובד רק אם אתה נמצא באותה הפונקציה.
ברגע שתעבור מערך לפונקציה אחרת או אם הכרזת מערך
ואתה שם את מערך שעל הערימה, שבה השתמש malloc
ודברים כאלה, אז כל ההימורים מבוטלים.
אז אתה בעצם צריך לעבור מסביב
טיעון מיוחד או פרמטר נוסף
אומר לך כמה גדול הוא המערך.
במקרה זה, הייתי רוצה להשתמש בפסיקים אני מצטער, זה הולך מחוץ למסך כאן
ואני אפגוש אותו בטענה אחרת
וקוראים לזה int len ​​לאורכו.
>> דבר אחד שעשויה לבוא על החידון
אינו מבקש ממך לכתוב או ליישם פונקציה מסוימת קראה משהו.
אם אנחנו לא נותנים לך את אב טיפוס, ולכן כל העניין הזה כאן,
כל הבלגן הזה נקרא הכרזת פונקציה או אב טיפוס הפונקציה,
זה אחד הדברים הראשונים שאתה רוצה להגדיר בבירור אם זה לא נתון
אליך מייד בחידון.
הטריק האחר שלמדתי הוא ש
אומר שאנחנו עושים לך אב טיפוס של פונקציה, ואנחנו אומרים, "היי, יש לך לכתוב אותו."
בתוך הסוגריים המסולסלים שיש לך על החידון
אם אתה שם לב שיש סוג שיבה ואתה שם לב שטיפוס ההחזרה
הוא משהו אחר מהחלל, מה שאומר שהפונקציה לא מחזירה שום דבר,
אז דבר אחד אתה בהחלט רוצה לעשות הוא לכתוב
איזה משפט חוזר בסופו של הפונקציה.
תמורה, ובמקרה הזה, אנו מכניסים ריקים כי אנחנו רוצים למלא את החסר.
אבל זה גורם לך לחשוב בצורה הנכונה על איך אני הולך לגשת לבעיה זו?
וזה מזכיר לך שאתה הולך לעשות כדי להחזיר ערך
למתקשר של הפונקציה.
>> כן. >> [סטודנטים] האם סגנון יחול כאשר אנחנו כותבים קוד בחידון?
כמו היישור וחומר מסוג הזה? >> [סטודנטים] כן.
לא, לא באותה מידה.
אני חושב שהרבה מזה משהו, אנחנו נבהיר בחידון ביום,
אבל בדרך כלל # לדאוג כולל ודברים כאלה, זה סוג של מחוץ.
[סטודנטים] האם אתה צריך להגיב הקוד הכתוב בכתב היד שלך?
אתה צריך להגיב הקוד הכתוב בכתב היד שלך?
בהתייחסו תמיד טוב, אם אתם מודאגים לגבי זיכוי חלקי
או שאתה רוצה שכוונתך לכיתה.
אבל, שוב, יבהיר בחידון עצמו וביום החידון,
אבל אני לא מאמין שאתה תהיה נדרש כדי לכתוב הערות, לא.
בדרך כלל לא, אבל זה בהחלט מסוג הדברים שבי
אתה יכול לתקשר הכוונה שלך, כמו "היי, זה לאן אני הולך עם זה".
ולפעמים זה יכול לעזור עם זיכוי חלקי.
מגניב.
>> זיל.
[זיל] מה ההבדל בין הכרזה, אומר, int lang
בטיעונים או הפרמטרים לעומת הכרזה משתנית בתוך הפונקציה?
וואו, קפה ירד לקנה הנשימה.
[זיל] כמו שדברים שאנחנו רוצים לשים בטענות.
כן, זה שאלה גדולה.
איך אתה בוחר מה דברים שאתה רוצה לשים בטענות
לעומת מה דברים שאתה צריך לעשות בתוך הפונקציה?
במקרה זה כללנו את שני אלה כטיעונים
בגלל שהם משהו שכל מי שהולך להשתמש בפונקצית הסכום
צריך לציין את הדברים האלה.
>> פונקצית הסכום, כמו שדברנו עליה, אין כל דרך לדעת
כמה גדול הוא המערך שהיא מקבלת מהמתקשר שלה או מי שמשתמש בפונקצית הסכום.
יש לו כל דרך לדעת כמה גדול הוא מערך ש.
הסיבה שאנו עוברים באורך זה ממש כאן כטיעון
בגלל שזה משהו שאנחנו בעצם אומרים את המתקשר של הפונקציה,
מי שמתכוון להשתמש בפונקציית הסיכום, "היי, לא רק שאתה צריך לתת לנו מערך
של ints, אתה גם צריך לספר לנו עד כמה גדול המערך שנתת לנו הוא ".
[זיל] אלה יהיו גם יהיו טיעוני שורת פקודה?
לא, אלה הם טענות ממשיות שתעברו לפונקציה.
>> תן לי לעשות דף חדש כאן.
[הזיל] כמו שם יעבור-
[נייט ח] אם יש לי int ראשי (ריק),
ואני הולך לשים ב0 החזרה שלי כאן למטה בתחתית,
ואומר שאני רוצה לקרוא את פונקצית הסכום.
אני רוצה לומר int x = סכום ();
כדי להשתמש בפונקציית הסכום אני צריך לעבור גם במערך שאני רוצה לסכם
והאורך של המערך, כך שזה המקום שבי
בהנחה שיש לי מערך של ints,
אומרים לי int numbaz [] = 1, 2, 3,
סוג של שימוש שטבח את התחביר נכון לשם,
אז מה הייתי עושה הוא בסכום שהייתי רוצה להעביר ב
שניהם numbaz והמספר 3
לספר את פונקצית הסכום "אוקיי, הנה המערך אני רוצה לסכם".
"הנה הגודל שלה".
האם זה הגיוני? זה עונה על שאלתך?
>> במובנים רבים הוא עושה במקביל את מה שאנחנו עושים עם ראשיים
כאשר יש לנו את טיעוני שורת הפקודה.
תכנית כמו קיסר צופן, למשל, שצריכה
הארגומנטים בשורת פקודה לא יהיו מסוגלים לעשות כל דבר.
זה לא הייתי יודע איך להצפין אם אתה לא אומר לו מה מפתח לשימוש
או אם אתה לא אומר לו מה אתה רוצה מחרוזת להצפנה.
הצגת הודעה לקלט, זה שבו יש לנו 2 מנגנונים שונים
לקחת קלט במשתמש, ללקיחת מידע מהמשתמש.
לבעית הגדרה 1 ראינו GetInt זה GetString הדרך, GetFloat
של הנחיה לקלט, וזה נקרא שימוש בזרימת הקלט הסטנדרטית.
זה קצת שונה.
זה משהו שאתה יכול לעשות בזמן זה בניגוד ל
כשאתה מזכיר את התכנית, כאשר אתה מפעיל את תכנית ריצה.
טיעוני שורת הפקודה כולם ציינו בעת להתחיל להפעיל את התכנית.
אנחנו כבר ערבוב שני אלה.
כאשר אנו משתמשים בטיעונים לפונקציה, זה הרבה יותר כמו טיעוני שורת פקודה לראשית.
זה כשאתה מזכיר את הפונקציה אתה צריך להגיד את זה
מה בדיוק הוא צריך על מנת לבצע את משימותיו.
עוד דבר טוב להסתכל ואני אתן לך להסתכל על זה בזמנך הפנוי,
והיא הייתה מכוסית בחידון, הייתה זו תפיסה של היקף
ומשתנים מקומיים לעומת משתנים הגלובליים.
האם לשים לב לזה.
>> עכשיו שאנחנו מקבלים על דברים אחרים,
בשבוע 3 התחלנו לדבר על חיפוש ומיון.
חיפוש ומיון, לפחות בCS50,
היא מאוד הקדמה לחלק מהחלקים התיאורטיים יותר של מדעי מחשב.
הבעיה של חיפוש, הבעיה של מיון
בעיות גדולות, קנוניות.
איך אתה מוצא מספר מסוים במערך של מליארד מספרים שלמים?
איך אתה מוצא שם מסוים בתוך ספר טלפונים
שמאוחסן במחשב הנייד?
וכך אנחנו מציגים את הרעיון הזה של לרוץ פעמי asymptotic
באמת לכמת כמה זמן, כמה קשה בעיה אלה,
כמה זמן לוקחים לפתרון.
ב, אני מאמין, חידון של 2011 יש בעיה שאני חושב שראויים
מכסה מהר מאוד, שהוא זה, הבעיה 12.
הו, לא, זה אומגה.
>> כאן אנחנו מדברים על זמן הריצה המהירה ביותר האפשרי
לאלגוריתם מסוים ולאחר מכן זמן הריצה האיטי ביותר האפשרי.
אומגה וO זה הם באמת רק קיצורי דרך.
הם קיצורי סימנים, על שאמרו
כמה מהר במקרה הטוב ניתן יהיה להפעיל האלגוריתם שלנו,
וכיצד איטיים במקרה הגרוע ביותר האפשרי יהיה האלגוריתם שלנו להפעיל?
בואו נעשה כמה כאלה, ואלה היו גם מכוסים
בטווח הקצר בסימון אסימפטוטי, שאני מאוד ממליץ.
ג'קסון עשה עבודה ממש טובה.
בחיפוש בינארי, אנחנו מדברים על חיפוש בינארי כאלגוריתם,
ואנחנו בדרך כלל מדברים על זה במונחים של הגדול O.
מה הוא הגדול O?
מהו זמן הריצה האיטית ביותר האפשרי של החיפוש בינארי?
[סטודנטים] N ²?
סגור, אני מניח דומה לזה.
זה הרבה יותר מהר מאשר זה.
[סטודנטים] בינארי? >> כן, חיפוש בינארי.
[סטודנטים] זה log n.
היכנס n, אז מה עושה להתחבר n אומר?
זה חצי זה כל איטרציה.
בדיוק, אז במקרה האיטי ביותר האפשרי,
אומר שאם יש לך מערך ממוין
של מיליון מספרים שלמים והמספר שאתה מחפש
הוא גם האלמנט הראשון במערך או האלמנט האחרון במערך.
זכור, אלגוריתם החיפוש הבינארי עובד על ידי ההתבוננות באלמנט האמצע,
לראות אם זה המשחק שאתה מחפש.
אם זה הוא, אז נהדר, מצא את זה.
>> במקרה הטוב ביותר, כמה מהר עושה ריצת חיפוש בינארי?
[סטודנטים] 1.
1, זה זמן קבוע, הגדול O של 1. כן.
[סטודנטים] יש לי שאלה. כשאתה אומר להיכנס של n, אתה מתכוון ביחס לבסיס 2, נכון?
כן, אז זה דבר האחר.
אנחנו אומרים n יומן, ואני מניח שכשאני הייתי בתיכון
תמיד הנחית שהיומן היה בסיס 10.
כן, אז כן, להיכנס 2 בסיס בדרך כלל הוא מה שאנו משתמשים.
שוב, לחזור לחיפוש בינארי, אם אתה מחפש או
אלמנט ממש בסוף או האלמנט בהתחלה,
בגלל שאתה מתחיל באמצע ואז אתה זורק
לפי 1/2 אינה עומד בקריטריונים שאתה מחפש,
ואתה הולך למחצית הבאה והמחצית הבאה ובמחצית הבאה.
אם אני מחפש את האלמנט הגבוה ביותר במערך השלם מ'
אני הולך לחצות אותו ביומן ביותר של 1 מ'פעמים
לפני שאני סוף הסוף לבדוק ולראות שהאלמנט שאני מחפש
הוא בגודל או במדד הגבוה ביותר במערך,
ושייקח את היומן של n, היכנס של 1 מ'פעמים.
>> מיון בועות.
האם אתם זוכרים את אלגוריתם מיון הבועות?
קווין, האם אתה יכול לתת לי סיכום מהיר של מה שקרה באלגוריתם מיון הבועות?
[קווין] בעיקרון זה עובר את כל מה שברשימה.
הוא מסתכל על שני הראשונים.
אם הראשון הוא גדול יותר משניית אחת שהחילופים אותם.
לאחר מכן משווה אותו דבר שני ושלישי,, החלפות,
השלישית ורביעית, כל הדרך למטה.
מספרים גדולים יעקבו עד הסוף.
ואחרי לולאות אולם רבות שתסיים.
בדיוק, אז מה אמר קווין הוא שאנחנו נבדוק את המספרים גדולים
בועה עד סוף המערך.
לדוגמה, אכפת לך ללכת דרך דוגמה זו אם זה המערך שלנו?
[קווין] אתה תיקח את 2 ו 3.
3 הם יותר גדולים מ 2, כך שאתה להחליף אותם.
[נייט ח] נכון, ולכן אנחנו להחליפם, ולכן אנחנו מקבלים 2, 3, 6, 4, ו 9.
[קווין] ואז אתה משווה את 3 ו 6.
3 הם יותר קטנים מ 6, אז אתה משאיר אותם,
ו 6 ו 4, שהיית מתחלף איתם, כי 4 הם קטנים יותר מאשר 6.
[נייט ח] נכון, אז אני מקבל 2, 3, 4, 6, 9.
[קווין] ו9 הם גדולים יותר מ 6, ולכן תשאיר אותה.
ואתה הייתי חוזר על זה שוב.
>> [נייט ח'] האם אני עושה בשלב זה? >> [קווין] מס
ולמה אני לא עושה בשלב זה?
כי הוא נראה כמו המערך שלי הוא מסודר. אני מסתכל עליו.
[קווין] עובר על זה שוב ולוודא שאין יותר החלפות
לפני שתוכל להפסיק באופן מלא.
בדיוק, כך שאתה צריך לשמור על עובר ולוודא שאין החלפות
כי אתה יכול לעשות בשלב זה.
למעשה היה זה רק מזל, כמו שאמרת, שאנחנו בסופו
רק שאצטרך להחליט לעבור 1 עד ואנחנו מסודרים.
אבל כדי לעשות זאת במקרה הכללי אנחנו באמת צריכים לעשות את זה שוב ושוב.
ואכן, זו הייתה דוגמה למקרה הטוב ביותר האפשרי,
כמו שראינו בבעיה.
ראה שהמקרה טוב אפשר היה N.
עברנו זמן 1 המערך.
מהו מקרה הגרוע ביותר האפשרי עבור אלגוריתם זה?
[קווין] N ².
ומה זה נראה? מה היית מראה מערך כזה ייקח זמן ² n?
[קווין] [לא ברור] מיון.
בדיוק, כך שאם היה לי את המערך 9, 7, 6, 5, 2,
1 9 הייתם בועה את כל הדרך.
לאחר איטרציה 1 שנהיה לנו 7, 6, 5, 2, 9.
ואז היית בועה עד 7, 6, 5, 2, 7, 9, וכן הלאה וכן הלאה.
>> היינו צריך לעבור את כל המערך n פעמים,
ואתה יכול למעשה לקבל מעט יותר מדויק מזה
כי ברגע שאנחנו כבר עברנו 9 כל הדרך עד למקום האחרון האפשרי שלה
אנחנו יודעים שאנחנו לא צריכים להשוות מול שהרכיב שוב.
ברגע שנתחיל מבעבע 7
אנחנו יודעים שאנחנו יכולים לעצור ברגע נכון לפני 7 9
מאז אנחנו כבר לעומת 9 לזה.
אם אתה עושה את זה בצורה חכמה זה לא באמת, אני מניח, כל כך הרבה זמן.
אתה לא מתכוון להשוות את כל [לא ברור] הצירופים האפשריים
בכל פעם שאתה עובר כל איטרציה.
אבל עדיין, כאשר אנו מדברים על זה גבול עליון שאנו אומרים כי
אתה מסתכל n ² ​​השוואות לאורך כל הדרך.
>> בואו נחזור, ומכיוון שאנחנו מתחילים לקבל קצת קצרים בזמן
הייתי אומר שאתה בהחלט צריך לעבור את שאר טבלה זו,
מלא את כל זה.
לחשוב על דוגמאות. לחשוב על דוגמאות קונקרטיות.
זה ממש שימושי ומועיל לעשות.
למשוך אותו החוצה.
זהו הסוג של טבלה הכמו שאתה עובר במדעי מחשב
אתה באמת צריך להתחיל לדעת אלה על ידי לב.
אלה הם סוגים של שאלות שאתה מקבל בראיונות.
אלה הם מיני דברים שטוב לדעת,
ולחשוב על מקרי הקצה האלה, באמת להבין איך לחשוב על
ידיעה כי לבועה למיין את המערך הגרוע ביותר האפשרי
כדי למיין שבהוא אחד שזה בסדר הפוך.
>> מצביעים. בואו נדבר קצת על מצביעים.
בדקות האחרונות שיש לנו כאן
אני יודע שזה משהו יחד עם קובץ I / O שהוא די חדש.
כאשר אנו מדברים על מצביעי הסיבה שאנחנו רוצים לדבר על מצביעים
משום, אחד, כאשר אנחנו עובדים ב-C
אנחנו באמת ברמה נמוכה למדי בהשוואה לשפות תכנות המודרניות ביותר.
אנחנו למעשה מסוגלים לתפעל את המשתנים בזיכרון,
להבין איפה הם נמצאים ממש בתוכנו זכרון RAM.
לאחר שהלכת על מנת לקחת שיעורים של מערכת הפעלה שתראו
שזה, שוב, סוג של הפשטה.
זה לא באמת המקרה.
יש לנו זיכרון וירטואלי שמסתיר פרטים אלה מאתנו.
>> אבל נכון לעכשיו אתה יכול להניח שכאשר יש לך תכנית,
לדוגמה, כאשר אתה מתחיל לרוץ-תכנית צופן קיסרך
אני אעבור חזרה לiPad שלי ממש מהר,
כי בתכנית מאוד מתחילה, אם יש לך, יניח,
4 ג'יגה RAM של המחשב הנייד שלך,
אתה מקבל להפריש הנתח הזה, ואנחנו קוראים לזה זיכרון RAM.
וזה מתחיל במקום שאנחנו הולכים להתקשר 0,
והיא מסתיימת במקום שאנחנו קוראים 4 ג'יגה.
אני באמת לא יכול לכתוב. ואווה, זה פרוץ.
כאשר התכנית שלך מבצעת
מערכת ההפעלה חורטת את זכרון RAM,
והוא מציין פלחים שונים לחלקים שונים של התכנית שלך לחיות בה
כאן למטה האזור הזה הוא סוג של שטח הפקר.
כשאתה עולה מעט יותר כאן
יש לך את המקום שבו למעשה
הקוד לחיי התכנית שלך.
זה קוד בינארי בפועל, שלמעשה מקבל קובץ ההפעלה נטען לזיכרון
כשאתה מפעיל את תכנית, והוא חי בקטע הקוד.
וכפי שהתכנית שלך מבצעת את המעבד נראה בקטע הקוד הזה
כדי להבין מה היא ההוראה הבאה?
מהי השורה הבאה של קוד אני צריך לבצע?
>> יש גם קטע נתונים, וזה המקום בו אלה קבועי המחרוזת
לקבל מאוחסנים שאתה כבר משתמש.
ואז, קצת יותר למעלה יש המקום הזה שנקרא הערימה.
אנחנו לגשת לזיכרון לשם באמצעות malloc,
ולאחר מכן לכיוון חלקו עליון של התכנית שלך
יש ערימה,
וזה שבו אנחנו כבר משחקים ברוב של ההתחלה.
זה לא סולם או משהו.
הרבה זה מאוד תלוי מכשיר,
מערכת הפעלה תלויה, אבל זה יחסית איך דברים מקבלים הכו בעד.
כאשר אתה מפעיל תכנית ומצהיר על משתנה בשם x-
אני הולך לצייר קופסה אחרת למטה, וזה הולך להיות זכרון RAM גם כן.
ואני הולך לחפש.
אנחנו לצייר קווים משוננים, כדי לציין שזה רק קטע קטן של זכרון RAM
ולא את כולו כפי שאנו מציירים בראש.
>> אם אני מצהיר משתנה שלם בשם x,
אז בעצם מה שאני מקבל הוא מיפוי
שמאוחסן בטבלת הסמל של התכנית שלי
שמחבר את השם x לאזור זה בזיכרון שאני נמשך
ממש כאן בין הקווים האנכיים.
אם יש לי שורת הקוד בתכנית שלי שאומרת x = 7
המעבד יודע "אה, בסדר, אני יודע שחיי x במיקום זה בזיכרון".
"אני הולך להמשיך ולכתוב 7 שם."
איך זה לדעת מה מיקום זה הוא בזיכרון?
טוב, זה הכל נעשה בזמן הידור.
המהדר דואג להקצאה שבו כל אחד מהמשתנים מתכוונים ללכת
ויצירת מיפוי מיוחד או יותר נכון חיבור הנקודות
בין סמל ולאן היא הולכת, שמו של משתנה
ואיפה זה הולך לגור בזיכרון.
אבל מתברר שאנחנו באמת יכולים לגשת אליו בתוכניות שלנו גם כן.
זה מקבל חשוב כאשר אנחנו מתחילים לדבר על כמה ממבני הנתונים,
שהוא מושג שאנחנו הולכים להציג בהמשך.
>> אבל לעת עתה, מה שאתה יכול לדעת הוא שאני יכול ליצור מצביע למיקום זה, x.
לדוגמה, אני יכול ליצור משתנה מצביע.
כאשר אנו יוצרים משתנים מצביע אנו משתמשים בסימון הכוכבים.
במקרה זה, זה אומר שאני הולך ליצור מצביע לint.
זה בדיוק כמו כל סוג אחר.
אנחנו נותנים לו משתנים כמו y,
ואז להגדיר אותו שווה לכתובת, לכתובת.
במקרה זה, אנו יכולים להגדיר y להצביע על x
על ידי לקיחה את הכתובת של x, שאנחנו עושים עם אמפרסנד זה,
ואז הקים y להצביע עליו.
מה זה בעצם עושה הוא אם אנחנו מסתכלים על זכרון RAM שלנו
זה יוצר משתנה נפרדת.
זה הולך לקרוא לזה y,
ומתי הקו הזה של קוד מבצע
זה באמת הולך ליצור מצביע קטן שאנחנו בדרך כלל לצייר כחץ,
והוא מגדיר y להצביע על x.
כן.
[סטודנטים] אם x הוא כבר מצביע, היית פשוט לעשות
int * y = x במקום שיש אמפרסנד?
כן.
אם x הוא כבר מצביע, אז אתה יכול להגדיר 2 מצביעים שווים זה לזה,
ובמקרה זה לא הייתי נקודת y ל x,
אבל זה כל מה שהייתי מצביע על x כדי להצביע.
לדאבוננו, מחוץ לזמן.
>> מה הייתי אומר בשלב זה, אנחנו יכולים לדבר על זה מנותק,
אבל הייתי אומר להתחיל לעבוד דרך בעיה זו, # 14.
אתה יכול לראות שיש כבר קצת מלא בבשבילך כאן.
אתה יכול לראות שכאשר אנו מצהירים 2 מצביעים, int * x * y ו,
ושים לב שמצביע * הבא למשתנה היה משהו שנעשה בשנה שעברה.
מתברר שזה דומה למה שאנחנו עושים את זה שנה.
זה לא משנה איפה אתה כותב * כשאתה מצהיר על המצביע.
אבל יש לנו בכתב * לצד הסוג
כי זה עושה את זה מאוד ברור שאתה מצהיר על משתנה מצביע.
אתה יכול לראות שהכרזת על 2 מצביעים נותן לנו 2 תיבות.
כאן כשקבענו x השווה לmalloc
מה שזה אומר הוא הקצאת זיכרון בערימה.
התיבה הקטנה ממש כאן, המעגל הזה, נמצאת בערימה.
X הוא מצביע עליו.
שים לב ש-y עדיין לא מצביע על שום דבר.
כדי לקבל זיכרון לאחסון המספר 42 לx
היינו להשתמש במה סימון?
[סטודנטים] * x = 42.
בדיוק, * x = 42.
כלומר, פעל על החץ ולזרוק 42 שם.
כאן ושם סדר Y ו X יש לנו y מצביע על x.
שוב, זה בדיוק כמו שאמר קווין ושם סדר y שווה ל-x.
Y אינו מצביע על x.
למעשה, הוא מצביע על מה x הוא מצביע גם כן.
>> ואז סוף הסוף בתיבה האחרונה זה יש 2 דברים אפשריים שאנחנו יודעים לעשות.
אחת הוא שאנחנו יכולים לומר * x = 13.
הדבר השני הוא שאנחנו יכולים לומר, אלכס, אתה יודע מה הייתי יכול לעשות כאן?
אפשר לומר * x = 13-או
[סטודנטים] אתה יכול להגיד מה שint.
[נייט ח] אם זה מכונה משתנה int שאנחנו יכולים לעשות את זה.
כמו כן, אנו יכולים לומר * y = 13 משום ששניהם מצביעים לאותו המקום,
כדי שנוכל להשתמש במשתנה כדי להגיע לשם.
כן. >> [סטודנטים] מה היה נראה אם ​​אנחנו רק אומרים x int הוא 13?
שיהיה הכרזה משתנות חדש בשם X, שלא היה עובדים.
הייתה לנו התנגשות בגלל שאנחנו הכרזנו x להיות מצביע עד כאן.
[סטודנטים] אם רק הייתה הצהרה כי על ידי עצמו כיצד היה נראה כמו במונחים של המעגל?
אם היו לנו X = 13 אז יהיו לנו תיבה, ובמקום שחץ
יוצא מהקופסה היינו לצייר אותו כרק 13.
[סטודנטים] בתיבה. אוקיי.
>> תודה שצפית, ומזל טוב על חידון 0.
[CS50.TV]