[Powered by Google Translate] [שבוע 3]
[דוד י מלאן - אוניברסיטת הרווארד]
[זה CS50. - CS50.TV]
תן לי לכוון אותנו לכיוון שבו הפסקנו בפעם אחרונה,
שהתחיל לחשוב קצת יותר על תחביר
ומנסה לחשוב קצת פחות על כל הפרטים הקטנים
זה לוקח קצת זמן להסתגל לכך רחוק במונחים של פסיק
וסוגריים וסוגריים מסולסלים,
להתחיל לקחת דברים קצת לרמה המושגית גבוהה
כך שהבעיות שאנחנו עכשיו להתחיל לפתור בשבועות הקרובים
הולכים לערב הרבה יותר בבעיות מושגיות ברמה גבוהה יותר
וקצת פחות בתחבירי כמו שאתה מקבל הרגליים רטובות
והידות מלוכלכים עם חלק מהתחביר מהשבועות האחרונים.
>> אז זוכר ששבוע שעברנו הציג את הרעיון הזה של מערך.
ומערך באנגלית ניתן לתאר מה? >> [תגובת תלמיד לא נשמעה]
סליחה?
אוסף? >> [תגובת תלמיד לא נשמעה] >> אוקיי, טוב.
אוסף של פריטים. אז ראה את מערכים בלגרד.
אם קרה לשימוש עבור pset 0 אחת מרשימותיו של Scratch שאתה יכול לגרור דברים
כמו תפוזים ובננות ל, מלאי של מינים,
זה כמו סוג של מה שמערך הוא.
ואז יותר מבחינה טכנית, בהקשר של מחשב עצמו,
מערך הוא פשוט נתח רציף של זיכרון.
במילים אחרות, יש לך שני בתים, ולאחר מכן בתים אחרים, ואז בתים אחרים, ואז בתים אחרים,
אם היית מצייר הבתים האלה בתמונה ו,
הם יהיו גב אל גב אל הגב אל גב. זה מה שאנחנו מתכוונים ברצף.
>> אז זה מספר בית 1, ואז 2, ולאחר מכן 3.
זה לא אומר עד כאן, כאן, כאן למעלה, כאן.
מערך הוא גוש רציף של 0 או יותר בתים.
אז מה שהם שימושיים ל?
זוכרים שהיו לנו זה סוג של דוגמה מאולצת של ציוני בחנים של אנשי אחסון בתכנית
כדי לחשב ממוצע החידון שלך לקורס מסוים,
ולהיזכר שאנחנו יכולים להתחיל לכתוב תכנית שבאמצעות הכרזת quiz1 משתנה.
ואז נהיה לנו עוד משתנה נקרא quiz2.
אבל אז, אם היו 3 בחנים בכיתה זו, quiz4.
או אם היה חידון שבועי, זה יהיה quiz5, quiz6, quiz7.
אז היית צריך כל אחד מהמשתנים הללו הכריזו בתוך ראשיים
או במקום אחר בתכנית שלך,
והבעיה עם גישה הזאת, קלה למרות שזה רק כדי להעתיק ולהדביק,
האם זה הופך מסורבל פשוט מהר מאוד.
חלילה לך למעשה יש 30 או 50 חידוני חידונים.
אם זה כמו חידון יומי תיכון סגנון פופ,
אז אתה רק צריך גיחוך רשימה ארוכה של משתנים שהצהירו,
וזה יוצא פשוט מהר מאוד מכלל שליטה.
זה מכוער, זה קשה לשמור על זה כל כך הרבה יותר קל לעשות טעות דפוס
אם אתה מקבל מספר 1 הוקלד בטעות איפשהו בתכנית שלך.
>> אז הציג את הרעיון של מערך במקום.
ואזכור שאנחנו יישמנו תכנית זו על ידי עושה משהו קטן כזה.
תן לי ללכת לספריית יום שני 3 מקורו של היום
ולפתוח את המערך, שראינו בפעם אחרונה.
ואף על פי שהיו כמה טריקים חדשים C כאן,
ביניהם את הרעיון קבוע,
זוכר שהכרזנו צף מרובים למעשה באמצעות תחביר זה:
מצוף, ואז את השם של המשתנה, ואז השתמשנו בסוגריים מרובעים ממש בפעם הראשונה,
ומה שאנחנו עשינו בתוך הסוגריים המרובעים האלה בצורה יעילה היה לשים מספר.
אבל במקום לשים את המספר, שמתי את המילה הזו מהוונת, חידונים.
ומה היה המניע להצבת מילה מהוונת כמו חידונים
ולאחר מכן משתמש בתחבולה של 17 קו כאן כדי לתת למעשה כי מספר?
מה היה המניע לשם? כן.
>> [תגובת תלמיד לא נשמעה] >> בדיוק.
אם אנחנו רוצים לשנות את הערך ש2, יש לנו רק לשנות אותו במקום 1
משום לשקול - אני אפילו לא זוכר מה התכנית הזו עשתה בדיוק,
אבל אם אתה רק לעלעל בו אתה רואה שעשועונים, חידונים.
אתה רואה שעשועונים, חידונים כאן למטה יותר.
אז אם לא היה לנו את זה קבוע, זה שימוש חד להגדיר,
היינו הקלדתי 2, אז 2, ולאחר מכן 2, אז 2, וזה בסדר. זה יהיה בדיוק נכון.
אבל יניח כי בשנה הבאה יש לנו 3 בחנים בCS50.
אז אני צריך ללכת ולעדכן את הקוד, יש לי להדר אותו,
אבל הבעיה היא שאם אני עושה משהו מטופש, כמו שאני מתעלם אזכור 1 מתוך 2
ותשכח לחבר 3, כל התכנית יכולה מאוד לשבור.
אז אנחנו רק מחפשים צרות.
>> אז הרעיון של קבוע הוא על כל פיסת הפקטורינג את החלק מנתונים,
אם זה חוט או char או מצוף או משהו כזה,
ומצהיר על זה מקום 1, כך שאתה יותר בקלות יכול לשנות את זה בעתיד.
וזה גם, בכנות, קצת יותר קל לקריאה, כי אם אתה רק חושב על זה עכשיו,
זה חידונים, או שאנחנו יכולים אפילו לשנות את שמה משהו כמו NUMBER_OF_QUIZZES
או משהו מפורש יותר.
הקוד פשוט הופך להיות קצת יותר ברור על מה שהוא עושה,
ואתה תוהה קצת פחות מה מספר 2 שעלול לקרות למתכוון.
אז קבוע לא היה מה לעשות עם מערכי יסוד.
המערך הוצג בדרך של הסוגריים המרובעים האלה.
>> אז שם לב כי בקו 23 ששואלים את המשתמש ", מה היו ציוני הבחנים שלך?"
אז אנחנו רק צריכים לולאה זה שככל הנראה שואל את המשתמש לכיתותיהם. איך?
זה סובב 0-2. ואני אומר, כי 2 בחנים בכל הכמוסות הוא כיום 2.
אז זה סובב מ 0 עד 2 ואז זה מדפיס את חידון משהו של משהו #,
ואז הוא משתמש בGetFloat כדי לקבל ערך מהמשתמש.
אז מבחין זו היא רק חתיכה האחרת החדשה של תחביר מיום רביעי שעבר.
אם אתה רוצה לאחסן משהו במיקום מסוים במערך,
שוב להשתמש בסוגריים המרובעים.
>> אז יש קצת הדיכוטומיה כאן.
בפעם הראשונה שתשתמש בסוגריים המרובעים
אתה משתמש בו כדי לציין עד כמה גדול אתה רוצה להיות במערך.
אבל הקשר זה ליד איפה שאנחנו שוב להעסיק סוגריים מרובעים האלה
משמעות דבר הוא שבו במערך שאתה רוצה לשים קצת ערך?
וכאן ההבחנה ניתן להסיק מהקשר.
שים לב שיש לנו כאן סוג נתונים, ולאחר מכן יש לנו את שמו של משתנה,
אז יש לנו הסוגריים המרובעים שלנו עם מספר בפנים, פסיק. זה הכל.
אז זה הכרזה.
זה ממש כאילו שעשינו משהו כמו לצוף grade1; לצוף grade2;
אבל שוב, זו חל מהר מאוד להרבה יותר מדי להעתיק, להדביק,
אז במקום שאנחנו פשוט פשטנו אותו ככזה,
מה שאומר שמעתה יש לנו כיתה שניתן לאחסן בסוגר 0,
יש לנו כיתה אחרת, שיכול להיות מאוחסנת ב1 הסוגר
אבל מה אם אני לפשל ו, למשל, לולאתי מרחיקה לכת -
למשל, אני עושה את זה פחות או שווה ל,
שההיזכרות הייתה המקור לבאג קודם -
אשר למעשה אומר שעל חלק איטרציה מקרית שלישית של לולאה זה
אני משתמש בסוגריים 2. ביעילות, מה שעלול לקרות כאן? סליחה?
[תלמיד] זה הולך להיות מוחלף. >> האם זה הולך להיות מוחלף?
מה יהיה מוחלף?
זה ממש לא אומר להחליף את מה שהיא במיקום 2 עם ערך ההחזרה של GetFloat.
אבל הבעיה היא מה גודל המערך בנקודה זו בסיפור?
[תגובת תלמיד לא נשמעה] >> המערך הוא עדיין רק בגודל 2
בגלל המערך, כמו כל משתנה, הוכרז ראשון, לפני שהשתמשנו בו,
ואנחנו שצוינו כאן בגלל זה תמידי שיש לי 2 ציונים שאני הולך לשים.
>> אבל זכרו, מדעני המחשב מתחילים לספור מ 0.
אם כך, המקום הראשון שבמערך הוא סוגר 0.
המיקום הבא הוא 1. הדבר הזה הוא מעט שבמעט רחוק מדי לצד.
אז במילים אחרות, אם אני ממש היה מערך זה -
ותראה לי כמה טוב זה משתף פעולה כאן בשבילנו -
אם יש לי מערך שאני פשוט נמשך כדלקמן
ואני כבר הוקציתי שטח עבור 2 אלמנטים, אני יכול לצייר את זה כאילו זה בזיכרון
שם בד לבן גדול זה.
זה רק זכרון RAM יש לי במחשב שלי, חלטורה של RAM, 2 GB של זכרון RAM, מה,
אבל 2 הקופסות האלה עכשיו בנפרד מייצגות לצוף, 32 סיביות.
אז אם אני שם מספר 1 כאן כמו 1.0, אז שמתי מספר אחר כאן כמו 3.2
אבל אז אני עושה סוגר 2, זה כמו לשים משהו כאן.
וכפי שהתמונה מרמזת, אין שם כלום.
זה כמו סוג של שטח ההפקר בגלל שלא שאלתי את מערכת ההפעלה
לתת לי חידון שלישי.
אם אני רוצה שעשיתי חידון שלישי, אני היה צריך להיות מחשבה תחילה
לשאול את מערכת הפעלה לזה על ידי הכרזת חידונים להיות לא 2
אלא במקום שווה 3.
>> אז במילים אחרות, תמונה שיש לנו ביעילות ביד נראית כמו זה כאן.
זה שוב הוא שטח ההפקר. לא כדאי לנסות לכתוב ערכים כאן.
אבל שוב, כי מדעני מחשב לספור מ 0,
כאשר אנו מדברים על המיקום הזה במערך, שאמור להיות מיקום 0,
זה אמור להיות מקום 1, וזה אפילו לא קיים
בגלל שאנחנו בקשנו את מערכת ההפעלה רק 2 מקומות כאלה.
אז אלו מכם עם ניסיון בתכנות מראש משפות אחרות
אולי יודע שזה לא תמיד המקרה עם מערכים או דברים הנקראים וקטורים.
במקום זאת, אתה יכול פשוט לשמור על ההוספה וההוספה והוספת דברים למערכים,
אשר, למען האמת, היה לנו את היכולת הזאת בלגרד ובכל זאת נראים שאנחנו נותנים אותו כאן
כי עם C אתה מתכנת הרבה יותר מפורש.
זה רק אתה והמחשב עכשיו, והמחשב הוא רק הולך לעשות
מה שאתה אומר לו לעשות.
אז אם אתה אומר את זה רק כדי לתת לך 2 צף בדרך של הקו 22 כאן,
זה כל מה שאתה הולך לחזור ממערכת ההפעלה: מקום ל2.
>> כך יותר ויותר את התוכניות שלך הולכות מדי פעם להיות מרכבה בכל קשורים למערכים.
זה פשוט סוג של האופי של החיה לפיו כל אחד מאיתנו עלול לטעות,
ובשלב מסוים אתה יהיה מדד סביר מאוד מעבר לגבול של המערך שלך.
וזה רק דרך מפוארת שלך אומר נכנס משהו סוגר
ומשהו היה פשוט גדול מדי של מספר. הלכת מעבר לגבולות של המערך שלך.
אבל כרגע הוא זה הפוך.
שאר התכנית הזו באמת אין שום יסוד לעשות עם מערכים.
זה הכל רק על חלק חשבון פשוט לממוצעי מחשוב.
אז יש לנו כאן בזה ללולאה כאן קודם סכום משתנה בשם שאנו לאתחל ל 0.
אז שנעמיק בין 0 עד 2 שוב ונוסיף לכך משתנה הסיכום
כיתת i, כך הסוגר 0 אז 1 הסוגר.
ואז, כפי שהיית עושה בבית הספר יסודי על מנת לחשב את הממוצע,
אנחנו פשוט לוקחים את הסכום הזה, מחלק אותו במספר הכולל של חידונים,
ואז למען סדר טוב אנו קוראים לפונקציה כאן נקראת סיבוב.
>> עכשיו, כהערת אגב, מה סיפור עם int סוגריים זה על קו 34?
אולי זה צריך לבוא כבר בקטע, לא ממש דבר על זה באופן רשמי כאן,
אבל מה הוא int זה בparens כנראה עושה? >> [תגובת תלמיד לא נשמעה]
כן, זה מתייחס ליציקה או ליהוק שחקנים,
מה שאומר שלוקח נתונים מסוג 1 והמיר אותו למשנו.
אתה לא יכול לעשות את זה עם כל סוגי הנתונים כי לפעמים זה יהיה קצת מוזר.
אבל במקרה הזה, אם ערך ההחזרה של סיבוב הוא מצוף
כי, אחרי הכל, אני לוקח את מצוף וחלוקתו על ידי מספר כמו 2,
אני הולך לחזור לצוף.
אבל אנשים בבית ספר יסודי לא ממש רוצים לדעת שהממוצע שלהם היה 93.4
משום שהם מבינים שהם היו אי פעם כל כך קרוב לנקודה ש95 עיגול.
>> אז אנחנו רוצים במקום להשתמש int לעגל כולם int הקרוב ביותר,
אשר במקרה זה הולך להיות 94 עם לא נקודה אחריו.
אז זה פשוט טריק מתמטי.
ואנחנו נחזור לרעיון הזה של יציקה כי זה יהיה השלכות,
אם לא גילה כבר, לכל בעיה להגדיר 2.
אז מערך ואז, אתה יכול לחשוב עליו - זה הולך לגרום לי לחייך כל היום.
זה נראה כאילו זה אם אתה מצייר תמונה של זה,
אבל המפתח הוא שהגודל הוא גם נבחר על ידך
כאשר אתה מבקש אותו ממערכת ההפעלה.
כל שאלות ואז על מערכים? כן.
[שאלת תלמיד לא נשמעה]
אה, שאלה טובה.
השאלה היא מה קורה ל0 null במערך? זה לא קיים בהקשר זה.
שקיים רק בהקשר של מחרוזות, שאנחנו עומדים להגיע לרגע.
אבל למערך, כמו במקרה הזה, כל מה שתקבל זה מה שאתה שואל את מערכת הפעלה ל.
>> ואגב זה, שמא זה יהיה ברור,
אני כל זמן אומר לך לשאול את מערכת ההפעלה, לשאול את מערכת ההפעלה.
מערכת הפעלה, כפי שאתה בוודאי יודע, היא Mac OS, Windows, Linux.
כשאתה מתקשר פונקציות כמו GetFloat
או שאתה הגדרה משתנה כמו ציונים,
בסופו של היום אתה למעשה שואל מישהו אחר כדי לתת לך זיכרון ש
כי אנחנו שואפים כמתכנתים
אין לי מושג איך בעצם לקבל גישה פיזית לזיכרון.
אבל מישהו עושה: מערכת ההפעלה.
אז מלבד הצגתנו עם אייקונים יפים ותפריטים ותיקיות וכמו
שאתה רואה על שולחן העבודה שלך, בין אם מק או PC,
מערכות הפעלה גם לעשות דברים השיגרתי ברמה הנמוך,
דברים הטכניים ביותר לניהול ג'יגה
או 2 ג'יגה בייט של זיכרון שיש לך, ניהול המעבד שיש לך, וכן הלאה.
לכן, כאשר אתה כותב קוד,
אתה באמת משדל במערכת ההפעלה שלך במובן הזה.
אני הולך לעשות כדי למזער את זה. בסדר.
>> שאלות אחרות על מערכים?
לא? אוקיי.
אז המעבר באופן טבעי ממערכים הוא בעצם לנושא שזה קצת מוכר.
והסתכלנו לו בחטף בפעם האחרונה זה יותר מדי.
זו הייתה דוגמא מחרוזת מיום רביעי.
למשל מחרוזת זו הייתה תכנית די פשוטה,
ואני באמת שפשטתי אותה על ידי כמה שורות למטרות של היום.
כל שהוא עושה בקו 19 הוא לקבל מחרוזת מהמשתמש, מאחסן אותו במשתנה בשם זה.
ואז בשנת 22 והלאה קו זה כנראה שאופי הדפסת המחרוזת 1 בכל שורה.
אבל איך עושה את זה?
אנחנו מצהירים שאני משתנה, הגדרתי אותו שווה 0,
וזה הופך להיות רגל ישנה עכשיו.
אנחנו לא ראינו את זה עד יום רביעי, אבל אתה יכול להסיק מסוג של שמה
strlen מחזיר רק מה שכאשר ניתנים ים? אורכו של החוט.
אז אם אני מעביר אותה מחרוזת, במרכאות דוד,
זה קורה בתקווה לחזור אליי מספר 5 בגלל הדוד.
אז זה את מטרתו בחיים היא לקחת מחרוזת, אם הקוד קשה על ידך
או במקרה זה מחובר לחשמל כמשתנה, כטיעון,
וזה דמוי מה אורכו של חוט שהוא.
>> אז הנה עכשיו אנחנו לשאול כמה סימון מדוגמא החידון הקודמת.
אין לזה שום קשר לצפים, יש מה לעשות עם חידונים,
אבל מסתבר ששקר לבן הקטן אנחנו כבר אומר לך מאז שבוע 1
הוא שמחרוזת אינה קיימת באמת בג
מחרוזת בסוף היום היא באמת רק מערך.
זה מערך של בתים, כך בתים, בתים, בתים, בתים, שההיזכרות היא רק 8 ביטים,
כך נתח של זיכרון, נתח של זיכרון, נתח של זיכרון, נתח של זיכרון.
ואת האמצעי שבעזרתו מחרוזת מיושמת
הוא על ידי הצבת התו הראשון כאן,
אז הנה, אז כאן, אז הנה, גב אל גב אל גב בזיכרון של המחשב.
אז אם אתה רוצה כדי לאיית מילה כמו שלום, היית שם את הדמות H 1,
אז E, אז L אז L, אז O - 5 תווים בסך הכל - אי שם בזכרון RAM של המחשב שלך.
אבל פרט המפתח כאן הוא שהם הולכים להיות גב אל גב אל גב אל גב,
ממש ליד אחד את השני.
כשאני אומר של [i], מה באנגלית זה נותן לי?
מה זה [i] מייצגת במקרה זה? כן.
>> [תלמיד] אופי ith במחרוזת. >> בדיוק. אופי ith במחרוזת.
כעת, אני עומד להתחיל ב 0 לפי ללולאה כאן,
אבל זה בסדר, כי הכל מתחיל לספור מ 0.
אז נ [0] הולך לייצג את מכתב H במילה כמו שלום,
נ [1] הולך לייצג מכתב כמו E במילה כמו שלום, וכן הלאה.
ומה נדמינו שאנחנו עושים בכל איטרציה של לולאה זה
באופן זמני לאחסון אופי ith במשתנה בשם ג, וזה רק char,
ואז אתה מדפיס את ג
כך שבסופו של היום מה התכנית הזו עושה הוא בא.
אם אני הולך לספריית המקור ואני עושה string1 ואני הולך קדימה ולהפעיל string1,
ואז אני מקליד מילה כמו שלום, זן, כל שהוא עושה זה אופי זה 1 בכל פעם.
>> אז יש הזדמנות לחידוד כאן.
אני סוג של עושה יותר עבודה, למרות שזה יותר ברור, אולי בדרך זו, ממה שצריך.
איזה שורת הקוד כאן יכול כנראה אני זורק לגמרי? כן.
קו 24. בקו 24 אני מכריז משתנה.
אני מאחסן את האופי של ה-i של בזה, אבל אז אני משתמש כאן ג.
אז אני משתמש בג, ולכן אני מרגיש כאילו אני לא יכול פשוט לזרוק את הקו 24 משם.
[הערת תלמיד לא נשמעה] >> בדיוק.
אז כשזה מגיע למדבר על העיצוב של תוכניות,
תבחין פישוט זה קל של הקוד, שהוא פשוט קריא כ,
אבל מבין שזה רק משתנה, סוג הנתונים שלו הוא מערך,
כך זה [i] היא פשוט הולך באופן מיידי לחזור לאופי ith שבמחרוזת.
ואם אתה רוצה לפרסם את זה, זה בסדר.
אתה פשוט צריך להשתמש בג% כי אתה לא מדפיס מחרוזת,
אתה מדפיס תו במחרוזת, וגם את זה יש השפעה של הדפסת תו ה-i.
ולהיזכר באמת ההבדל היחיד משבוע שעבר עם שימוש printf
הוא שבעוד שבשבועות האחרונים היינו עושה משהו סופר פשוט
כמו מציין מיקום של% לאחר מכן את השם של מחרוזת כאן,
עכשיו אנחנו צוללים בקצת יותר עמוקים מתחת למכסת המנוע ואומרים,
לא להדפיס את המחרוזת; להדפיס תו הבודד בו.
>> אז אנחנו יכולים לעשות משהו שונה קצת פה בגלל שיש אחר 1 - לא באג
כי תכנית זו היא נכונה, אבל אני עושה משהו טיפשי
שמוזכר בקצרה ביום רביעי.
אבל במחשבה לאחור, איך העיצוב של תכנית זו ניתן לשפר עוד יותר? כן.
[תגובת תלמיד לא נשמעה] >> אה, טוב.
אז זוכר שהצגנו משתנה שני נקרא n פעם אחרונה,
שנראה שסותר את עצמנו, כי המטרה שלי לפני שנייה
היה פשוט לזרוק משתנה כמיותר,
אבל לזכור כי ביום רביעי אנחנו באמת עשינו את זה.
אני שיניתי ללולאה בעצם יש פסיק פה, אז n = strlen,
ולאחר מכן לכאן עשיתי i <n, אז עשיתי את שלי במרווחים.
מהו הרווח הבסיסי שאני משיג על ידי שינוי האתחול שלי לזה
והמצב שלי לעכשיו זה? >> [תגובת תלמיד לא נשמעה] >> בדיוק.
אני לא נזכרתי strlen שוב ושוב ושוב, כי זוכר איך לעבודות לולאה.
גם אם הם מתחילים לקבל יותר מסובך למראה,
זוכר שהדבר לפני הפסיק הראשון הוא האתחול, המתרחש פעם אחת.
התנאי, כמובן, הוא באמצע,
וזה מקבל נבדק בכל פעם שאתה עובר את הלולאה.
>> אז זה סוג של טיפשים שמבקש מחשב את אותה השאלה שוב ושוב -
מה אורכו של שלום? מה אורכו של שלום? מה אורכו של שלום? -
משום שכפי שנראים היום וביום רביעי, זה בהחלט הולך לקחת זמן,
וזה לא שימוש טוב מאוד של זמן, כי כדי להבין את האורך של מחרוזת
למעשה לוקח קצת מאמץ.
זה אינו מיידי, כפי שהוא בשפות מסוימות.
זאת על ידי שינוי זה ל n, המחיר שאני משלם הוא מה?
אנחנו רואים תחלופה כאן.
אני יכול לחסוך זמן על ידי לא שואל את אותה השאלה ארורה שוב ושוב,
אבל זה הולך לעלות לי משהו, וזה מה?
>> [תלמיד] אתה מאבד כמות מסוימת של זיכרון. >> בדיוק. זה הולך לעלות לי קצת זיכרון.
אז במקרה הזה זה עולה לי מה?
עוד 32 ביטים כי N הוא רק int, כפי שמשתמע מהמילה int כאן.
אבל האם זה בסדר?
למען אמת, זה כנראה בסדר, כי אם אתה חושב על זה,
עוד המחרוזת היא, יותר זמן אני הולך להיות בזבוז
בגלל strlen הולך לחטוף קרא שוב ושוב ושוב
לכל איטרציה של הלולאה.
ובימים אלה, Mac שלי יש 2 הופעות של RAM, בימים אלה 4 הופעות של RAM לפעמים.
אני חושב שאני יכול להרשות לעצמו 4 מתוך הבתים האלה דווקא כדי לזרז את העניינים.
אבל זה הולך להיות תחלופה ונושא ממש בתכנות ובמדעי מחשב
של לא באמת מקבל שום דבר בחינם.
אם אתה רוצה לשפר משהו כאן, יש לך לשלם על זה ביד השנייה היא איכשהו.
מקום כתלות בזמן במקרה זה.
>> אז שכל זה מוביל למעלה אל משהו מסתורי כזה,
אשר, כפי שאתה בוודאי לגלות את זה עכשיו, בעצם אומר?
[תגובת תלמיד לא נשמעה] >> כן, אז זה הוא, הקפד לשתות השוקו שלך,
למעשה באמצעות אלגוריתם שנקרא ROT13, ROT 1-3,
שרק אומר לסובב את כל האותיות 13 מקומות,
מה שאומר שייקח ולאחר מכן להוסיף 13 לזה וללכת נקודה, נקודה, נקודה
כל הדרך למכתב ה -13 משם, לעשות את אותו דבר עבור B ו-C ולפיתוח וכן הלאה.
אז אם אנחנו באמת להמיר את זה כאן באמצעות משמרת של 13 מקומות ו,
אנו נחזור למה שהיה קטן ראלפי, ש, הקפידו לשתות השוקו שלך.
אבל עכשיו לבעיה להגדיר 2, במהדורה הסטנדרטית לפחות,
יש לך לסוג של אין זה enciphering עצמך,
ויש לנו איכשהו לקחת בקלט כמו זה ולהצפין אותו, או לפענח אותו.
>> אז מי אלה הסוג של היסודות מוביל אותנו לזה הזדמנות?
בואו נסתכל על דוגמה שלישית זו כאן.
קודם כל, זה נקרא ASCII. מה ASCII אין להפנות לראש?
קוד תקן אמריקאי למחלף מידע,
אשר היא דרך ארוכה באמת לומר את מה? מה הוא ASCII?
[תגובת תלמיד לא נשמע] >> מה זה? >> [תלמיד] מפת תווים. >> מפת תווים.
זה פשוט ממפה מספרים לאותיות משום שהעולם יש סטנדרטי
מה מספרים מייצגים את מה אותיות, כך שכל אחד מאיתנו יכול להשתמש במחשבים
והתוכניות שלנו בכל הן רק תואמות כשמדובר להדפיס את הדברים על המסך.
אז לזכור כי 65 קורים לייצג, 97 קורים לייצג אותיות קטנות.
וכך התכנית הפשוטה הזה כאן ASCII היא ניצול של העובדה -
כי העולם יודע שהון הוא 65 - וזה פשוט מדפיס את המיפוי.
>> אז לפני שאנחנו צוללים לתוך הקוד הזה, תן לי במקום לפתוח את חלון מסוף.
תן לי ללכת קדימה ולעשות ASCII, ואז בואו פשוט להפעיל את הדבר הזה רק כדי לקלקל את הפלט.
וזה רק עושה את זה: תרשים ממש גדול שפשוט אומר לי את כל הקודים השונים
לכל אותיות השונות.
אז תכנית סופר פשוט, אבל לא היה לי קשה לקוד 52 קווים אלה של פלט:
26 אותיות רישיות, 26 אותיות קטנות.
במקום זאת, עשיתי את זה תכנותי עם כמה לולאות.
שים לב מה שעשיתי כאן.
אני חוזר על עצמו מהוא 65 בעד 65 + 26 כי רציתי להדפיס 26 אותיות
באותיות האנגליות, אני + + בכל איטרציה, ועכשיו שמתי לב זה שוב.
זה ההישנות של ליהוק שחקני ידידנו
לפיו אתה להמיר סוג 1 נתונים למשנו
כי מה שאני רוצה לעשות בתכנית מסוימת הזאת?
אני רוצה לספור מספרי כי ככה אני גדלתי ספירה - 65, 66, 67, וכן הלאה -
אבל אני לא רוצה להדפיס רק את המספרים.
אני רוצה להדפיס את המכתב ואחריו את המספר.
אני רוצה להדפיס: מספר, B: מספר, אבל אני יכול לעשות את זה עם אותו משתנה מדויק.
אז להדפיס את ג% כמראה מקום לאופי,
ד% כמראה מקום לספרה או מספר.
ואז מה אני אחבר עבור 2 המציינים האלה?
אני תחילה חבר במקביל האופי שלי, ואז אני אדפיס לי את עצמו.
>> אז הבחנת בכך גם פשוט עובד.
בדיוק כמו שאני יכול להטיל ממצוף לint
על מנת לעבור ממספר אמיתי למספר שלם,
כאן אני יכול ללכת מן int לchar, שזה קצת מוזר -
לא ממש מפה אל העולם האמיתי - אבל במחשבים
char הוא רק מספר מתחת למכסת המנוע,
ולכן אנחנו כל כך מפורשים כאן אי פעם למחשב, ואמרו,
printf, להדפיס לא אני כבן 65, להדפיס אותו כשווה ערך המספרי שלו.
ומתברר לי מבחינה טכנית אפילו לא צריך את זה.
מה אני עושה לפני רגע במפורש מטיל
ידי קביעה מה סוג נתונים שאני רוצה ללכת ומ.
אבל שם לב שיש לי כבר ג% מציינים מיקום זה
ו% מציינים מיקום זה אחר ג כאן.
למרות שזה לא int, המחשב מבין שchar,
זה רק int מתחת למכסת המנוע.
>> אז אם אני ממש הדר זה ולהפעיל מחדש את תכנית ASCII,
שם לב לזה עדיין רק עובד כי המחשב מבין שיש התכתבות זו.
עכשיו, זה יותר חשוב לעשות ליהוק המפורש בעולם הזה צף לints
כי יש שאתה בעצם קבלת החלטה מחושבת:
לזרוק את כל מה שאחרי הנקודה העשרונית.
כאן יש באמת דבר לזרוק בגלל אופי הוא רק מספר,
ומחרוזת היא פשוט מערך של תווים.
אז כשזה מגיע זמן ליישום חלק הצפנה או פענוח,
איך זה שאנחנו באמת יכולים לתרגם משהו כמו השטות הזאת ל,
הקפד לשתות השוקו שלך?
מה אם אנחנו יודעים עכשיו - בואו ניקח כהנחה - שהמפתח,
המספר שאנחנו מסתובבים כל המכתבים האלה על ידי, הוא המספר 13?
אז הלכו כל הדרך לO בתחילת המשפט מהאות B,
הקפד לשתות השוקו שלך, כי אם אני עושה ב '
ואז אני חוזר C, D, E, F, G, H, I, J, K, L, M, N, O,
בגלל זה ההצפנה של האות B הופכת O
כי אני פשוט הוספתי 13 לזה.
>> אז אם אני רוצה זה לפענח, אני בעצם צריך לקחת O ואז להחסיר 13 מזה.
או, למען אמת, כי יש 26 אותיות באלפבית, זה נפלא סימטרי,
גם אנחנו יכולים רק להוסיף 13 וכולנו נחזור למכתב ב '
אבל איך אתה הולך על יישום משהו כזה בקיסר
או באמת מניפולצית מחרוזות באופן כללי?
אם אות B הוא מה מספר?
מה אות B? אז זה 66, נכון?
אז אם המכתב הוא 65 והאות B הוא 66,
כך 66, כל מה שאני צריך לעשות הוא להוסיף 13 לזה, וזה נותן לי 79.
ואם אנחנו הולכים לגיליוננו קצת לרמות, אכן 79 המפות על O.
>> אבל יש קצת פינת מקרה כאן.
מהו, למשל, אות Z?
אם אנחנו עושים 66 + 25 כדי לקבל את כל הדרך עד סוף האלפבית, אנחנו בגיל 91.
91 + 13 נותנים לי 104, ונחשו מה?
104 לא שווים אות גדולה.
בואו נחזור לגיליון רמאית קטן כאן.
אם אני יכול להפעיל מחדש את התכנית במכשיר, שים לב ש104, אם אני חוזר לחלון המסוף,
104 הן כנראה באותיות הקטנות h.
אז אנחנו צריכים קצת טריק מפתח כאן כדי לוודא שכאשר אנחנו מתחילים בZ
ואנו מוסיפים 13 לזה שאנחנו לא רוצים רק כדי לשמור שועטים קדימה למספרים גדולים יותר ויותר.
מה אנחנו באמת רוצים לעשות?
אתה רוצה לעטוף.
>> אז מתברר, כפי שראית בסעיף כנראה עכשיו או במפרט סט הבעיה עצם
הבין שיש למפעיל אחר בC שגם הוא סימן אחוזים,
בעוד שאנחנו מנצלים% לכאן כדי לציין מציין מיקום אבל,
יודע את זה, במיוחד לקבוצת הבעיה 2, יש גם משהו כזה:
int x = y% z.
תן לי רק להציג את זה כצורה כללית מאוד של זה.
אחוזים כלומר מה בשפת תכנות? >> [תלמיד] מודולו.
מודולו, אשר הוא דרך מפוארת לומר את השארית.
למרות שיש הבדל קל בהגדרה שם,
שזה אומר לחלק y ידי z אבל לא מחזיר את תוצאת שהחלוקה;
במקום זאת, להחזיר את השארית.
>> אז אם Y הוא למעשה 3 וz הוא למעשה 2, 3 חלקים 2 הוא 1 עם שארית 1,
אז מה עושה x בעצם שווה בתרחיש זה? 1.
זה רעיון כל כך פשוט, ברמה נמוכה.
זה לוקח קצת זמן כדי לקבל את דעתך עוטפת אותו
כי זה כנראה עבר זמן מאז שאתה אף נאלצת אכפת שאריות
ובעצם להשתמש בם למשהו תכליתי,
אבל במקרה הזה את העובדה הפשוטה שאתה יכול ללכת ממספר גדול כמו 3
למספר קטן יחסית כמו 2 ולאחר מכן לעטוף ביעילות
באמצעות השאר לערך קטן יותר כמו 1 הולך להיות טריק לא יסולא בפז
שאנחנו יכולים להשתמש בשניהם למשהו כמו קיסר וVigenere דבר השני זה
בבעיה להגדיר 2, אבל זה הולך להיות טריק חוזר לאורך כל הסמסטר.
, זה פשוט רעיון פשוט של לקחת את היתרה באופן כללי
הוא הולך כדי לאפשר לנו לעטוף.
וכמו שאנחנו מתחילים לשחק יותר עם מערכים, כמו שאנחנו מתחילים לשחק יותר עם זיכרון עצמו,
זה הולך להיות יותר ויותר מטריק חזק.
>> אז כל שאלה אז על ASCII או הייצוג של מחרוזות כמערכים?
ואנחנו ניקח את זה ברמה גבוהה 1 נוספת. כן.
[שאלת תלמיד לא נשמעה] >> שאלה טובה.
מה זה אומר כאשר למשתנה יש כוכבית לפניו?
תן לי לדחות את מענה לכך בכל פרט,
אבל זה מתייחס לנושא הידוע כמצביע.
מצביעים צריכים לעשות עם זיכרון, ואנחנו בעצם היום
לוקח את הצעד הראשון לקראת אותו הדיון,
אך לעת עתה, בואו יעמידו הפנים שהכוכב לא קיים
ואנחנו נמשיך לקרוא מחרוזות מחרוזות במקום להשתמש * char,
שיש לך כנראה ראה בעבר ואני אשים על המסך ברגע כטיזר.
אז אנחנו נחזור לזה בפירוט רב יותר מהדרך שלך תהיה כנראה אוהב.
סופו של דבר, לא היום. כן.
>> [שאלת תלמיד לא נשמעה]
באיזה קשר אתה צריך לספק את הסימן לאופי? >> [תלמיד] כן.
אז כברירת מחדל, כאשר אתה לא שמת את +, רק מספרים חיוביים בדויים.
אז אם רק לכתוב את המספר 1, זה 1 חיובי.
אם אתה באמת רוצה לציין את שלילת ערך,
אתה ממש צריך לעשות -1 במקלדת.
אבל זה כנראה לא כל השאלה שלך. >> [תגובת תלמיד לא נשמעה]
>> שאלה טובה. אוקיי.
אז זה צריך לעשות, אני מניח, עם איזה סוג של באג שנתקלת בי
בגלל שאתה ממיר מספר שלם לאופי,
אבל איכשהו השליליות התערבו,
וכך האופי פשוט יצא munged איכשהו.
אז לעת עתה, בואו פשטנות היתרה קצת עד שנחזור לסוג זה של נושא.
לעת עתה, לחשוב על דברים בדרך זו - וזו פשטנות.
אבל בעולם של מספר שלם, יש לך כמה ביטים שברשותך?
יש לך 32 סיביים.
ועד כה, שדברנו על המספר הכולל של מספרים שלמים אתה כן יכול לייצג
הוא בערך 4 מיליארדים מוחלטים משום שיש לך 32 סיביים,
אז זה 2 עד 32, כך שזה בערך 4 מליארד שקל.
אבל אנחנו ראינו בשבוע או 2 לפני שאתה לא באמת צריך טווח המספרים
מ 0 על עד 4 מליארד דולרים.
הטווח במקום עובר מ 2 מליארד בערך שליליים לחיובי 2 מליארד דולרים.
אבל אז זה מעלה את השאלה, איך אתה מייצג את הרעיון של 2 מיליארדים שליליים
שלא לדבר על שלילי 1?
לעת עתה, אנו יכולים פשטנות יתרה, ורק אומרים שאנחנו הולכים להשתמש בקצת השמאליים ביותר
של 32 הביטים האלה, ואם זה 1 זה מספר שלילי,
ואם זה 0 זה מספר חיובי.
הבעיה עם זה ייצוג מופשט של מספרים שליליים
הוא שאם אתה בכוונה מתחכם, ומנסה להמיר מאופי למספר
או להיפך, אין דבר כזה כדמות שלילית.
בעולם של ASCII, אשר משתמש רק 8 סיביים, כל אלה משנים 8 של הביטים,
וקצת השמאליים ביותר יש מה לעשות עם השליליות.
ורק שיהיו ברור, כשאני אומר ביטים שמאליים ביותר,
זוכר שכשעשינו דוגמאות שלנו קצת הקשורות בשבוע הראשון
זוכר שציירנו דברים כמו 1001101, משהו כזה.
כשאני אומר קצת השמאלי ביותר, אני פשוט ממש מתכוון 1 שאתה כותב את כל הדרך לצד השמאל.
אז בעולם של דמויות אין מושג שלילי,
כך שלמעשה יש מעט השמאלי ביותר משהו לעשות עם ASCII, ולא כלום עם השליליות.
>> אז זה נשמע כאילו - ומחוץ להקשר זה קשה לענות בדיוק -
אבל איכשהו, הקוד שלך היה מבלבל שקצת שמאלי ביותר כמייצג ערך שלילי
כשזה באמת היה חלק מהדמות בשאלה.
ושוב, אני פשטני מדי, כי מחשבים בעצם לעשות משהו קצת להשתכלל
מסתם שינוי שקצת שמאלי ביותר ל1 לסימן שלילי לעומת 0.
הם במקום, אם אתם סקרנים לגוגל, להשתמש משהו שנקרא בדרך כלל השלמה של 2,
וזה קצת יותר מתוחכם מגישה
אבל הרעיון הוא סופו של דבר את אותו הדבר.
>> אז בקיצור, זה היה צריך לעשות עם העובדה שאתה היה מעסה את מספר לתו
או להיפך, אלא הקוד שלך לא היה מודע לעובדה
כי 1 מהחתיכות האלה הייתה משמעות בעולם הספרות.
זה לא המקרה בעולם האופי.
אבל זה נשמע כאילו אתה קבוע, ובמקרה כזה שנוי במחלוקת כרגע. שאלות אחרות.
אוקיי.
אז עד כה, כל התוכניות שכתבנו לקחו קלט אולי מהמשתמש
בצורה של פונקציות, כמו GetInt, GetString,
או אם אתה קראת את קדימה בספרים שונים, או הפניות באינטרנט,
אתם עצמכם שהיו משתמשים בפונקציות כמו scanf ש, בכנות, אנו משתמשים בCS50 הספרייה.
אבל בשבוע או 2, אנחנו בעצם להראות לך איך ספריית CS50 מיושמת
כך שאנחנו יכולים לקחת את גלגלי העזר האלה לגמרי.
>> אבל מתברר שיש עוד דרך לקבל קלט ממשתמש.
למעשה, אנחנו בעצמנו כבר משתמשים בנימוקים של שורת פקודה
במשך כמה שבועות.
בכל פעם שיש לנו לרוץ קלאנג או נגמרנו לנו לעשות,
אנחנו לא רק שהקלדנו צלצול, זן, אנחנו לא הדפסנו לעשות, Enter.
מה שכתבנו בדרך כלל אחרי מילת הצלצול במסופנו חלונות הפקודה?
[התלמיד] שם הקובץ. >> שם הקובץ, נכון?
Hello.c או mario.c או מה שם הקובץ הרלוונטי הוא.
ובמובן זה באמת מה שעשית הוא שהשפעת על התנהגותו של קלאנג
כי ללא ספק אנשים שכתבו קלאנג היו לי מושג שאתה קצת ישן
הולך לכתוב תכנית בשם כעבור שנתי mario.c.
אז היה לך איכשהו להשפיע על התנהגותה של התכנית,
ושקלאנג התכנית צריך להיות כתוב בצורה כזו שהוא יכול לקבל קלט ממך
על ידי התוספת של מילים על הפקודה לפני שהמשתמש לוחץ על Enter.
>> אז מתברר שזה זמן מה אנחנו כבר הצהרנו כמעט כל התוכניות שלנו
להתחיל ככה - int main (void) - ואז אנחנו כבר הלכנו קדימה
והתחיל לכתוב את הקוד שלנו.
ואולי יש לנו קצת חד כולל בחלק העליון של הקובץ,
אבל כמעט כל התוכניות שלנו עד כה התחיל עם זה
למרות שאתה עשוי לראות בסעיף, בספרים, באינטרנט הפניות
כי זה לא בעובדה צריך להיות מבוטל.
צורה לגיטימית נוספת לזה לקחת היא אז המחרוזת argv [] int argc ו.
אז עכשיו מה זה רומז?
מתברר שargc, שהוא כינוס אנושי - אתה יכול לקרוא לזה foo,
אבל זה יהיה רק ​​הרבה פחות ברור לקוראים -
argc פשוט הוא טיעון לפונקציה שנקרא main שמייצג את מה?
מה argc לבלוט למי שמכיר?
>> [תגובת תלמיד לא נשמעה] >> כן, מספר הטיעונים או לספור ויכוח.
זה פשוט כמו זה.
כמה ויכוחים הועברו לתכנית זו?
מה זה אומר?
אם בשורת הפקודה יש ​​לי להפעיל משהו כזה - צלצול mario.c--
argc כשפגעתי זן הולך לקחת על ערך, קצת מבלבל, 2.
אז מתברר שargc הוא ספירת ויכוח,
אבל מסיבות הסטוריות, השם של התכנית עוצמה נכלל שבספירה.
אז argc הוא 2 כשכתבתי צלצול mario.c.
מה argv מכיל?
קודם כל, argv נראה כמו מחרוזת אבל לא ממש
כי כמו ביום רביעי שעבר ועוד יותר היום,
סוגריים מרובעים אלה לציין את מה? זה מערך.
אין מספר במערך, וזה צריך להיות הגיוני באופן אינטואיטיבי
בגלל שהאנשים שכתבו לפני שנתי צלצול בהחלט היו לי מושג
כמה אנשי מילים, כמונו, מקלידים בשורת הפקודה לפני שפגע Enter.
>> אז במקרה הזה כאן הם הכריזו הפונקציה עיקרית כלוקח מערך של טיעונים,
0 או יותר ויכוחים.
הם לא יודעים מראש כמה יש,
כך שיש במכוון לא בתוך מספר הסוגריים המרובעים האלה.
אבל העובדה שהסוגריים המרובעים נמצאים שם אומרת לי המחשב,
מצפה מערך.
Argv הוא רק סימון מקוצר עבור וקטור ויכוח.
וקטור הוא דרך מפוארת לומר מערך,
ומערך הוא דרך מפוארת של להגיד רשימה או אוסף.
אז זה רק אומר שאם אתה כותב ראשי כמו זה
במקום כמו איך אנחנו עושים את זה כבר לשבועות האחרונים,
התכנית שלך עכשיו יש את הכח לקבל את הטענות של שורת פקודה
כך שאתה כבר לא צריך לכתוב מריו ולאחר מכן על Enter,
לאחר מכן הקלד במספר עבור כמה בלוקים גבוהים אתה רוצה להיות הפירמידה,
לאחר מכן על Enter שוב.
אנחנו אפילו לא צריכים להשתמש GetString יותר או GetInt או GetFloat לצורך העניין.
אנחנו רק יכולים לצפות מהמשתמש להקליד את המילים האלה בשורת הפקודה עצם
בדיוק כמו כותבי קלאנג החליטו שזה יהיה ממש מעצבנת תכנית
אם לקמפל את הקוד שלך אתה ראשון צלצול מוקלד, Enter,
אז אמר למשתמש, אנא הקלד את השם של הקובץ שאתה רוצה לקמפל,
אז הקלד בmario.c והקישו על Enter.
אבל זה בדיוק מה שאנחנו עושים למשתמשי השבועות האחרונים שלנו.
אנו משתמשים GetString ואנחנו מחכים עד התכנית פועלת כדי להנחות אותם לקלט.
זה כבר לא צריך להיות במקרה.
>> אז בדוגמה זו כאן, עכשיו יש לנו המחרוזת argv,
וגם את זה הוא פשטני,
גלגלי עזר שבקרוב מאוד יורדים.
זו היא הדרך הנכונה יותר של כתיבת הצהרת חלופה זו של עיקרי
כי מסתבר כי מה שאנו ממשיכים לקרוא למחרוזת בעצם יש כוכב,
כוכבי, בהגדרתה בפועל, אבל זה רק נראה מסובך,
זה מבלבל בהתחלה, ולכן אנחנו מקלים רק על ידי יצירת מילה נרדפת של מינים
בספרייה שCS50 דמות * מפות למילת מחרוזת יותר ידידותית למשתמש זה.
>> אז בואו ננסה את זה דווקא אז. תן לי ללכת קדימה, לפתוח את gedit כאן.
תן לי ללכת קדימה ולפתוח argv של 1.
תכנית זו כנראה מדפיסה את הטענות, אבל בתנאים בשפה אנגלים,
על ידי ההתבוננות בקוד זה, מה זה עושה יותר ספציפי?
אם אני מקליד בפקודת a.out foo הבר, מה מקבל מודפס בחלון השחור ולבן שלי?
A.out foo בר, Enter.
קדימה. כן. >> [תגובת תלמיד לא נשמעה]
טוב. אז a.out, קו חדש, foo, קו חדש, בר, קו חדש.
מדוע זה קורה? אנחנו בהחלט יכולים לאשר ברגע.
זה סוג של קו רך של קוד.
זה פשוט מדפיס קו חדש רק כדי לעשות דברים יפים על המסך.
זה לולאה זה iterating מ 0 בעד argc,
וזה הגדלה בכל איטרציה + +.
אז זה אומר עכשיו להדפיס מחרוזת, כפי שנרמז על ידי% s זה.
Argv [i] הוא פחות או יותר את אותו הרעיון מהדוגמא הקודמת.
נהגנו לקרוא לזה משתנה, עכשיו זה נקרא, באופן שרירותי, argv.
משמעות הדבר הוא להדפיס את טיעון ith שהוקלד בשורת הפקודה,
ואז אחרי שכל העניין הזה נעשה, רק למען סדר טוב להדפיס עוד קו חדש.
>> אז בואו נראה את זה. בואו תפתחו לי את חלון המסוף.
בואו לאסוף אותי argv של 1, ועכשיו תן לי לרוץ argv של 1, Enter. הממ. אוקיי.
בואו לרוץ בר foo. מעניין. באז.
ואם אי פעם תהו מדוע אני מסוג זה,
זה פשוט גם כנס מדעי מחשב טיפש.
העולם לעתים קרובות צריך מציינים מילוליים רק למילים.
אז אם אתה רוצה לדבר על איזה מייתר הגנרית,
מדעני מחשב פשוט נוטים לומר foo כאשר הם צריכים את מילה אקראית,
אז הם אומרים בר אם הם צריכים את מילה שנייה אקראית,
אז הם אומרים באז אם הם צריכים את מילה שלישית, ואז הם אומרים qux אם הם זקוקים למילה רביעית,
ואז יש באינטרנט ויכוח דתי עצום על מה שבא אחרי qux,
כך שאתה יכול לגגל את זה כדי להבין מה המילה השרירותית האחרת צריכה להיות.
אבל אלה לא היו כל משמעות,
למרות foo בר, אם כי גוגל, שעושה יש משמעות,
שהוא חלק מהאטימולוגיה כאן.
>> אז כל זה עושה אז מדפיס 1 מתוך המחרוזות הללו בכל שורה.
אז אם אני במקום, אם כי, רציתי לקבל קצת להשתכלל,
תניח שאני לא רוצה להדפיס כל מחרוזת בכל שורה;
רציתי להדפיס כל דמות מכל מחרוזת בכל שורה.
איך אני יכול לעשות את זה במקום?
מה אני צריך לשנות על תכנית זו, אם אני רוצה להדפיס לא כל מילה
אבל אני רוצה להדפיס כל מילת אות אחרת אות אחרת אות,
אז מילת האות הבאה על ידי אות אחרת אות?
איך לשלב רעיונות אלה עד כה? כן.
[תלמיד]% ג. >> בסדר. אז אנחנו צריכים המקום ג%.
טוב, כי אני לא רוצה להדפיס מחרוזות שלמות, אני רוצה להדפיס את התווים. מה עוד?
>> [תגובה בלתי נשמעת תלמיד] >> מעניינת.
אז אנחנו צריכים סוג של ממד שני כאן עכשיו
כי תחשוב על argv כמערך, אבל זה מערך של מחרוזות.
אבל נכון ל, כאילו, לפני 15 דקות, מה זה מחרוזת? זה מערך של תווים.
אז באמת, argv הוא מערך של מערך של תווים,
מערך של מערכים של תווים.
אז מתבררים שאנחנו יכולים להשתמש בסימוני סוגריים מרובעים פשוט יותר. אז בואו לעשות את זה.
בחלק העליון של לולאה זו על קו 19, אני הולך לחזר מאותי לargc,
אבל אז אני הולך לעשות את זה:
ל-- אני לא יכול להשתמש אני עכשיו.
אני צריך עוד משתנה כי אני רוצה לחזר על המילים
אבל אז גם על פני האותיות במילים
אז יש לי מין ציר אנכי וציר אופקי, סוג של מושגית.
אז j int מקבל 0, אז אני רוצה לעשות כל עוד j j הוא פחות מ - ואני אנקה את זה בקצת.
כיצד לחזר על פני האותיות במחרוזת? אנחנו עשינו את זה לפני רגע.
Strlen של argv [i]. טוב.
ושוב, אני עושה את חוסר יעילות קטן כאן לא יצירת n או משהו כזה,
אבל אנחנו עוד נחזור לזה.
>> אז עכשיו j + +. עכשיו יש לי לכניסה נוספת כאן.
מה אני עכשיו רוצה להדפיס על כל איטרציה?
[תגובת תלמיד לא נשמעה] >> אז [i] ייתן לי מילה.
[I] [j], כמו סוג של מטריקס.
אלה מכם עם רקע במתמטיקה-y,
אנחנו סוג של אינדוקס אפילו עמוקים יותר לתוך מטריצה ​​זה או זה מערך של מערכים,
מבנה זה 2-ממדי.
אז עכשיו בואו נראים מה קורה כאן. בואו תפתחו לי חלון המסוף הגדול שלי.
תן לי לעשות את השידור חוזר של argv של 1.
וכבר פשלתי כאן, וזה שיעור טוב כי גם אני שכחתי לעשות את זה.
הכרזה במשתמע 'strlen' פונקצית ספריית C עם חתום סוג '-
אני אפילו לא יודע מה שאר זה אומר, אבל אני לא ראיתי את זה קודם,
הכרזה במשתמע.
בכל פעם שאנחנו רואים את השגיאה הזו, מה זה בדרך כלל מסמל?
>> [תגובת תלמיד לא נשמע] >> שכחתי ספרייה למעלה. אבל חכה רגע.
בדרך כלל אני כבר פשלתי כי שכחתי CS50 הספרייה, אבל זה שם.
בדרך כלל אני כבר פשלתי כי שכחתי התקן I / O.
ולמען האמת, אני אפילו לא צריך את זה. אנחנו לא באמצעות GetString היום.
אז מה אני מפספס?
יש ספרייה אחרת שכרגע אנחנו צריכים להשתמש string.h נקרא מדי פעם,
וזה עדיין ספרייה אחרת שיש לו יותר פונקציות שאינן בתקן I / O.
>> אז בואו נחזור לחלון המסוף הגדול שלי.
אוקיי. עכשיו, לעזאזל, אני מניח שטעיתי. אני משתמש בספריית CS50.
אז אנחנו יכולים לתקן את זה באחת מ2 דרכים.
אנחנו יכולים לקחת את גלגלי העזר מעכשיו ופשוט לעשות את זה,
או סוג של בואו נשמור פישוט שרק לעת עתה, ולהדביק את זה בחזרה ב,
לפתור את הבעיה, ועכשיו אחזור לחלון המסוף.
אז כדי שיהיה ברור, בספריית CS50 היא לא רק פונקציות,
זה גם ממילת המפתח, ולכן שגיאות שפשוט קרו.
>> אז הנה זה בא. אני תקנתי את שתי סוגיות הספרייה. Enter. טוב.
Argv של 1, foo בר, Enter. מצוין.
אז עכשיו יש לנו כל אות בכל מילה המודפסת 1 בכל שורה,
שלא עושה לתכנית מאוד מעניינת,
אבל עכשיו יש לנו הודעת יכולת לא iterating רק על מילים
אלא גם על אותיות בודדות במילים, שנשמעה מאוד מוכר
לאפילו הפשוט ביותר של יישומים כמו אותיות נאבקות במחרוזת כמו זה.
בואו נלך קדימה, לקחת ההפסקה שלנו 5-הרגע פה.
וכשנחזור, נתחיל לדבר על היעילות
עם שאנחנו יכולים לעשות את הדברים האלה יותר טובים.
>> בסדר. אנחנו נחזור.
הודות לאחד מTFS שלנו שמשחק הרבה bananagrams,
אנחנו באמת צריכים כל חבורה של תווים עימנו כאן היום
פיזי התגלגל עם חתיכות פלסטיק קטנים האלה,
ותרשו לי להציע שרעפים לבנים ריקים זה כאן מייצג את ה-RAM במחשב שלי -
מחשב נייד, שולחן עבודה, כל דבר - ויש נראה הרבה ממנו
כי אם אנחנו מתחילים לקצוץ את זכרון RAM זה לחתיכות קטנות בגודל הבתים,
בואו שרירותי לומר משהו שהגודל ומטושטש שמייצג -
שם אנחנו הולכים, ובואו להתרחק קצת כאן -
בואו נגיד משהו שמייצג גודל בית אחד.
אז אנחנו אכן יכולים להתאים חבורה שלמה של בתים או תווים בתוך הזיכרון הזה,
כפי שהוצע על ידי הגודל היחסי כאן.
>> אז תניח שעכשיו המטרה היא להקצות זיכרון למחרוזת.
איך זה באמת עובד?
בתוכניות שכבר כותבים, יש לנו בדרך כלל משתמשים בGetString,
אבל עכשיו, באופן ברור, יש ערוץ זה אחר באמצעותו אנו יכולים לקבל קלט מהמשתמש בargv
באמצעות טיעוני שורת פקודה.
אבל מה באמת קורה מתחת למכסת המנוע?
מתברר אם אנו מכנים - בואו לגלול חזרה לGetString - GetString הפונקציה
בספריית CS50, המשתמש מתבקש למחרוזת,
המשתמש מקליד במילה מסוימת - בואו נקראים לזה שלום.
ואנחנו אומרים כבר השבועות האחרונים שערך ההחזרה של GetString
הוא למעשה חוט, כמו המילה שלום.
>> אבל מה הוא באמת עושה GetString?
ככל שהמשתמש מקליד את השלום, Enter, GetString הוא להבין,
בסדר, כמה תווים זה? זה H-E-L-L-O.
אז זה צריך להקצות, זה צריך לשאול את מערכת ההפעלה - לינוקס במקרה זה -
לפחות 5 בתים כדי לאחסן שלום.
ומה זה ואז ממשיך לעשות ברגע שהוא חוזר 5 הבתים האלה ממערכת ההפעלה
הוא להוציא שלום גב אל גב אל הגב אל גב.
וכן מה שבאמת חזר מGetString הוא נתח של נתונים שנראה כך.
אבל זה קצת לא מדויק, כי מתברר שזה לא פשוט כמו
כרק מאחסן שלום בזיכרון של המחשב
כי תניח שהתכנית שלי שאני כותב ב-C ואז קוראה GetString שוב,
והמילה הבאה סוגי המשתמשים היא בביי, ביי.
טוב, אני צריך להתאים את המילה BYE אי שם בזיכרון.
אני לא יכול לכסח לו שלום.
לדוגמה, אני לא רוצה שהמחשב פשוט להתחיל להחליף ככה
המילה המקורית כי אולי אני עדיין משתמש במילת שלום במשתנה
במקום אחר בתכנית שלי.
>> אז ב-Y-E יש לגמור במקום אחר בזיכרון.
אבל בדרך כלל היא המוסכמה שהמחרוזת הבאה שתקצו
כנראה, אבל לא תמיד, הוא הולך בסופו של דבר את מיקום הזיכרון הזמין הבא.
ואם לא שאלתי את מערכת הפעלה לכל זיכרון
מאז הפעם האחרונה שהתקשרתי לGetString, סיכויים הם המילה BYE
הוא הולך בסופו מייד אחרי מילת שלום בזיכרון.
אבל בנקודה זו ניתן אולי לראות איפה בעיה פוטנציאלית עולה.
משום שהנתחים הקרובים של זיכרון, את הבתים הקרובים שהיו רק חופשיים -
לנקות צפחה לבנה - בזיכרון של המחשב היו ממש ליד שלום,
זה מרגיש כמו המחרוזת הראשונה שבקשתי פתאום עלול לשנות עכשיו
כי אני כבר השתניתי במהותו לHELLOBYE
במקום איכשהו demarcing תחילת BYE וסופו של שלום.
>> אז מתברר כי מה שבאמת קורה מתחת למכסת המנוע,
שייתכן שהבחנת בהפניות באינטרנט או סעיף או ספרים
או בכלל לא פשוט עדיין הוא שאין למעשה תיחום מכוון
בין מילים בזיכרון של מחשב.
ואכן, במקרה זה כאן, ולא רק לשים BYE ממש ליד שלום,
במקום זאת, המחשב מכניס את תו מיוחד, תו null המיוחד, אם אפשר לומר כך,
המיוצגת בסמן עם קו נטוי 0.
אז סיפור ארוך קצר, זוכר כי תווים מיוצגים בASCII.
ASCII הוא פשוט מיפוי בין מספרים ואותיות,
ורוב המכתבים האלה מתחילים 65 בערך להון,
אבל מסתבר שבהחלט יכול לייצג את מספר 0 כמספר שלם או בינארי,
ומתברר שהעולם החליט כבר מזה זמן רב, "אתה יודע מה?"
"0 בואו מילואי מספר שלא מייצג את כל תווים במקלדת -
"לא מכתבים, לא מספרים, לא פיסוק. 0 הם מיוחדים".
"זה הולך להיות תו null המיוחד, ואנחנו הולכים לכתוב אותו כ\ 0".
ההבדל הוא שאם אנחנו רק כתבנו 0, 0 הוא אופי.
תזכיר כי יש קודי ASCII עבור 0, עבור 1, ל2, ל3
בגלל 0 אופי שונים ממספר 0.
ואתה יכול לראות שאם אתה מסתכל אחורה מהשבוע 1 כשדברנו לראשונה על ASCII,
0 1 ו 2 ו 3 את כל הדרך עד 9 היו קודי ASCII שלהם.
הם לא במקרה, היו 0 עד 9. הם מאוד שונים.
אז 0 רק אומר "אני מיוחד", ואת \ 0 המשמע, פשוטו כמשמעו, "אני לא 0 האופי".
"אני זה ערך מיוחד, תו null."
אז אני באמת צריך עוד אחד מאלה שכן אני לא יכול לעשות את אותה טעות פעמים.
>> אז אחרי המילה BYE אנחנו גם הולכים צריכות עוד אחד מהתווים הריקים האלה.
תן לי לקחת את העט שלי כאן ותנו לי לצייר עוד \ 0 במהירות
כך שלאחר ששאלתי את מערכת ההפעלה עבור 2 מחרוזות
דרך GetString אחרי שיחה נוספת לGetString,
זה מה שבעצם בזיכרון.
אז כשאני אחזור מחרוזת, אני באמת מקבל את זה בחזרה,
וכאשר אני מקבל את המחרוזת הבאה, אני באמת מקבל את זה בחזרה.
אז זה מעלה את השאלה, strlen, קודם כל, מה שצריך זה לחזור?
כשאני קורא strlen על מחרוזת של והים היה מילת שלום שמשתמש הקליד ב,
מה היה לנו ברור שאומרים האורך של שלום היה לפני כמה דקות?
זה היה 5, נכון? H-E-L-L-O. וזה אכן מה strlen עבודות.
זה מחזיר את מה שאדם נורמלי הייתי מצפה אורך מחרוזת להיות.
אבל במציאות, עד כמה גדול הוא המערך של תווים המאחסנים שלום?
זה בעצם 6.
אז strlen לא מזכיר את העובדה שכדי לך.
אבל מתחת למכסת המנוע של המחשב הוא אכן באמצעות 6 בתים כדי לאחסן 5-מכתב מילה,
וזה נכון לא משנה כמה זמן היא המילה.
יש תמיד הולך להיות דמות הפסקת אפס מיוחדת בסוף המחרוזת
לdemarc האורך הכולל שלה.
>> אז אם אתה עכשיו אדם יישום strlen 20, לפני 30 שנים,
איך אתה הולך על יישום strlen עצמו?
אנחנו לוקחים כמובן מאליו שהוא קיים, בדיוק כמו שאנחנו לוקחים כמובן מאליו שקיים printf,
אבל אם שלום הוא המילה בשאלה
ומה יש לי בזיכרון הוא משהו שנראה כמו זה,
אם היה לך לreimplement strlen מכיוון שהתבקשו
או כי, בכנות, אתה לא יודע strlen קיים -
היה לך לגלגל את זה בעצמך - איך אתה יכול ליישם strlen
כאשר ניתן משהו שנראה כמו זה?
עכשיו שאנחנו יודעים מחרוזת היא מערך, אנחנו יכולים לחזר על כל אחת מהדמויות הבודדות
שימוש במשהו כמו - בוא ננסה לעשות את זה במהירות ההבזק.
>> תן לי ללכת אל המכשיר. תן לי ליצור קובץ חדש, strlen.c.
תן לי ללכת קדימה עכשיו, אבל כולל stdio.h כך שיש לנו גישה לprintf.
תן לי לעשות (void) העיקרי int. אה. אני רק עושה את זה בעצמי לעכשיו אז. [מגחך]
תודה.
זה מה שאני עושה. בסדר.
אז לפני שהדלקתי את המסך, הקליד את כל זה.
ועכשיו מה שאני הולך לעשות הוא בא:
printf ("תן לי את מחרוזת:")
זה רק הוראות רכות.
עכשיו תן לי לעשות = GetString של המחרוזת.
אני כבר צריך לעשות שינוי עכשיו.
אני משתמש בספריית CS50 פתאום, ולכן נתן לי ללכת קדימה והקלד בcs50.h.
ועכשיו בואו נעשה את זה: printf ("האורך הוא:% d, strlen [s] -
ואני עדיין לא עשיתי. מה עוד אני צריך להוסיף לתכנית זו?
>> [תלמיד] string.h. >> String.h.
אז לעת עתה, אנו משתמשים strlen, אז בואו נוודא שמהדר יודע איפה זה,
כל כך מעט שפיות לבדוק.
אני מקבל מחרוזת בשורה 8, וקו 9 אני מדפיס את אורכה עם ד%.
אז בואו נלך קדימה, לפתוח את זה.
יש לנו לעשות strlen - הידור בסדר -
strlen - תן לי להתמקד ב-- זן, H-E-L-L-O, Enter. האורך הוא 5.
>> אוקיי, אז strlen נראה עבודה, אבל העולם ידע את זה.
אז בואו עכשיו ליישם strlen עצם כדלקמן.
תן לי לקחת את זה משם ספרייה.
כבר אין לנו גישה לstring.h כי אני אפילו לא יודע שזה קיים.
אבל זה בסדר, כי אני יכול ליישם strlen עצמי
ויש לו לקחת את המחרוזת שנקראה קלט,
ועכשיו אני צריך להבין את אורך המחרוזת.
אז איך אני יכול לעשות את זה?
מה אם אני עושה - בואו לראות איך לעשות את זה - מה אתה רוצה לעשות?
>> [תגובת תלמיד לא נשמעה] >> אוקיי.
אז אנחנו יכולים לעשות את זה בחבורה של דרכים. תן לי לנסות לקחת את הגישה הזאת.
בואו לתת לעצמי משתנה int i, אז אני מתחיל ב 0.
והרשה לי לומר זה: בעוד קלט [i] היא לא שווה את מה? \ 0.
אז מתברר, כמו במקרה עם כל התווים בעת כתיבתם, פשוטו כמשמעו, בתכנית,
אתה צריך להשתמש בגרשיים בודדים, ולא במרכאות כפולות.
אז אם הייתי כותב את המכתב, אני הייתי עושה את זה, את האות ב ', אני הייתי עושה את זה.
זה, לעומת זאת, יהיה מחרוזת, לא אופי אישי.
>> אז אני רוצה \ 0, פשוטו כמשמעו. מה אני רוצה לעשות בלולאה הזו?
למעשה, אני צריך עוד משתנה, כך שאורך int מקבל 0.
גם אם לא הייתם בטוחים למה התחיל את הדרך שעשינו,
עכשיו שאנחנו הולכים בדרך הזאת, מה אני רוצה לעשות בקו 9?
אורך + + ולאחר מכן כאן בקו 10, אורך תמורה.
אז איך strlen מיושם?
זה באמת ייושם כנראה כזה.
אולי האדם שהשתמש ללולאה, אולי לעשות בזמן לולאה - מי יודעת?
אנחנו באמת צריכים להסתכל מתחת למכסת המנוע בקוד המקור הממשי
בקובץ מסוים נקרא string.c כנראה.
>> אבל כאן בואו נחשוב על מה שאני עושה.
אני מכריז על משתנה בשמי, הגדיר אותו שווה 0.
אז אני מכריז בשם אחר אורך משתנה, הגדיר אותו שווה 0.
ואז אני אומר תוך דמות ith בקלט אינה שווה לתו null המיוחד, \ 0,
להגדיל את האורך.
אבל ברגע שדמות ith היא האופי המיוחד הזה, מה קורה ללולאה?
זה קצר. זה מפסיק, מה שאומר שאנחנו מייד לאחר מכן נחזור אורך.
>> אז אם אני לא בלגן, בואו נלך קדימה ולחזור לחלון המסוף שלי.
בואו הדר אותי. ואני לא לפשל.
redeclaration לא תואם של פונקצית ספריית strlen.
אז אני מנסה לקבל חכם יותר ממה שלי כאן.
המהדר בעצם יודע שיש פונקציה שנקראת strlen
למרות שאנחנו לא כללנו את הספרייה. זה בסדר גמור. לא משנה מה.
אנחנו רק הולכים לשתף פעולה אז. בואו לשנות את האורך הזה.
הרשה לי לשנות את השימוש בו לאורך כאן, וזה יגרום לי קלאנג מאושר יותר.
במאמר מוסגר, כי חלק מהפונקציות הללו הם כל כך מעצבן הזה משותף -
strlen, prinf - הם למעשה יש סוג של מעמד מיוחד.
וכך קלאנג פשוט יודע משהו מיוחד עליהם קצת.
זה לא תמיד המקרה עם רוב הפונקציות, כך שזו הסיבה שצרחנו עליו.
>> תן לי לנסות שוב. למרבה המזל, זה עבד בפעם ההיא.
אז עכשיו תן לי לרוץ strlen התכנית שלי.
תן לי את מחרוזת: H-E-L-L-O, Enter. ואני דפקתי את העסק.
למה? >> [תגובת תלמיד לא נשמעה] >> בדיוק.
אז יש לי את עצמי כאן לולאה נחמדה מאוד למראה אינסופית
כי למרות שאני הגדלת אורך בכל איטרציה,
מה אני עושה באופן ברור לא? אני לא להגדיל כל אני. אוקיי. תיקון קל. כן?
אוקיי. המספר עכשיו לא היה לנו לסטות מטעות נפוצה אחרת שבו אני צריך סוגריים.
ולמען אמת, קוד זה מתחיל להיראות מכוער,
אז אנחנו ניקח דקירה בניקיון זה ברגע.
אבל עכשיו אני הגדלה של אורך ואני.
בכנות, אני כבר רואה את הזדמנות לשיפור כאן, אבל אנחנו עוד נחזור לזה.
>> אז עכשיו בואו רק לוודא שאנחנו לפחות יש התקדמות.
זה קרה לכמה מכם, ואני שכחתי להזכיר את זה מראש.
כאשר יש לך מזל הרע של תרחיש כזה, איך אתה לתקן את זה
קצר של הפעלה מחדש של המכשיר או המחשב או לסגור את החלון?
זה ממש קל.
בקרת ג ישלח זה גזר סמל 'קטן, ושפשוט מסתיים רוב התוכניות.
אם יש לך לולאה אינסופית ממש רעה שהוא מדפיס אינסוף דברים פעמים,
ייתכן שלעתים צריכים להכות הבקרה C אלף פעמים כדי להפוך אותו באמת לשמוע אותו.
אז רק עכשיו אני מבין כי אני לא מדפיס כל דבר, זה היה די קל.
מבחינה טכנית, ברגע שמספיק, אבל אני מתעצבן ואני בדרך כלל להכות אותו כי פעמים רבות.
>> אז strlen. תן לי את מחרוזת: שלום. האם זה הולך לעבוד הפעם?
אוקיי. עוד טעות נפוצה. צריך להדר מחדש.
זה היה מכוון, כי אחד. בסדר.
אז strlen, H-E-L-L-O, Enter. מצוין.
אז עכשיו יש לנו strlen עד 5.
אז יש לנו reimplemented גלגל שפשוטו כמשמעו.
אז עכשיו בואו לנקות את זה כי זה לא עושה אותי הרשים
עם העיצוב של הקוד שלי.
מה אנחנו יכולים לחסל באופן ברור בתכנית זו כדי לנקות את זה?
[תגובת תלמיד לא נשמעה] >> כן. פשוטו כמשמעו, אנחנו מטפלים אני ואורך זהים.
אז למה אנחנו לא פשוט להתחכם ולומר, בעוד אורך?
במקום זאת, בואו פשוט נקרא לזה אורך מלכתחילה, לאתחל אותו ל 0
כי כברירת מחדל המחרוזת אין אורך עד שנבין מה זה.
>> עכשיו אנחנו עושים את זה, ועכשיו זה תכנית די אלגנטית.
משתנה אחד. ניקיתי אותו, הדקתי אותו.
אז עכשיו בואו נחזור לחלון המסוף שלי. בואו נלך קדימה ולהפעיל את זה.
הפוך strlen. נראה טוב. הפעל strlen שוב, Enter.
תן לי את מחרוזת: שלום, Enter. ונראה שזה עובד כמו 5.
עכשיו, שיהיו ברור, אם אני לא כתבתי, למשל, שלום במחרוזת 1
ואז BYE באחר, אנחנו יכולים בהחלט יש מספר מילים.
אם הביטוי שאני בעצם רוצה להקליד לא היה שלום, אלא, למשל,
שלום העולם, הודיע ​​כי מה שלא יהיה לו זה מצב כאן, נכון?
זה הייתי מציע שזה 2 מחרוזות.
אתה יכול בהחלט יש תווי מקש רווח, כך שאם הקלדנו למעשה בביטוי ארוך יותר
כמו שלום עולם, מה שהיינו באמת יש בזיכרון
נראה קצת כמו משהו שיש.
>> בסדר. כל שאלות אז על הייצוג של מחרוזות כאן?
לא? בסדר.
אז אמרתי קודם לכן שקורא strlen שוב ושוב במכוון ככה
כנראה לא הרעיון הכי הטוב, כי אתה הולך לעשות הרבה עבודה
שוב ושוב ושוב.
אכן, איזה סוג של עבודה הוא הכרחי לחישוב אורך מחרוזת, כנראה?
אתה צריך להתחיל בתחילה ולאחר מכן תראה, תראה, תראה, תראה, תראה
עד שסוף סוף רואה שאופי מיוחד, ובשלב זה, אה, עכשיו אני יודע את האורך.
אז קודם לכן כאשר הייתי strlen שקראו שוב ושוב ושוב,
הסיבה שהצעתי שהיה סוג של טיפשים היא כי שוב, מחרוזת שנראית כמו זה.
זה לא הולך להשתנות בכל פעם שלחזר באמצעות לולאה כלשהי,
כך אתה עושה עבודה מיותרת.
באותו הזמן אתה צריך לדעת, במאמר מוסגר, כי מהדרים כמו קלאנג בימים אלה
פותח במשך שנים רבות,
וסופרים מהדרים, מתכנתים, הם די חכמים.
וכך מתברר שהצלצול ואחר מהדרים באמת יכולים להבין את זה,
בסדר, כן, אתה כתבת strlen במצבך,
שטכני אומר שאנחנו היינו קוראים את זה שוב ושוב ושוב.
אבל מהדרים חכמים באמת יכולים לייעל את אלו סוגים של החלטות משתמש עניות
מתוך הקוד שלך לתיקון דברים.
>> אז פשוט תבין שלפעמים המהדר הוא יותר חכם מאיתנו
ויהיה סוג של להסתיר את הטעויות שלנו.
אבל בהחלט כשמדובר בקבוצות בעייתיות וכדומה,
אל תחשבו על החלטות עיצוב יסוד השגויות האלה
פוטנציאל מהסיבה הפשוטה שאנחנו הייתם עושים הרבה יותר עבודה
ממה שבאמת צריכים לעשות. אבל כמה עבודה יותר?
במקרה של שלום עולם, בואו נתחיל להכליל את גודל הבעיה.
מה אורכו של הבעיה או גודל הבעיה
כאשר המילה שהמשתמש הקליד בהוא שלום?
זה כנראה 5, אולי 6. פלוס או מינוס 1. לא משנה מה.
זה כל כך קרוב שפשוט נתקשר אליו 5.
>> אז מה גודל הבעיה כאן כשמנסה להבין את האורך של שלום?
זה 1, 2, 3, 4, 5, 6 ואולי לתו האחרון, אבל בואו להכליל שכn.
אז n, בדיוק n משתנה, הוא מה שמדעני מחשב יהיו בדרך כלל להשתמש
כדי לתאר את גודל בעיה, ובעיה ביד היא כמה זמן הוא שלום?
כמה זמן ייקח strlen?
זה לוקח על סדר פעולות n, שבו כל צעד הפירוש יסתכל אופי,
מסתכל על אופי, תסתכלו על אופי.
והיה לנו את הדיון הזה לפני כמה זמן, מספר הפעולות לוקח משהו.
היום הראשון בכיתתנו שכולם יעמדו במבוכה,
ואז כולם התחיל בזוגות אחד עם השני
כדי ממש לספור באופן אידיאלי כמה אנשים היו בחדר.
ואנחנו גם עשינו עוד דבר לפיו אם אני במקום עשיתי את זה בדרך בית הספר הישנה
רק בהתחלת 1, 2, 3, 4, 5, 6 וכן הלאה,
שגם הגודל שהבעיה היה של n גודל. היו שם אנשי n בחדר.
אבל אני יכול לזרז את זה, נכון? סגנון בית הספר יסודי אני יכול להתחיל לספור ב2s.
2, 4, 6, 8, 10, 12. וזה מרגיש כל כך הרבה יותר מהר, ואכן זה הוא.
זה ממש במהירות כפולה, אבל שוב, אם 400 אנשים נוספים נכנסו לחדר הזה
בבת אחת, האלגוריתמים האלה ייקחו עוד 200 400 או אולי צעדים.
>> אבל לעומת זאת, אם אנחנו באמת מקבלים חכמים ואנחנו במקום כולכם סופרים את עצמכם,
זוכר איך אלגוריתם שעבד.
כולכם קם. תן לי מהר קדימה לזה.
כולכם קמו, שהסתדרת בזוגות, אז חצי מכם התיישבו,
המחצית מכם התיישבה, חצי מכם התיישבו,
ועל כל איטרציה של לולאה זה משבוע 0, חצויי בעיה ביד
והלך לn / 2, אז n / 4, אז n / 8.
והמשמעות של זה היא שאם 400 אנשים נוספים נכנסים לחדר, לא עניין גדול,
זה ייקח לנו עוד סיבוב 1, לא 400 עוד סיבובים, ולא 200 יותר כדורים.
וכך הסיפור שספרנו לפני כמה זמן הייתי צריך לעשות משהו עם זה.
קו אדום זה כאן הוא ליניארי, זה ישר, ובה כיתוב כn
כי כגודל בעיה גדל,
אם האלגוריתם או התכנית שבה אתה פותר את זה לוקח צעדי n,
נוכל לשרטט אותו כקו ישר שבו זה לוקח יותר זמן בגודל גדול יותר של הבעיה.
וגישת twosies, ספירה 2, 4, 6, 8, עדיין בקו ישר, רק קצת יותר טובה.
זה לוקח קצת פחות זמן, כך שהשורה הצהובה היא מתחת לקו האדום לנקודת נקודה.
>> אבל אפילו טוב יותר היה זה גביע קדוש של מה שאנחנו מכנים זמן לוגריתמים
שם גם אם שוב נכפיל את מספר האנשים בחדר,
נכפיל את הגודל של ספר טלפונים מהיום הראשון של כיתה,
לא ביג דיל, זה לוקח מדמיע עמודים 1 יותר, לוקח עוד 1 לשבת
כדי לפתור בעיה זו גדולה פי שניים.
וכך בשיחה שאנחנו מקבלים עכשיו להתחיל לשכב
איך בעצם לפתור בעיות ביעילות
אם תיקח בחשבון הפשוט ביותר של בעיות מסוג זה?
תניח שיש לנו 8 דלתות שמאחוריו כמה מספרים,
וכל אחד מהמספרים האלה אינו ממוין בכל דרך,
הם מספרים שלמים רק אקראיים מאחורי הדלתות האלה,
ואנחנו שואלים את השאלה איך אתה הולך על מציאת המספר - מי יודע -
7 מאחורי הדלתות האלה?
מה אתה, אנושי, היה עושה כדי למצוא לי את המספר 7
אם שוב כל אחד מאלה הם דלתות ולראות שיש לך ערך כדי לפתוח דלת?
מה האלגוריתם שלך יהיה אולי?
>> [תגובת תלמיד לא נשמעה] >> אז להתחיל עם השמאל ולפתוח דלת, פתח את דלת, פתח את דלת.
ובמקרה הגרוע ביותר, כמה זמן זה ייקח לנו למצוא את המספר 7?
ושוב, הם לא מסודרים, כך שזה לא קל כמו, ובכן, אני עומד לפתוח את דלת 7.
זה יכול לקחת אותנו, מקסימאלי, 8 צעדים.
במקרה הגרוע ביותר, 7 הם אקראי ממש בסוף של שורת דלתות,
כך שייתכן שנהיה עליך לנסות את כל דלתות n.
אז שוב כאן, נראה שיש אלגוריתם ליניארי.
למעשה, עשינו את זה רק לפני כמה שנים.
אחד מקודמיך היה תיגר עם זה בדיוק
שם לא הייתה לנו גרסה דיגיטלית, שהיינו במקום לוח
עם כמה חתיכות של נייר עליו.
ומה שחשבתי שהיית צריך לעשות זה לקחת מבט מהיר לאחור על איך זה הלך,
אחת ההזדמנויות הטובות ביותר המביכות ביותר ואולי על במה
יש הפגנה כאן על סנדרס.
היו לנו 2 שורות של מספרים.
אנחנו רק הולכים להסתכל על מה שקורה כאן עם שון לחלקו עליון של שורות אלה.
אם אף אחד לא מתנדב שוב בCS50,
היו לנו את ברכתו של שון כדי לשמור על זה מול מצלמה,
לכן הוא יודע שמאה אנשים כבר צופים בזה עכשיו לשנים.
אבל שון עשה עבודה מדהימה - או שהוא - במציאת קשר למעשה מספר מסוים.
>> אז בואו לראות איך הוא פתר אלגוריתם זה כדי שנחדש את השיחה הזו לפני זמן רב
של איך אנחנו מוצאים את הדברים ביעילות.
[מלאן בוידאו] לא הסתרתי את מספר 7 מאחורי הדלתות האלה,
אך חבוי בחלק מהדלתות אלה, כמו גם מספרים אחרים שאינם שליליים,
והמטרה שלך היא לחשוב על השורה העליונה של מספרים כפשוט מערך
או סתם רצף של פיסות נייר עם מספרים שמאחוריהם,
והמטרה שלך היא, באמצעות המערך העליון רק כאן, תמצא לי את המספר 7.
ואז אנחנו הולכים לביקורת איך ללכת על עושה את זה. >> בסדר.
[מלאן] מצא אותנו המספר 7, בבקשה.
[שחוק]
[מלאן] מס [שחוק]
5, 19, 13, [שחוק]. זה לא שאלה מכשילה.
1.
[שחוק]
בשלב זה הציון שלך הוא לא כל כך טוב, אז אתה יכול גם להמשיך. [שחוק]
3.
תמשיך. למען אמת, אני לא יכול שלא לתהות מה עוד אתה חושב על. [שחוק]
רק השורה העליונה, כך שיש לך 3 שמאל. אז תמצא לי 7.
[סטודנטי ממלמל]
[מלאן] 17.
[סטודנטי ממלמל]
[מלאן] 7! [מחיאות כפות]
>> אז ביום רביעי שנוכל לצלול לתוך זה ואלגוריתמים מתוחכמים יותר למציאת דברים.
לעת עתה נשאיר אותך עם שון ולראות אותך ביום רביעי.
[CS50.TV]