>> [השמעת מוסיקה]
דאג LLOYD: בסדר.
סוג של נושא מוזר, נכון?
מספרי קסם.
מה איילה הוא מתכוון כשהוא מדבר על מספרי קסם?
ובכן, חלק מהתוכניות שאנחנו כבר נכתבו בCS50
עד כה היו כמה מוזר מספרים שנזרקו סוג של בהם.
אולי מסיבות שאנחנו עושים לא לגמרי מבין עכשיו.
לדוגמא, בבעיה מריו, ש כתרים הגובה של הפירמידה בגיל 23.
אנחנו במפורש אמרתי לך לא יכול ללכת גבוה יותר מ -23.
>> אבל מה 23 אומר?
ובכן, אם אתה קורא את spec בזהירות, אתה
אולי ראה ש סיבה שהכתרנו אותו בגיל 23
בגלל הגובה הסטנדרטי של חלון מסוף הוא 24.
ולכן אם יש לנו פירמידה להיות גבוהה יותר מזה,
זה יכול לעשות את הדבר המוזר הזה שבו הוא פועל מחוץ למסך.
ואתה יודע, מה עושה זה אומר בהקשר, נכון?
>> האם המשמעות של 23 ברור מייד למישהו שמסתכל על התכנית שלך
ואולי יש שונה חלון מסוף גודל?
כנראה שלא.
זה נראה כמו, אישור.
ובכן, מדוע שזה רק פחות מ 23?
באופן כללי, זה סוג של הרגל רעה בעצם
לכתוב קבועים לתוך הקוד שלך.
בכך, כאשר אתה בעצם לעשות לכתוב מתמדת לקוד שלך,
לפעמים הוא מכונה באמצעות מספרי קסם, וזה משהו ש
אנחנו בדרך כלל רוצים לנסות ולהימנע.
>> לדוגמא, בואו נסתכל בפונקציה פשוטה זו כאן.
ברור שאין נתונים סוג C בנקרא כרטיס או סיפון.
אז רק לשאת איתי.
זה קצת פסאודו קוד מעורב כאן.
זוהי פונקציה שנקראת להתמודד כרטיס שכנראה
לוקח סיפון כפרמטר שלה, ו פלט רצוני כרטיס בודד.
>> ואני עושה כאן משהו שבו אני יש לולאה שעוברת 0-52,
ואני עוסק כרטיס.
ובכן, יש לנו קסם מספר בכאן, נכון.
האם אתה רואה מה הוא מספר הקסם?
או יותר מכך, אתה לראות מה הבעיה כאן?
במיוחד אם זה הוא רק פונקציה אחת
בקובץ עצמו ב תיקייה המכילה
חבורה של שונה קבצים, כל אחד מהם
עושה עוד דבר לחפיסת קלפים.
אולי זה מערבב אותם, או עוסק יד של חמישה כרטיסים במקום כרטיס בודד.
>> האם אתה רואה מה ש בעיה יכולה להיות כאן?
האם אתה רואה את מספר הקסם אני כבר מוזרק לתוך הקוד?
זה 52, נכון.
>> כמו, באופן אינטואיטיבי שאתה בוודאי יודע, בסדר.
כמו סיפון סטנדרטי של כרטיסים מכילים 52 קלפים.
אבל בתכנית שלנו, זה פשוט סוג של מרחפים שם.
זה כמו פתאום יש 52.
>> דרך אחת לפתור את זה בעיה היא לעשות את זה.
אנחנו מאוד במפורש עכשיו קורא את גודל הסיפון כ52.
זה נותן לו קצת יותר אינטואיטיבי כלומר, כאשר ללולאה
בהמשך אנו אז אומרים, אני הוא פחות מגודל סיפון.
זה פשוט נראה טוב יותר מאשר לומר 52.
עכשיו זה עושה בעצם לפתור את הבעיה.
זה נותן כמה סמלי משמעות לקבועה.
אבל זה סוג של ממש להציג את בעיה נוספת
כי לא יכול להיות ברור מייד.
גם אם משתנה זה הוא הכריז globally--
אתה זוכר מה זה אומר כאשר אנו מצהירים
משתנה גלובלי לעומת מקומי?
גם אם אנחנו מכריזים על משתנה בעולם, מה אם יש
פונקציה אחרת ב החבילה של פונקציות שלנו
עסקה שעם מניפולציה כרטיס שלא במתכוון משנה גודל סיפון,
או שזה מגדיל אותו על ידי 1 או מקטין אותו על ידי 1.
זה יכול לאיית צרות, נכון?
עם סט במיוחד אם יש לנו עסק כרטיסים שבו דשדוש הסיפון המלא
נדרש.
אם גודל סיפון יורד על ידי 1, למשל, ל -51,
אנחנו לא ממש דשדוש כל הכרטיסים אולי.
אנחנו עוזבים אחד מהם החוצה.
וערך שאולי יכול להיות חזה או מנוצל על ידי שחקן רע.
>> C מספק מה שנקרא הוראת עיבוד מוקדמת, ש
גם נקרא מאקרו ל יצירת קבועים סמליים.
ואכן, יש לך כבר ראה הוראת עיבוד מוקדמת,
גם אם לא שמע את זה נקרא שעם #include.
זה עוד דוגמא למאקרו או הוראת עיבוד מוקדמת.
>> דרך ליצור קבועים סמליים, או מתן שם לקבוע
כך שיש לו יותר כלומר, הוא כדלקמן.
define #, שם, החלפה.
באמת חשוב בצד כאן באמת מהיר.
אין לשים פסיק ב סוף #defines.
אז זה define #, שם, החלפה.
>> כאשר התכנית שלך היא הידור, מה שקורה בפועל
הוא מהדר אם הולכים לעבור את הקוד שלך
ולהחליף את כל מופעים של המילה "שם" עם כל מה שאתה
לשים כתחליף.
בדומה לכך, אם #include הוא סוג דומה לשל העתקה והדבקה,
אז define # הוא סוג של דומה לחיפוש והחלפה,
אם אי פעם השתמש בתכונה שב תכנית לעיבוד תמלילים, למשל.
>> כך למשל, אם אני define # pi כ3.14159265,
אם אתה טוב יותר מבחינה מתמטית פתאום נוטה ואתה
לראות 3.14159265 מעופף סביב בקוד שלך,
אתה כנראה יודע שזה מדבר על צרכן.
אבל אולי אנחנו יכולים לתת את זה משמעות סמלית יותר קטנה.
ואנחנו יכולים לומר במקום define # pi כפה מלא כי מספרים
כי אני לא הולך לשמור קריאה שוב ושוב.
>> ומה יקרה אז ב לקמפל זמן הוא כאשר התכנית היא
, הדבר הראשון שנערך ש שיקרה הוא שזה ילך דרך
והוא יחליף בכל פעם הוא רואה P הון, אני הון,
זה ממש יהיה להחליף אותו ב 3.14 וכן הלאה, כך שאתה
לא צריך להקליד אותה בכל זמן בעוד התכנית שלך עדיין
יש את הפונקציונליות שאתה מצפה, כי אתה עובד
עם מניפולציה, הכפלה, החלוקה, מה שזה לא על ידי צרכן.
>> אתה לא מוגבל לזה החלפה למספרים בלבד.
לדוגמא, אני יכול define # כמובן כCS50 המחרוזת.
במקרה זה, כאשר תכנית עוברת הידור,
define # יעבור קוד, להחליף בכל פעם
הוא רואה "כמובן" עם CS50 המחרוזת.
>> תוכל להבחין כאן גם כי אני לעתים קרובות
define # כולי מוגדר סמלי קבועים, כביכול,
תמיד נמצא בכל כמוסות.
זה כנס.
זה לא נדרש.
הסיבה בדרך כלל אנשים ישתמשו כל הבירות כאשר הם #defining
רק כדי לעשות את זה ממש ברור ש אלמנט מסוים של הקוד שלי
הוא קבוע מוגדר.
אם זה היה באותיות קטנות, זה אפשרי ש זה עלול לבלבל אותם עם משתנה.
וזה כנראה לא דבר טוב לעשות.
>> אז זה בפרט הפתרון הוא הרבה יותר טוב
יותר גם של קודמיו.
אם אני גודל סיפון #define הראשון 52, ולאחר מכן עכשיו השימוש שלי של 52, או גודל סיפון כאן,
הוא הרבה יותר אינטואיטיבי והרבה יותר בטוח.
אתה לא יכול לתפעל קבוע.
אתה לא יכול להגיד 52 פלוס פלוס.
זה לא הולך להמיר אותו ל -53.
אתה לא יכול לשנות 52 למשהו.
>> באפשרותך לשנות משתנה הערך שלו הוא 52,
שהיה התיקון הראשון שהיו לנו בעבר.
ואתה יכול להגדיל משתנה של -53.
אבל אתה לא יכול להגיד 52 פלוס תוספת ו יש שהופכים פתאום ל52 53.
52 הוא תמיד 52.
ואז אתה לא יכול לשנות בטעות גודל סיפון כאן על ידי מניפולציה זה,
>> צד טוב נוסף השפעה אם כי זה
כי אתה מודע לכך שלא כל המדינות ברחבי העולם
להשתמש חפיסת הקלפים בגודל 52?
לדוגמא, זה ממש נפוץ ב גרמניה להשתמש בגודל חפיסת 32,
שבו הם להפשיט את חלק של כרטיסי הערך נמוכים יותר.
ובמקרה הזה, אני רציתי נמל החבילה שלי
של פונקציות העוסקות ב מניפולציה כרטיס לגרמניה.
אני יכול בערכאה הראשונה ש הראה, צריך ללכת ולהחליף
כל המופעים של 52 בקוד שלי עם 32.
>> אבל כאן, בגודל סיפון אם אני define # 32 בחלקו העליון של הקוד שלי,
אם אני צריך לשנות את זה, אני יכול פשוט ללכת ולשנות את זה דבר אחד.
הדר מחדש את הקוד שלי, וכל פתאום זה מתפשט דרך.
למעשה, אנחנו יכולים לשנות את הסיפון גודל לכל ערך שאנחנו רוצים.
>> האם אני יכול לעניין אותך ב משחק של טנדר גודל סיפון?
>> אני דאג לויד.
וזה CS50.