ג'ייסון הירשהורן: הברוך הבא, כולם, עד שבוע 6. אני שמח לראות את כולכם בריא ושלמים לאחר חידון 0, כי אני יודע ש היה קצת מחוספס. אבל לשמחתי, כל מה שאתה עשה טוב מאוד. וכך הוא נפלא. אם אתה בקטע שלי, נתתי לי ביותר מכם לגבות החידונים שלך כבר. כמה מכם, אני נפגש אחרי השיעור. ואם אתה סטודנט והארכה אתה לא קיבלת את החידון שלך בחזרה עדיין, TF שלך הוא כנראה עובד על זה ולדירוג זה, ויקבל אותו בחזרה אליך בהקדם. אז תלמידי הסיומת שלי שהם צופה כרגע - בתקווה לחיות - אני אקבל את החידונים שלך זמן קצר גם כן. סדר היום שלנו להיום הוא כדלקמן. ראשית, אנחנו הולכים לעבור על כמה משאבים שCS50 מספק לך. אנחנו הולכים לעבור על חידון 0 הבאה, ו אני מוכן לענות על כל שאלה שאף אחד יש על בעיות מיוחדות. ולאחר מכן, נהיה הולך על קובץ I / O והבעיה מוגדר 5. אלה שני הנושאים האחרונים ייקחו את חלק הארי של סעיף היום. אני שם את הרשימה הזאת כל שבוע כמו תזכורת לכולכם, אבל של ליבה סעיף, יש לנו רק 90 דקות - אנחנו הם לא יוכלו לכסות את כל מה שאני אשמח לכיסוי בשבילכם. אבל יש להם המון משאבים עבורנו לך לצייר על כפי שאתה להכיר החומר והעבודה דרך הבעיה שלך קובעת. תזכורת לכך שיש לי באינטרנט טקסט תיבה, שהוקמה כדי שתוכל למלא אם יש משוב בשבילי, הן חיוביות והן בונה, על סעיף. כתובת האתר שנמצא ממש כאן למטה. אז בבקשה, קח רגע אם יש לך משוב, בין אם בסעיף, או אחריו, או אחרי שאתה לראות את הווידאו באינטרנט, כדי לתת לי המשוב שלך. אני באמת מעריך את כל וכל זה. אז אני כבר נהלתי שיחות קטנות עם הרבה שלי תלמידים בכל ימות השבוע - כפי שאני מוסר חידוני גב, מדבר על כמובן, לראות איך אתה עושה. ונושא אחד יש לבוא שוב ו מעל במדבר על - ב בפרט - בעיה קובעת. ויש לי במארז נושא זה על הלוח עכשיו. בעיקרו של דבר, יש הבדל בין הפיכת במשהו שהוא נעשה בצורה נכונה ומשהו שנעשה כן. רוב האנשים כבר עושים נפלאים במונחים של תקינות - של 5 או 4 של על כל psets. רוב האנשים מקבלים אלה כל הזמן. עם זאת, רק בגלל שאתה עשית משהו נכון זה לא אומר שיש לך עשה משהו כמו באלגנטיות, או ביעילות, או כמו נקי כמו שאתה היה יכול לעשות את זה. וזה מה שהעיצוב - ובמידה, בסגנון פחותה - צירים הנן ל. אז אני דוחף את כל מה שאתה, וTFS האחר הם דוחפים לך חבר 'ה, לתורו לא רק בדברים שהם נכונים, אבל להפוך בדברים שהם מקודדים היטב. לא עושה מיותר עבור לולאות, לא חישוב מחדש של משתנים אם אין לך. לדוגמא, במבט לאחור לבעיה להגדיר 4, כאשר הנחת הלבנים על מסך, כל שורה - כל לבנה ב שורה נתון יש את אותה קואורדינטה y - באותו הגובה לתאם. כך שקואורדינטת y לא צריכה יחושב בתוך הפנים מקונן ללולאה שסביר להניח שאתה משמש לשים את הלבנים האלה על המסך. זה רק צריך להיות מחושב בכל פעם שעברת שורה או עבר את שורה. אז אומר שאם יש 10 לבנים ב שורה, כל לבנה יכולה להיות אותה קואורדינטת y, ושקואורדינטת y יכול פשוט להיות מחושב פעם אחת עבור כל אלה. זה לא צריך להיות מחושב 10 פעמים, ולא עושה את זה צורך החישוב שקורה בפועל קריאה לפונקציה - הקריאה לפונקצית gracked החדשה. אז אם זה היה קצת מבלבל עבור לך, באופן כללי יותר, דברים ש לא צריך לקרות בכל פעם מחדש אתה עובר דרך לולאת FOR לא צריך להיות לשים בתוך לולאת FOR, ולא צריך קורה כל פעם שאתה הולך דרך לולאת FOR. עוד דוגמא עיצוב טובה שראינו בשבוע 3 ל15, אתה יכול לשמור אחר אפס. לכן, כאשר אתה לאתחל את הלוח, אתה לחסוך - במשתנה גלובלית, אולי - x ו-y-לתאם של אפס. ואז כל פעם שאתה - בפונקצית המהלך שלך, בכל פעם שאתה עושה מהלך מוצלח, שתעדכן מיקומו של האפס. שיציל אותך מהצורך לעשות מקונן ללולאות להסתכל דרך לעלות בכל פעם בפונקצית המעבר שלך ולמצוא את אפס, או למצוא את האריחים, ולאחר מכן לבדוק מה הלאה אליו. במקום זאת, יש לך את מיקומו של אפס, אתה יכול רק להסתכל למעלה, למטה, ולשמאל וימין שלו, כדי למצוא האריח שחיפשת. אז במונחים של התוכניות שאנחנו כתיבה, הם אף פעם לא גדולים מספיק כי חלק מהחלטות עיצוב אלה הם באמת הולכים לעכב שלך תכנית, או לגרום לו לפעול לאט יותר, אפילו או אולי נגמר לו זיכרון. אבל אנחנו עדיין דוחפים אותך החבר 'ה לכתוב אלגנטי וכ קוד יעיל ככל האפשר. אז אם אתה עושה בסופו של כתיבת דברים שיש להם גדול יותר באופן משמעותי היקף, הם יהיו כתובים בטוב לעצב בנוסף להיותו נכון. אז מספר שיש לך הביא את זה. זה משהו שאנחנו מחפשים - משהו שאנחנו הולכים להמשיך לדחוף אותך החבר 'ה על. אם אי פעם יש לך שאלות כלשהן על עיצוב של התכנית שלך, אתה מוזמן כדי להגיע אליי, ואני שמח ללכת דרך התכנית שלך איתך, ולהצביע על כמה מהעיצוב החלטות שאתה עשית, ותיתן לך קצת הצעות על איך לעשות את זה אפילו החלטות עיצוב טובות יותר. אז אנחנו הולכים להמשיך הלאה לדבר על חידון 0. לפני שאנחנו עושים את זה, עושה לאף אחד יש לך שאלות על מה אני כבר כיסיתי עד כה? [קול רשרוש] ג'ייסון הירשהורן: שבע שניות. על אישור. בואו נדבר על חידון 0 קצת. יש רובכם החידון שלך בחזרה של 0. אם לא, אני מקווה אתה זוכר את זה קצת. אבל אם אתה כבר לקח 0 חידון, אז אתה גם יש להם גישה לאינטרנט בפורמט PDF מדגם הפתרונות. האם יש למישהו שאלות לפני אנחנו קופצים לחומר של השבוע על בעיה מסוימת בחידון - 0 מדוע התשובה היא מה זה? האם מישהו מבולבל על שום דבר? גם אם יש לך הבעיה נכונה, אבל רק רוצה לי להסביר את זה קצת יותר, אני שמח לעשות זאת כעת. אז אני שואל אותך חבר 'ה כדי לבוא מוכן עם כמה מחשבות על חידון 0. אז מי הייתי רוצה לקבל אותנו התחלתי עם שאלה או להגיב על חידון 0? [רשרוש נייר] ג'ייסון הירשהורן: לא לכל אחד עשה בצורה מושלמת. אז אני יודע [צוחק] שם צריך להיות כמה שאלות על חידון 0. על אישור. כן. Ompica. OMPICA: מספר 10. ג'ייסון הירשהורן: מספר 10. איזה מהם היה מספר 10? OMPICA: - ג'ייסון הירשהורן: אני haven't - OMPICA: כולל - ג'ייסון הירשהורן: מספר 10 היה שמונה לi - כתיבת שמונה עד i? OMPICA: כן. ג'ייסון הירשהורן: אישור. אז יש לי שאלה נוספת שאתה יכול שאל היה האם אני רואה את הנולד? התשובה היא כן. בסעיף לפני החידון, שאלתי אתם קוד שני סטרלינג ו שמונה עד i. שניהם קרו לי מופיע בחידון. כך אני מקווה, ששילמת תשומת לב לכך. ואם היה לך, אז היית צריך כנראה עשה טוב על שני אלה. אבל שמונה ל i, אנחנו לא באמת קוד זה בכיתה, אבל זה היה, שוב, שאל בחידון. אז כמה דברים לקחת שים לב, כאשר קידוד שמונה עד i. הדבר הראשון, לכל השאלה, היה זה שהיית צריך לבדוק אם המחרוזת היה שווה לריק. כמה אנשים ניסו לבדוק בשלב מאוחר יותר בתכנית אם של סוגר הייתי - כך אופי ספציפי שב מחרוזת - היה שווה לריק. אבל זכור, null שהוא במהותו - זה טוב לחשוב על null כמצביע אפס - מצביע לאפס - מקום בזיכרון שבו אתה לא יכול לגשת אליו. אז אם משהו שווה לריק, אתה יודע שזה לא אותחל, או שאין שום דבר שם. אז ים הוא כוכב char, s אני סוגר הוא char. כך שזה הגיוני להשוות s ל null, אבל זה לא סוגר לי לריק. אבל שוב - כך היה הדבר הראשון שהייתם אמור לעשות - בדוק כדי לוודא שאתה באמת יש מחרוזת אמיתית. בשלב הבא, אתה רוצה לעבור כל תו במחרוזת. וכדי שיהיה כמו סוגר של להיות אני, למשל, אם אני הוא איטרטור שלך. ולקחת את האופי הזה, ו לקבל הערך האמיתי שלה. זה שיש לך מאוחסן כchar, אבל ערך ASCII לאפס - אפס כדמות - הוא לא ממש שלם אפס. זה מספר אחר שאתה יכול להסתכל למעלה בטבלת ASCII. אז דרך אחת לתקן את זה - כנראה הדרך הטובה ביותר כדי לתקן את כי - הוא לגרוע ממנו ערך התו - אפס כדמות. ציטוט אז מינוס אחת, אפס, עוד ציטוט אחד. שייקח את כל מה שיש לך מספר כchar, ולקבל את זה שווה את המספר כמספר שלם בפועל. וזה דומה מאוד לגישה הרבה אנשים לקחו ב בעיה להגדיר 2, עם קיסר וViginere - צפנים אלה, כאשר אתה היו סיבוב שלהם. אז אחרי שיש לו כמספר מ אפס עד תשע, ואז - בהתאם לאן זה הולך במספר הסופי - אתה צריך להכפיל את זה על ידי כוחו של 10. יש אנשים שעברו מהגב ל קדמי, והתרבה ​​הבודד מספר על ידי כוחו של 10. חלק מהאנשים עברו מ מלפנים לאחור - וכך לקח הגבוה ביותר להורות מספרים הראשונים - ותציל אותם ב משתנה דלפק הגלובלי. ולאחר מכן בכל פעם דרך ל לולאה, תכפיל את זה ענק גלובלי נגד משתנה על ידי 10, כדי להפוך מקום לתו הבא. אז זה היה קצת מבלבל בלי לי לכתוב את זה על הלוח. אבל הפתרון לדוגמא הוא זמין לך. אבל אלה היו הדברים הגדולים אנחנו מחפשים. גם סימון כדי לוודא שכל אופי אישי אכן היה אופי בין אפס ותשע, ולא איזו דמות אחרת, כמו, למשל. אלה היו הדברים שאנחנו מחפשים בשאלה הזאת. האם זה עונה על השאלה שלך? OMPICA: כן. ג'ייסון הירשהורן: אישור. האם יש שאלות אחרות על חידון 0? מה עם קומפילציה? כולם להרכיב נכון? לא. היו שם - [צוחק] כל שאלות על תהליך הידור? וואו. [רשרוש נייר] ג'ייסון הירשהורן: כן. מייקל. מייקל: האם מספר 7 - אקראי? ג'ייסון הירשהורן: מספר 7. מספר 7 היה מקבל מספר שלם אקראי. מצוין. אז אתה נתון מספר שלם ו השלם b, ואתה רוצה אקראי שלם בין A ו-B. אנחנו בעצם יכולים לכתוב את זה על הלוח, כי זה אחד הייתה שורה אחת של קוד - דרך אחת לעשות את זה. אז אנחנו נתנו drand כמו פונקציה שאנחנו יכולים להשתמש בו. ומה drand - בהנחה שזה היה זרע - מה drand לחזור? מיכאל: לצוף בין 0.0 ו1.0. ג'ייסון הירשהורן: מספר - כן. מספר בין 0 ל -1. וכך יש לנו ב 'ו. ואז יש לנו המספר האקראי שלנו בין 0 ל -1 שניתן לנו על ידי drand. יש אנשים שניסו לשים ב, או מינוס b , או משהו בתוך אלה סוגריים. זה אומר שהם טיעונים לפונקציה זו. drand אינו לוקח כל טיעונים - כמו getString עושה לא לקחת שום טענות. אז זה רק סוגריים פתוחים, קרוב פארן - וזה, כשלעצמו, הוא הקריאה לפונקציה. וזה נותן לך מספר בין 0 ל -1. כמובן, יש לנו את כל מגוון שמספרים יכולים להיות בו תגיד, אם b הוא 10 והוא 5, אנחנו באמת רוצה מספר עם טווח של 5. אז הדבר הבא שאנחנו צריכים לעשות הוא להכפיל את זה על ידי מינוס הטווח ב. אז בהנחה שהתרבתה. ושייתן לנו מספר בטווח נתון. ומאחר שטווח מסוים הבדל בין מינוס b. ולבסוף, זה יהיה רק ​​לתת לו מ-- אומר הטווח שבין מינוס b הוא 5, שייתן לנו מספר בין 0 ל 5. אבל אם הוא למעשה 5, אנחנו צריכים להגביר את טווח זה עד איפה זה בעצם אמור להיות, על ידי הוספה. כך שמקבל את זכות ההיגיון. ולאחר מכן, יהיה לך עוד שאלה? מיכאל: לא. אני פשוט מרגיש ממש מטומטם עכשיו. [צוחק] ג'ייסון הירשהורן: מס לא מרגיש ממש מטומטם. מספר האנשים נאבק עם שאלה זו. ואז, השאלה השנייה היא, drand, אתה אמר, נותן לך לצוף - חוזר לצוף. אבל פונקציה זו ביקשה למעשה למספר שלם שיוחזר. אתה לא צריך להטיל את זה באופן מפורש למספר שלם, כי אלה פעולות תהיה להתייחס אליו ככל לצוף - כמספר נקודה צפה. כמו הרצון הזה - גם אם זה הוא מספר שלם, זה יהיה יוכפל בצורה נכונה. כל הכפל יעבוד. אתה לא צריך להטיל את זה כאן. למעשה, אתה לא צריך להפיל אותו. שהיית - אם תטיל מספר זה בין 0 ל - 1 מספר אקראי, נקודה צפה - אז זה גם יהיה רק ​​0 או 1, ולכן אתה מאבד את כל הדיוק הזה. אבל בסופו של הדבר, כאשר אתה חוזר, זה באופן אוטומטי מקבל נשלח בחזרה למספר שלם. אז אתה לא צריך לעשות שמטיל את עצמך. אז זו הייתה התשובה ל שאלה זו, מספר 7. יש עוד שאלות על חידון 0? כן, אנני. אנני: כאשר אנו משתמשים ברקורסיבית - כאשר אנו משתמשים בלולאות איטרטיבי? ג'ייסון הירשהורן: כאשר אתם משתמשים רקורסיבית - כך באופן כללי יותר, יתרונות וחסרונות של רקורסיה לעומת גישת איטרטיבי. מישהו יכול להציע פרו או קון? בבקשה? לא ניתן לאף אחד. מי יכול להציע פרו או קון? [רשרוש נייר] סטודנט 1: רקורסיבי הוא פחות קידוד - פחות הקלדה? ג'ייסון הירשהורן: אז בדרך כלל, רקורסיה במיוחד, פונקציה - או אלגוריתם כמו מיזוג סוג - אשר משאיל את עצמו לגישה רקורסיבית - יכול להיות יותר פשוט קוד באופן רקורסיבי. ופשוט יותר הגיוני לעשות את זה באופן רקורסיבי. כך שיהיה מקצוען לרקורסיה. אחר? כן? תלמיד 2: קון לרקורסיה - היא משתמשת בזיכרון רב יותר. ג'ייסון הירשהורן: אז בדיוק נכון. פונקציה רקורסיבית תהיה לשמור על הוספה ערימת מסגרות לערימה. אז אם אתם פועלים בהרבה מספרים, וצריך לקרוא לזה לתפקד הרבה, אז אתה בהחלט יהיה תופס יותר זיכרון, ואילו גישת איטרטיבי רק לשים אחד מחסנית מסגרת במחסנית, כיוון כל זה קורה בתוך פונקציה אחת. כל יתרונות וחסרונות אחרים? כן. סטודנט 3: יתרונות לרקורסיה. אתה לא צריך לקבוע ב לקדם כמה פעמים קוד צריך להיות חוזר ונשנה. אתה יכול להיות מספר קבוע מראש של פעמים שאתה צריך לחזר, ולאחר מכן רקורסיה היא טובה יותר, כי זה לוקח את התוצאה הזו. ג'ייסון הירשהורן: אני חושב שזה נכון. אבל אני חושב שבשני המקרים אף פעם לא היית - כנראה שהיית קצת קלט מהמשתמש. או פונקציה זו תהיה קצת קלט שיקבע כמה פעמים זה צריך לרוץ. אז בדרך כלל, לא היית עושה את קוד קשה - אפילו בגישה איטרטיבית - איך הרבה פעמים לולאה שיש להפעיל. האם יש לך עוד שהיית לחשוב על, אנני? על אישור. אז אלה הם כנראה שני - פרו הגדול ביותר והגדול ביותר קון לרקורסיבית לעומת גישת איטרטיבי. על אישור. כל דבר אחר על חידון 0? בואו נעבור הלאה. אני קובץ / O. יש קצר נפלא השבוע בקובץ I / O שתקווה יש לך התבונן מרובה פעמים, והעריץ. הרבה עבודה נכנס לזה, ויש לי שמע את זה הוא בטירוף מועיל. אני כללנו גם הקישור בשקופית זו, במקרה לא היה לך הזדמנות לצפות בו 10 פעמים. לכן, אנחנו הולכים תעברו בקצרה על שלבים עיקריים לפתיחה ועבודה עם קבצים, ולאחר מכן אנחנו הולכים לצלול לתוך בעיה קידוד לפני בוחן את סט הבעיה. אז שוב, אני הולך לשים את זה על המסך, אבל אני הולך לדבר על רק רגע על מה שאנחנו עושה כאן עם קובץ I/O-- מה זה אומר? זה אומר שאנחנו יכולים ליוצרנו תוכניות, ולאחר מכן יש לנו תוכניות יציאה, ולא עשה כל השפעה על העולם שמחוץ לתכנית שלנו. אבל כאשר אנחנו מתחילים בעבודה עם קבצים - שניהם קוראים אותם וביצירה אותם - יכול להיות לנו השפעה כלשהי על עולם שמחוץ לתכנית שלנו. בדיוק כמו שאם Microsoft Word לא היה מסוגל כדי להפוך את כל מסמכי Word, ואז פעם אחת Microsoft Word כולך להפסיק, העבודה כבר לא תהיה, וזה היה באמת יהיה חסר תועלת. אנו סופו של דבר רוצים להיות מסוגל לכתוב תוכניות שיכולים להשפיע עולם הסובב אותם, הן על ידי לקיחת תשומות מורכבות - במונחים של קבצים ו באמצעות קבצים, ויצירה גם מעניין ותפוקות משכנעות - במונחים של סוגים שונים של קבצים של. אז בגלל זה אנחנו מתחילים ללמוד איך לעבוד עם קבצים. באופן ספציפי יותר, מה שאנחנו עושים הוא כדלקמן. זה פשוט מאוד. יש רק כמה צעדים, ו הם מופיעים כאן בקוד זה. אז אנחנו הולכים לעבור קו קוד זה על ידי קו. ראשית, אתה רואה מודגש - כאשר אתה עובד עם קובץ, ללא קשר לסוג קובץ זה, אתה צריך לפתוח אותו. וכי הוא בקריאה לfopen - ממש כאן. אתה כולל את שמו של הקובץ. אם הקובץ לא נמצא בספרייה שלך, או התיקייה שבה בתכנית זו חיי, אז אתה גם צריך לכלול נתיב שבו קובץ שהוא. אנחנו הולכים להניח שזה קובץ שנקרא "text.txt" - מסמך טקסט פשוט - הוא ב אותה תיקייה תכנית זו היא. אז זה עוד דבר שכדאי דעה - שאם אתה רוצה לפתוח קובץ במקום אחר, שאתה באמת צריך לכלול את מיקומו. שנית, אתה יכול לעבור לויכוח fopen, וזה מה שאתה רוצה לעשות עם הקובץ. ישנם שלושה נימוקים עיקריים ש אתה הולך לעבור לfopen. מי יכול לתת לי שלושה אלה? מי יכול לתת לי אחד מהם? כן. תלמיד 4: שם הקובץ? ג'ייסון הירשהורן: מצטער. שלוש טענות עיקריות שאתה יכול לעבור כטיעון השני לfopen. אתה צודק - שם הקובץ הוא את הטענה הראשונה. אבל הטיעון השני הוא fopen בדרך כלל שלושה מיתרים, ועל - כן. Aleja. Aleja: להוספה. ג'ייסון הירשהורן:, אם אתה רוצה לצרף לקובץ שכבר קיים. תלמיד 5: R לקריאה. ג'ייסון הירשהורן: R, אם אתה רוצה לקרוא מקובץ. סטודנט 6: W לכתיבה. ג'ייסון הירשהורן: וw, אם רוצה לכתוב לקובץ. אז במקרה הזה, אנחנו כותבים לקובץ, כך שיש לנו W. אתה פותח אותו, אתה גם צריך לשמור קובץ איפשהו, וזה עם קוד לצד שמאל של אופרטור ההשמה - אני יוצר מצביע לקובץ קרא, במקרה, בקובץ זה. אנחנו לא הולכים לדאוג מה דבר קובץ כובעים כל זה. די אם אומרים, שזה זמן רב זרם של אפסים ואחדים. וכך אנחנו הולכים להפעיל אותו ולהבין אותו. הדבר הבא שאנחנו צריכים לעשות - ו זה חשוב מאוד - בכל פעם שאתה פותח את קובץ - למעשה, בכל פעם שאתם קוראים malloc, עבור למשל, ולקבל כמה זיכרון ונסה ולשמור אותו במצביע, אתה תמיד רוצה לבדוק כדי לוודא כי הפונקציה לא תחזיר null. אז במקרה הזה, אנחנו בודקים לעשות בטוח שאנחנו בעצם פתחנו את להגיש בצורה נכונה, ולא היה אין שגיאה בתכנית שלנו. בשלב הבא, ברגע שאנחנו כבר בדקנו כדי לוודא שיש לנו קובץ עובד, אנחנו יכולים לכתוב, או לקרוא, או לצרף לקובץ. במקרה זה, אני פשוט מדפיס שורה אחת בקובץ זה. איך אני יודע את זה? ובכן, אני משתמש בפונקציה זו קרא fprintf. כל הפונקציות שאתה תהיה באמצעות בעת כתיבה ל, או קריאה מ, או המניפולציה קבצים תהיה דומה ל פונקציות שראיתם בעבר, אבל מתחיל באות F, עומד לקובץ. וfprintf, בניגוד להדפסה הרגילה שלנו אפליקציה, לוקחת טענה אחת נוספת, וזה הקובץ שבו אתה רוצה להדפיס את הקו הזה ל. אין לי שום דבר זכותו של Ohai. אין לי שלישי טיעון לprintf - או הטענה השנייה לprintf, טענה שלישית לfprintf, כי אני אין לי שום מצייני כאן. אני לא כולל כל משתנים. אבל שוב, fprintf וכל קובץ אלה פונקציות שפועלות עם קבצים בדרך כלל הולכים צריך את הקובץ שבו הם פועלים. לבסוף, הדבר חשוב האחרון לעשות הוא לסגור את התיק, בדיוק כמו עם - כל פעם שאנו malloc משהו, אנחנו רוצים לשחרר משהו, פן יש דליפת זיכרון - אנחנו רוצים כדי לסגור את הקובץ שלנו. אם תכנית זו יצאה ללא סגירה את הקובץ, רוב הסיכויים הם ששום דבר לא הולך לא נכון, במיוחד אם זה היה קובץ קטן. אבל זה בהחלט סגנון קידוד טוב ולתרגל תמיד לסגור את הקובץ שלך כשתסיים להשתמש בו. אז זה את היסודות של קובץ I / O. בטח כבר ראה את זה בעבר, או צפה בו בכך שקצר פנטסטי. האם יש למישהו שאלות, לפני אנחנו הולכים לכמה קידוד בפועל בעיות, על קובץ I / O או צעדים אני פשוט ניגשתי? [הקלדת SOUNDS] ג'ייסון הירשהורן: האם אתה יש לך שאלה, אבי? AVI: מס ג'ייסון הירשהורן: אישור. אני הולך לחכות עוד שבע שניות. [צוחק] זה טיפ ממש טוב. אתם פשוט לא אוהבים לשאול שאלות. זה בסדר. על אישור. אז הבעיה האימון הראשונה שלנו היא, שאנחנו הולך לשכפל את הפונקציה של שורת פקודת כלי שאתה כנראה השתמש בעבר - עותק - עותק הכלי. אם תקליד cp ולאחר מכן להעביר אותו שני טיעונים למסוף שלך, אתה יכול להעתיק קובץ. וזה מה שאנחנו הולכים לכתוב עכשיו. אז שוב, קוראים מתוך שקופית זו, הייתי לך לכתוב תכנית שלוקחת שתיים ועוד שתיים של שורת הפקודה רק טיעונים - קובץ מקור וקובץ יעד - ומעתיק את תוכנו של המקור קובץ לקובץ היעד בית אחד בכל פעם. אז זה הרבה לבקש. שוב, גישה טובה לזה היא לא ללכת ישר לקוד C, אבל לשבור אותו לתוך כמה צעדים. ראשית, לחשוב על ההיגיון - בדיוק מה שאני מבקש ממך לעשות - ולהבין את כל צעדים לבעיה זו. לא ב-C, רק בחלק pseudocode, או אפילו מודל המנטלי של מה קורה. בשלב הבא, ברגע שיש לך את pseudocode למטה, להבין איך pseudocode מפות על גבי כלים ודברים שיש לנו למד להשתמש בג ולבסוף, ברגע שיש לך את כל זה יחד, אתם יכולים לקודד את הבעיה. קח 5-10 דקות לעבוד על הבעיה הזאת. אני אשים את ההוראות לגבות בשני. ואז אנחנו הולכים לעבור על pseudocode, וקוד זה לחיות כקבוצה. אם יש לך שאלות בזמן שאתה עובד על זה, אל תהסס להעלות היד שלך, ואני אבוא סביבו ולענות עליהן. תלמיד 7: האם אני יכול לסחוב פיסת נייר? ג'ייסון הירשהורן: מה קורה? [הקלדת SOUNDS] ג'ייסון הירשהורן: אישור. בואו נלך על pseudocode הראשון, ו אז אני אתן לך עוד כמה דקות כדי לסיים קידוד. מי רוצה להתחיל אותי עם השורה הראשונה של pseudocode עבור פונקציה זו? תלמיד 8: ודאו כי ניתנו לך שני קבצים. ג'ייסון הירשהורן: אישור. ואם אנחנו לא? תלמיד 8: הייתי להחזיר 0. ג'ייסון הירשהורן: האם עלינו להחזיר 0? תלמיד 8: חזור - לריווח. סליחה. ג'ייסון הירשהורן: כן. כנראה שלא 0. בגלל 0 אומר הכל היה טוב. על אישור. אז זה הקו הראשון של pseudocode. למי יש את הקו השני של pseudocode? סטודנט 9: פתח את שני הקבצים? ג'ייסון הירשהורן: פתח את שני הקבצים. בסדר? סטודנט 10: בדוק אם הקובץ הוא NULL? ג'ייסון הירשהורן: בדוק כדי להפוך בטוח שלא הם NULL. במאמר מוסגר - סלאש 0 - הוא שNULL? סטודנט 11: מס ג'ייסון הירשהורן: זה לא NULL. זה נקרא שליחות קטלנית NULL. זה בעצם כוסמין רק עם אחד אני. אז בודק משהו נגד זה - זה בעצם אופי - כך בודק משהו נגד ה לא אותו דבר כמו בדיקה כדי לראות אם הוא שווה NULL. וכמה אנשים - על החידונים שלהם והבעיה שלהם סטים - יש לי שניים מאלה מבולבלים. אבל שני אלה הם למעשה שונה. אחד מסתיים מחרוזת - אחד הוא מצביע ל0. סטודנט 12: למה לא היית לבדוק כדי לוודא שהקבצים הם לא NULL לפני שאתה פותח אותם? חוסך כל כך פתוח: ג'ייסון הירשהורן משהו בקובץ זה. ואם תחזרו לכאן - כך הקו הזה - fopen - אתן לך כתובת וחנות כתובת שבקובץ אם זה עובד. אם זה לא עובד, זה יהיה לאחסן NULL - סטודנט 12: אוה. על אישור. תפסתי אותך. ג'ייסון הירשהורן: בקובץ. אז אתה לא יכול לבדוק NULL לפני שפתחת אותם. NULL אומר משהו לא לעבוד בצורה נכונה. על אישור. אז לבדוק כדי לוודא שגם אינו? או הם? מה אנחנו חושבים? אנחנו נלך עם זה. סטודנט 13: האם. ג'ייסון הירשהורן: האם? לא הוא? סטודנט 13: האם. ג'ייסון הירשהורן: אישור. אנחנו נראים לי קצת הסכמה על כך. גם הוא NULL. אוקיי, השורה הבאה של pseudocode. מי לא נתן לי קו עדיין? אנחנו נחכה לך. כן. סטודנט 14: אתה חייב לקרוא מהקובץ הראשון? ג'ייסון הירשהורן: אישור. סטודנט 14: או שאנחנו משתמשים fscanf או משהו כזה את הקובץ הראשון? ג'ייסון הירשהורן: אז אנחנו רוצים לקרוא מהקובץ הראשון ו-- בואו נשים את זה כאן. לקרוא מקובץ המקור. ואז, מה עושים אחרי ש לקרוא מקובץ המקור? מישהו אחר? סטודנט 15: כתוב אל קובץ היעד? ג'ייסון הירשהורן: אנחנו כותבים כדי קובץ היעד, ו-- על אישור. מה עוד חסרים לנו? מישהו אחר שלא נתן לי שורת קוד עדיין - של pseudocode. כן. סטודנט 16: אולי אתה תמיד יכול לבדוק אם יש משהו לקרוא ל, כמו השורה הבאה? כי הם כמו השורה הבאה, לראות אם היא קיימת. [אלקטרוני ביפ] ג'ייסון הירשהורן: אופס. זה תוכנת יומן שלי. כן? סטודנט 16: כן. ג'ייסון הירשהורן: אז תן לי לי את זה עוד פעם אחת. סטודנט 16: בדוק אם יש עדיין שורה הבאה מ קובץ מקור לקריאה. ג'ייסון הירשהורן: אישור. אז אנחנו לא קוראים את השורות - קראו בתים כאן - אבל אתה צודק. אנחנו רוצים לקרוא ולכתוב עד אין יותר בתים. על אישור. ולכן אלה באמת צריכים להיות מדורגים קצת, כי הם מתחת לשם. נכון? עד שאתה מחוץ לבתים, אנחנו הולכים לקרוא מקובץ המקור ולכתוב לקובץ היעד. ואז, מה שעבר קו של pseudocode? מישהו שלא ניתנו לי משהו עדיין. סטודנט 17: סגור את הקבצים? ג'ייסון הירשהורן: בדיוק. לסגור את התיקים. אז יש pseudocode שלנו. אני הולך לשים את pseudocode לתוך gedit, ובתוך כמה דקות אנחנו יהיה לקודד את זה ביחד. על אישור. תן לנו להתחיל כקבוצה. נישאנט, יש לי הקובץ החדש שלי. אני רק פתחתי את זה. מסמך ללא כותרת 1. מה הדבר הראשון שאני צריך לעשות? נישאנט: כלול ספריות? ג'ייסון הירשהורן: אישור. מה ספריות? נישאנט: stdio.h, stdlib.h, אני מאמין? ג'ייסון הירשהורן: אישור. מהו stdlib ל? נישאנט: שכחתי. ג'ייסון הירשהורן: אישור. אז כולל stdio. מה אני צריך לעשות עוד לפני אני מתחיל קידוד? נישאנט: כתוב בכותרת? ג'ייסון הירשהורן: איך אני מקבל את זה בצבע? [קולות חציצה] נישאנט: איך אתה מקבל את זה בצבע? ג'ייסון הירשהורן: איך אני צובע את הקידוד? נישאנט: אני לא יודע. אה. לשמור. ג'ייסון הירשהורן: שמור. כן. אני צריך לשמור אותו כקובץ. ג. אז לשמור אותו על שולחן העבודה כcp.c. מתוק. ואם אני רוצה להגיע לסגנון מלא נקודות, מה אני צריך כולל בחלק העליון? נישאנט: אתה יכול לכתוב את שמך, שם של התכנית, והמטרה כמו גם של התכנית? ג'ייסון הירשהורן: נראה טוב. מצוין. אז אתה כבר התחיל אותנו בצורה מושלמת. # Include - אנחנו גם נכתוב - על אישור. אז אני חושב שאני מוכן ללכת. למי יש את שורת קוד הראשונה בשבילי - או השורות הראשונות של קוד ש זה ייקח כדי לספק אותנו ראשון להגיב בpseudocode? שלך. 18 סטודנט: לא צריך להיות int argc, ולאחר מכן * argv char? ג'ייסון הירשהורן: אני חושב אתה צודק. בואו לשנות אותו לint paren הראשי, פתוח, תכנית + int, פסיק, char argv *? ככה? 18 סטודנט: בסוגריים. ג'ייסון הירשהורן: בסוגריים. סוגר פתוח, סגור סוגריים, קרוב הורה. מושלם. עכשיו אני יכול לקחת את טיעוני שורת הפקודה. על אישור. לוודא שאנחנו מקבלים שני קבצים. אתה יכול לתת לי את זה גם כן. 18 סטודנט: אם argc - זה לא שווה 3. ג'ייסון הירשהורן: אם paren הפתוח argc לא שווה 3? 18 סטודנט: כן, אתה חוזר 1 או משהו כזה. ג'ייסון הירשהורן: מצטער. 18 סטודנט: 1 חזור או משהו כזה. ג'ייסון הירשהורן: 1 חזור. בסדר? גדול. פתח את שני הקבצים. מי יכול לעזור לי לפתוח את שני הקבצים? מי לא נתן לי קוד עדיין? קורט? קורט: אז כל כמוסות מקור כוכב ה-F-אני-L-E. ג'ייסון הירשהורן: אני הולך להוציא את התנועות. אלה הם מגניבים. זה כמו Tumblr. 18 סטודנט: שווה fopen - ג'ייסון הירשהורן: שווה fopen? 18 סטודנט: paren הפתוח, argv, סוגר פתוח. ג'ייסון הירשהורן: המתן. סליחה. paren הפתוח. על אישור. 18 סטודנט: כן. תת argv 1. ג'ייסון הירשהורן: 1 Sub? 18 סטודנט: כן. Argv פתוח סוגר 1 - כן. ולאחר מכן פסיק, ולאחר מכן לחץ פעמים פתוחות ציטוט, r, ציטוט כפול, paren קרוב, פסיק. ג'ייסון הירשהורן: מתוק. ומה עם השני? 18 סטודנט: מאוד דומה, אבל במקום של S-R-C, היית קורא לזה D-S-T. ג'ייסון הירשהורן: אווו! אני אוהב את זה. 18 סטודנט: רק D-S-T. כן. ולאחר מכן argv, סוגר פתוח, 2. כן. ולאחר מכן w במקום r. כן. ג'ייסון הירשהורן: נהדר. הזוג הבא של קווים. כמו כן, אם יש למישהו דברים להוסיף קווים שעשינו, ירגישו חופשיים להוסיף אותם גם כן. בדוק כדי לוודא שלא הוא NULL. מי יכול לתת לי את הקוד אני צריך לספק את הקו של pseudocode? ארצ'ר. ארצ'ר: אם src שווה שווה NULL או DST שווה שווה NULL, ואז אתה חוזר - ג'ייסון הירשהורן: מה? ארצ'ר: החזר 2? ג'ייסון הירשהורן: חזרה 2. אז אם src paren הפתוח שווה שווה NULL, או - כל מה שthing's - צינור? צינור? אנחנו קוראים לזה צינור. צינור, צינור, DST שווה שווה NULL, לחזור 2. בסדר? עד שאתה מחוץ לבתים - אנחנו סוג של דילוג על שלב זה מ חלק pseudocode להולך לכאן. אבל עד שאתה מחוץ לבתים - מה זה נשמע כמו? איזה סוג של מבנה C - אבל אני לא משתמש במילת מבנה, כי אנחנו הולכים להתחיל להשתמש כי במקרים אחרים - אבל כלי C זה נשמע כמו? סטודנט 19: לולאה. ג'ייסון הירשהורן: לולאה. נשמע כמו לולאה. אז מי יכול לתת לי את השורה הראשונה של קוד הלולאה ממש כאן? גם אתה יכול לבחור איזה סוג של לולאה שאתה רוצה, אם אתה נותן לי הקו הזה של קוד. ישנם שלושה סוגים. אתה מקבל לבחור. הייתי מציע אחד מאלה. אבי. איזה מהם אתה רוצה? AVI: ל. ג'ייסון הירשהורן: ל. AVI: int i שווה לאפס. ג'ייסון הירשהורן: אישור. AVI: חלק זה אני לא בטוח. אבל האם אני פחות מגודל מקור כוכב? אני לא בטוח בזה. ג'ייסון הירשהורן: אישור. AVI: מכיוון שאתה רוצה גודלו של קובץ, נכון? ג'ייסון הירשהורן: אז זה כנראה לא לתת לנו את גודל בפועל להגיש בבתים. אז מה עוד יכולנו לעשות? מה הוא סוג נוסף של לולאה? או שאנחנו צריכים להישאר עם לולאת FOR? סטודנט 20: האם אתה יכול לעשות לולאת WHILE? ואז, מה שהיית עושה זה את היית - כי יש לנו * char לקובץ. אז אם אנחנו רק להגדיל כל כי עד שהיינו מוצא את תו NULL ב הסוף של זה? או לא, הוא שלא איך קבצים עובדים? ג'ייסון הירשהורן: אז אנחנו יכולים לשמור להגדיל כל char * עד שנמצאנו את NULL - סטודנט 20: בעיקרו של דבר להמשיך תו אחרי תו עד שפגענו סוף הקובץ. ג'ייסון הירשהורן: כן. אז זה מה שאנחנו רוצים לעשות. אנחנו רוצים להמשיך לקרוא, דמות על ידי אופי, עד שנגיע ל סוף הקובץ. סטודנט 20: כן. מצא - מה זה הסוף או תמרור עצור בסופו של קובץ טקסט. ג'ייסון הירשהורן: אישור. לכן, כאשר אנחנו מגיעים לסוף הקובץ - איך אנחנו יודעים שאנחנו כבר הגענו הסוף של קובץ? אם אני מתקשר - אז בואו צעד אחורה. מהי פונקציה? בואו נלך לקו זה ממש כאן. לקרוא מקובץ המקור. מי יכול לתת לי קו של קוד? סטודנט 21: fscanf? ג'ייסון הירשהורן: fscanf. על אישור. מה אם אני רוצה לקרוא, מאוד באופן ספציפי, בית אחד? סטודנט 21: אני לא יודע. ג'ייסון הירשהורן: אישור. אפילו פשוט יותר מאשר fscanf - מה הוא - אני רוצה לקרוא מקובץ מקור? לקרוא מקובץ מקור. מהי פונקציה - כן. 22 סטודנט: זה fread? ג'ייסון הירשהורן: fread. אני חושב שבא עם מקל כי אחד לעת עתה. איזה סוג של טיעונים אין fread לקחת? סטודנט 22: כנראה סוג הקובץ, ולאחר מכן מיקום בקובץ? ג'ייסון הירשהורן: מה אני יכול להקליד כאן כדי להבין איזה סוג של טיעונים fread לוקחת? סטודנטים מרובים: fread אדם. ג'ייסון הירשהורן: אדם fread וfwrite. נראה שהם מבלים יחד. אז fread לוקחת טיעונים כמה? סטודנט 23: ארבעה. ג'ייסון הירשהורן: זה לוקח ארבעה טיעונים. זה לוקח מצביע, גודל, וכי דבר, וזה מוזר, וכמה קבצים. בסדר? בואו לקרוא על זה כאן. "Fread הפונקציה קוראת memb n אלמנטים של נתונים, בכל בתים גודל ארוך, מהזרם שאליו מצביע להזרים, לאחסן אותם במיקום שניתן על ידי מצביע. " אז ארבע טענות. למה אני לא פשוט להעתיק את זה, ולהדביק אותו כאן. על אישור. אז מי יכול להתחיל למלא הטיעונים האלה בשבילי? אבי. AVI: להוציא את הריק. שים רק src. קח את המצביע ואת הכוכב. שים src. ואז - ג'ייסון הירשהורן: אז אני הולך להפסיק אותך לשם, כי זה לא נכון. אתה צודק עם src, אבל בי src צריך ללכת? [קולות חציצה] ג'ייסון הירשהורן: זה צריך ללכת לכאן. זה src - src שלנו הוא סוג. בואו נסתכל כאן. זה מבקש * סוג קובץ, אנחנו למעשה בדרך כלל רואה אותם ככה. אז זה מבקש טיעון של סוג קובץ * זרם המכונה שהוא src. בסדר? מה גודל של דברים לעשות אנחנו רוצים לקרוא? אני נתתי לך את זה ב בעיה תיאור. סטודנט 24: בית אחד בכל פעם. ג'ייסון הירשהורן: בית אחד. כמה גדול הוא בייט? הגודל שלו הוא בבתים, אז מה אני יכול לשים שם? סטודנט 25: אחד. ג'ייסון הירשהורן: אחד. נכון. הגודל שלו הוא בבתי יחידה, כך 1 הוא הבתים 1. כמה אני רוצה לקרוא בכל פעם. סטודנט 26: אחד? ג'ייסון הירשהורן: דבר אחד. אני רוצה לקרוא דבר אחד בגודל 1, ביס אחד בכל פעם. ואיפה אני יכול לשים אותו, ברגע שקראתי אותו? סטודנט 27: יעד? ג'ייסון הירשהורן: אז אני לא יכול לשים אותו ישר לתוך יעד. סטודנט 28: אתה הולך לשים אותו למצביע שלישי? סטודנט 27: ליעד. ג'ייסון הירשהורן: אישור. כן. סטודנט 29: אתה יכול להכריז על משהו לפעול כאחסון זמני קודם לכן. ג'ייסון הירשהורן: אישור. תן לי את זה. סטודנט 29: קובץ נוסף מצביע, אולי? ג'ייסון הירשהורן: אישור. אז זהו כוכב חלל - זה כוכב סוג מבוטל, כך שזה לא צריך להיות מצביע קובץ. ואם אני קורא בייט אחד, שבו יהיה מקום טוב כדי לאחסן בייט אחד? סטודנט 29: מערך? ג'ייסון הירשהורן: מערך. על אישור. ומה עוד משהו שהוא רק גודל בית אחד? סטודנט 30: char *? סטודנט 29: כן. ג'ייסון הירשהורן: char * לא בייט אחד. סטודנט 29: char. ג'ייסון הירשהורן: char הוא בייט אחד. נכון? אז בואו נקראים לחיץ הזה הוא גנרי שם המשמש לדברים האלה כדי לאחסן משהו באופן זמני. אז אני יוצר חיץ. נכון? אבל זה ייקח חלל *. אז אולי אתה צודק, שזה צריך להיות חיץ בגודל 0. אז הוא מאחסן אחד - נכון. מכיוון שזכות זו כאן - char חיץ הוא דמות, אבל זה לוקח חלל * - מצביע. אז אני יכול לעשות את זה ועכשיו החיץ הוא מצביע. מה עוד אני יכול לעשות? סטודנט ביום 31: שים את הכוכב הבא להיחרך. ג'ייסון הירשהורן: אני יכול יצר אותו char *. על אישור. מה זה עוד דבר שאני יכול לעשות? או בואו נלך עם זה. תו * חיץ, אז מה אני יכול לשים בפה? סטודנט ביום 31 ב: הצפת. ג'ייסון הירשהורן: הצפת. החיץ הוא מצביע לתו. ובמיקום זה, אנחנו מכניסים בייט של משהו שאנחנו כבר לקרוא אחד. כן. אבי. AVI: רק שאלה מהירה. האם אתה רוצה malloc חיץ? ג'ייסון הירשהורן: מי יכול לענות על שאלה זו? סטודנט 32: ובכן, זה לא ממש נקודה לכל דבר עכשיו, כך - ג'ייסון הירשהורן: אבל לעשות אנחנו רוצים malloc זה? סטודנט 32: אם היית עושה את זה כי דרך אגב, אני מניח, כן, כי היית צריך מקום אליו הוא יצביע ל. ג'ייסון הירשהורן: האם אנחנו צריך malloc זה? סטודנט 33: אם אתה הולך להשתמש בו מחוץ למעגל. ג'ייסון הירשהורן: האם אנחנו עומדים להשתמש בו מחוץ ללולאה? סטודנט 34: כן. סטודנט 35: המתן. האם אנחנו רוצים להכריז עליו בלולאה למעבר? ג'ייסון הירשהורן: אז אני מניח שיש לנו כמה בזמן פסאודו כאן שאנחנו מנסה להבין, כי שאנחנו לא הספקנו להגיע אליהן. אנחנו לא צריכים malloc זה. אנחנו פועלים בעיקריים, זה רק הולך לשימוש בתוך לולאה זה. היא לא צריכה להתקיים זה בחוץ. אז זה יכול להיות משתנה מקומי. יש לך מצביע משתנה מקומי. סטודנט 36: אבל זה לא להצביע לכל דבר. ג'ייסון הירשהורן: לא, זה לא אותחל לשום דבר. אבל אנחנו לא מתכוונים גם להשתמש בו. אנחנו הולכים לשים משהו ב זה הפעם הראשונה שאנחנו משתמשים בו. אז זה נראה בסדר. אז אנחנו לא צריכים malloc כאן. ואני חושב שזה בסדר כפי שהוא. על אישור. יש לנו את קו fread. בואו נעשה את השורה הבאה. אם אנחנו רוצים לכתוב לקובץ, מה שהוא פונקציה טובה להשתמש כדי לעשות את זה? סטודנט 37: Fwrite? סטודנט 38: fprintf? ג'ייסון הירשהורן: fprintf הוא אחד. מה עוד אחד? סטודנט 39: Fwrite. ג'ייסון הירשהורן: Fwrite. ולענייננו, fwrite, שראינו כאן, הוא כנראה הבחירה טובה יותר. זה לוקח ארבעה טיעונים גם כן. נישאנט, אתה יכול לתת שלי הטענות? נישאנט: Going הראשון של אחד להיות רק מאגר. ג'ייסון הירשהורן: אישור. נישאנט: אחד של השני פשוט הולך להיות 1. שליש הולך להיות 1. והרביעית הולכת להיות DST. ג'ייסון הירשהורן: האם יש למישהו כל שאלות על קו? זה נראה טוב. על אישור. אז עכשיו זה נראה כמו דבר אחד שאנחנו חסר - בעצם, בואו נכתוב השורה האחרונה זה. לסגור את התיקים. מי יכול לסיים אותנו כתיבה שתי השורות האחרונות האלה? כן. סליחה, מה שמך? לוסי: לוסי. ג'ייסון הירשהורן: לוסי. לוסי: src fclose ולאחר מכן יעד fclose. ג'ייסון הירשהורן: fclose, paren הפתוח, src, קרוב פארן, פסיק. וfclose - כן? לוסי: סוגריים פתוחים, DST ולאחר מכן פסיק. ג'ייסון הירשהורן: נהדר. ומה שאני צריך לכלול בסופו של הדבר? לוסי: להחזיר 0. ג'ייסון הירשהורן: להחזיר 0. האם אני חייב? רק שאלה. האם אנו צריכים לכלול החזר 0? סטודנטים רבים: מס ג'ייסון הירשהורן: מס ראשי עושים את זה באופן אוטומטי אם אתה מגיע לסוף. אבל אני חושב שזה נחמד לכלול אותו באופן מפורש. במיוחד כאשר אנחנו חוזרים אחרים דברים במהלך התכנית. על אישור. זה מה שאנחנו חסרים - למרות מה? מי יכול לחשוב על כמה - יש איזו תחושה של מה דברים אפשר להיכנס לשם? אפילו אם זה רק בחלק pseudocode כמו שפה? מה אנחנו באמת - מה אנחנו רוצים ללכת עד? כן, לוסי. לוסי: סופו של קובץ. ג'ייסון הירשהורן: סופו של קובץ. אז מה אתה מתכוון בסופו של קובץ? לוסי: ברגע שאתה מגיע סוף הקובץ, לעצור. ג'ייסון הירשהורן: אישור. אז ברגע שאנחנו מגיעים לסוף הקובץ. איך אנחנו יודעים כשהגענו סוף הקובץ? סטודנט 40: אני חושב שחיץ יוגדר NULL. סטודנט 41: הצפת מוכרזת בתוך הלולאה. ג'ייסון הירשהורן: אז אתה חושב חיץ יוגדר NULL. למה חיץ להיות מוגדר NULL? סטודנט 40: כי כשאתה fread, אתה מנסה לשים שום דבר למאגר. ג'ייסון הירשהורן: אישור. אז אתה חושב fread - כאשר אנו כבר הגענו לסוף קובץ, מה שfread הולכת לעשות? אני חושב שזה השאלה יש לנו להבין. מה fread עושה? האם זה לשים NULL במאגר, או זה עושה משהו אחר? איך אנחנו יכולים להבין מה זה? סטודנט 42: אדם. ג'ייסון הירשהורן: אדם. אז בואו נסתכל לכאן. להחזיר ערך. בהצלחה, וfread fwrite לחזור מספר הפריטים לקרוא או בכתב. מספר זה שווה למספר הבתים הועבר רק כאשר גודל הוא 1. אם מתרחשת שגיאה, או סוף הוא הגיע קובץ, ערך ההחזרה הוא ספירה קצרה פריט או 0. אז למטרות שלנו, אם מגיע fread סוף הקובץ, וקורא מן סופו של קובץ, לא נשאר כלום לקרוא, מה זה הולך לחזור? סטודנט 43: אפס? ג'ייסון הירשהורן: מה? סטודנט 43: אפס? ג'ייסון הירשהורן: אפס. זה הולך לחזור לאפס. אז אנחנו יודעים שfread, כאשר יש לנו הגיע לסוף הקובץ, הוא הולך להחזיר אפס. כיצד אנו יכולים להשתמש בזה לטובתנו? AVI: ניתן להכריז על משתנה מחוץ של הלולאה נקראת סימון. אם בדיקה שווה - לעת עתה - אחד. ג'ייסון הירשהורן: אישור. AVI: ואז אתה יכול לשים IF אמירה מייד אחרי fread אומרת אם fread שווה אפס - לא. ג'ייסון הירשהורן: מי יכול לעזור אבי? AVI: מה הערך חזר על ידי fread? ג'ייסון הירשהורן: אנחנו פשוט הלך על זה. AVI: איך אתה מייצג אותו? ג'ייסון הירשהורן: אז הוא חוזר - בוא נראה כאן למעלה - הוא חוזר size_t, שהוא למעשה מספר שלם. אז זה מחזיר מספר שלם. ובמקרה שלנו, זה יהיה בתמורה 1 או 0 - 1 אם זה לקרוא דבר אחד - בייט אחד, ו0 אם הגעתי לסוף. אז אם fread - כן? סטודנט 45: אתה לא יכול פשוט לשים את מלא fread (חיץ, 1, 1, src) לתוך בעוד לולאה? ג'ייסון הירשהורן: אז אתה מציע עושה את זה לשם? [קולות חציצה] ג'ייסון הירשהורן: רק שני. אז אנחנו נפטרים מזה. אז אתה מציע לשים fread לשם? מה שאנחנו צריכים גם לעבור אם אתה רוצה לעשות את זה? סטודנט 45: החיץ בחוץ. ג'ייסון הירשהורן: אנחנו צריכים גם להעביר את זה כאן. סטודנט 45: אבל עושה את זה כל הזמן להזיז אותו קדימה? [קולות חציצה] ג'ייסון הירשהורן: אישור. אז זה מה שOkshar מוצע. אנו יוצרים החיץ שלנו. אנו fread זמן מה, אז אנחנו fwrite. מחשבות על זה? סטודנט 46: השאלה היחידה שלי היא, האם זה באמת לבצע את פקודת fread? ג'ייסון הירשהורן: שאלה גדולה. כאשר אתה שם את קריאה לפונקציה בתוך מצב, עושה את זה קריאה לפונקציה לבצע? ראינו דוגמאות לכך בעבר. נכון? סטודנט 46: אישור. כן. אז היא עושה לבצע. ג'ייסון הירשהורן: ראינו דברים כמו שלפני, שבו יש לנו קריאה לפונקציה פנימית של מצב. האם זה קריאה לפונקציה לבצע? כן. אז התשובה היא כן. קריאה לפונקציה זו תבצע. אבל שוב, זה מה שאנחנו רוצים? מה היא אחת דרכים שאנו יכולים להבין לבדוק אם זה מה שאנחנו רוצים? סטודנטים מרובים: הפעל אותו? ג'ייסון הירשהורן: אנחנו יכולים להפעיל אותו. אבל לפני שאנחנו עושים את זה, אנחנו יכולים גם סיבה לעבור את זה. אם - אומר שיש לנו בית אחד בנו להגיש, עוד נגיע לכאן, אנחנו נגיע לקוד הזה. זה יפעל. fread יחזור בייט אחד ו לאחסן אותו במאגר. וזה יהיה להעריך עד 1, נכון, אחרי שהוא חוזר 1. אז בזמן 1. האם זה אומר שהקוד בפנים בעוד הלולאה תבצע? סטודנט 47: כן. זה נכון. ג'ייסון הירשהורן: כן. 1 הוא נכון. זה לא 0. אז הקוד בתוך כאן יבצע. כך תהיה לנו לכתוב את זה. אנחנו לחזור לזה שורה שוב. עכשיו יש לנו - אנחנו בסופו של הקובץ שלנו. אנו קוראים מסוף הקובץ שלנו, כי היה לנו רק בית אחד בו. Fread מחזירה 0, חנויות משהו במאגר. אני באמת לא יודע מה הוא מאחסן במאגר. אנחנו כנראה יכולים להסתכל למעלה כדי לראות מה היא עושה. כי אני באמת לא יודע. אנחנו לא יודעים, למי אכפת מה הוא מאחסן במאגר? אבל זה יחזיר 0. ובעוד 0 לבצע? WHILE 0 לא יבצעו. אז אנחנו נעבור לגור כאן למטה. אז בואו לקבל הרמת ידיים, אם זה הוא הקוד שאנו צריכים לרוץ, או אם צריך לעשות שינויים הראשונים. אז אם אתה חושב - אתה צריך להצביע. אם אתה חושב שאנחנו צריכים להפעיל את הקוד הזה כפי שהוא, בבקשה להרים את היד שלך. על אישור. יש אחד - אתה יש לך שאלה, דאגה? כן. סטודנט 48: לאחר שאנו מתקדמים חיץ מחוץ ללולאה, לעשות לנו צריך malloc זה? ג'ייסון הירשהורן: שאלה גדולה. לאחר שאנחנו עוברים חיץ מחוץ לולאה, יש לנו לmalloc זה? זו שאלת היקפה. אם אנחנו לאתחל חיץ מחוץ של לולאה זו, האם זה קיים בתוך הלולאה? סטודנטים רבים: כן. ג'ייסון הירשהורן: כן. היקפה משתרע על פני חלק פנימי של הלולאה, ובאמת, שום דבר מתחתיו בתוך קוד זה, לרבות דברים בתוך כאן. אז אנחנו לא צריכים malloc זה. זה משתנה מקומי, והיקפו עדיין כוללת את הלולאה. סטודנט 49: האם אנחנו צריכים לשחרר אותו? ג'ייסון הירשהורן: האם אנחנו צריך חיץ בחינם? סטודנט 49: כן, אם אנחנו לא malloc. ג'ייסון הירשהורן: האם אנחנו צריך חיץ בחינם? אנחנו לא. שוב, זה משתנה מקומי, ולכן אנחנו לא צריכים לשחרר אותו. על אישור. בואו לראות מה קורה. אז זה לא מאותחל. זה מה משהו ש מרקוס הציע קודם לכן. אז יש לנו שגיאה ש, חיץ משתנה הוא לא מאותחל בעת שימוש כאן. איך אנחנו יכולים לתקן את זה? סטודנט 50: malloc זה? סטודנט 51: שווה NULL? סטודנט 52: תגיד חיץ שווה NULL. ג'ייסון הירשהורן: אישור. נראה טוב. יש לנו את זה עכשיו. בואו ליצור משהו כדי לנסות העתקה. אז יש לנו קובץ הטקסט שלנו. איך אנחנו יכולים להפעיל את התכנית? כן. סטודנט 53: אתה יכול לעשות נקודה סלאש cp, test.txt. ואז אתה יכול שם קובץ אחר שזה יהיה לאחסן ל. ג'ייסון הירשהורן: אישור. אנחנו קוראים לזה out.txt. מגניב? אשמת Seg. מחשבות על אשמת הצינוק? זה נהדר. איך אנחנו יכולים לגלות איפה האשמה היא הצינוק? מה? סטודנט 54: Gdb. ג'ייסון הירשהורן: Gdb. אנחנו רצים gdb על ידי כתיבת לוכסן נקודת gdb, השם של התכנית שלנו. אין טיעוני שורת הפקודה שם. אנחנו הולכים להקים נקודת עצירה בראשית. אם אני רוצה להתחיל gdb, מה עליי לעשות? סטודנט 55: ר ' ג'ייסון הירשהורן: ר 'ואז מה? סטודנט 55: הטיעונים? ג'ייסון הירשהורן: אז שורת הפקודה טיעונים. בואו ללכת דרך. N הוא רק לוקח אותי שורה אחרת שורה. אני מתכוון ללכת עד אני מקבל את אשמת הצינוק שלי. יש אשמת הצינוק שלי. זה נראה כמו fread גרמה אשמת הצינוק שלי. אני יודע fread נגרמה באשמת הצינוק שלי, משום שזה היה קו אנחנו פשוט הוצאו להורג. והדבר היחיד שהיה קורה בקו זה - שני דברים היו קורים. Fread הולכת, ולאחר מכן היינו עושה כמה בדיקות WHILE. אני מוכן להתערב שאותו הזמן בדיקה לא הייתה גורם לתקלת הצינוק שלי. סביר להניח, הייתה fread גורם באשמת הצינוק שלי. אני גם רואה כאן משהו, memcopy. עותק זיכרון. נשמע כמו העברת זיכרון מ מקום אחד למקום האחר. נשמע כמו משהו שהיה קורה בfread, אולי כמה זיכרון עובר מכאן לכאן. בואו נעבור את זה שוב. כיצד ניתן להפעיל אותו על ולהפעיל אותו שוב? כן. סטודנט 56: האם אתה צריך לשים אמפרסנד לפני החיץ? ג'ייסון הירשהורן: אז אמפרסנד לפני החיץ היה נותן לי את הכתובת של חיץ, שהוא char *. בואו לרוץ דרך עוד פעם אחת זה. כיצד אני מפעיל דרכו עוד פעם אחת? סטודנט 57: האם אתה יכול פשוט הקלד לרוץ שוב? ג'ייסון הירשהורן: פשוט הקלד לרוץ שוב. אז אנחנו לא הולכים לבצע את הקו הזה. אז חיץ הוא מצביע NULL. לתקן? הוא מצביע על - בואו לראות. אם יש לנו שלנו - לצייר תמונה מהירה של זה. האם כל אחד יכול לראות אם אני כותב כאן? אז במחסנית, יש לנו מקומי משתנה וזה נקרא חיץ, ו זה מצביע לתו. מה כתובת הוא char זה ב? סטודנט 58: 0x0. ג'ייסון הירשהורן: נכון. זה מה שזה. כאן, בתוך חיץ, מאוחסן 0x0. זה מה שיש לנו - התקנה שיש לנו עכשיו. אז הקו הזה, fread, מכניסה משהו מהמקור שבו? לתיבה זו או תיבה זו? תיבה איזה? תיבה או תיבה ימנית השאיר? תיבת זכות זו. מכאן נובע את המצביע, ומכניס אותו לכאן. כאשר אנו מנסים ומגע זיכרון ב מיקום 0, מה אנחנו מקבלים? אשמת פילוח. זה השגיאה שיש לנו עכשיו. כן. סטודנט 59: אין לך לשים חיץ כוכב? או לא? לfread? ג'ייסון הירשהורן: אז fread לוקח מצביע. אז הוא עובר בחיץ. ואז זה יהיה דה התייחסות אותו איפשהו בתוך fread. אבל שוב, ראינו, זה לוקח מצביע. אנחנו לא צריכים להעביר את זה חיץ כוכב. שהיה עובר זה כל מה שהוא כאן. וזה כנראה ייתן לנו שגיאה כי אנחנו דה התייחסותו. נכון? כאשר דה התייחסותנו מצביע זה, כאשר אנחנו מנסים לגשת למיקום זה, אנחנו מקבלים הודעת שגיאה - אשמת הפילוח שלנו. אז - אופס. אנחנו הולכים לפרוש מgdb. הקו שלנו - הבעיה שלנו - נכונה כאן, על הקו הזה. וזה בעיה, כי של קו זה. איך אנחנו יכולים ליצור תיבה ש הוא נגיש בfread. נכון? אנחנו צריכים ליצור תיבה זה אחד בתים גדולים, בגודל של char. אבל אנחנו צריכים התיבה שתהיה נגישה כאשר פונקציה זו מבצעת. אז איפה - כן. יש לך רעיונות? סטודנט 60: רק להגדיר אותו כ כל תו אקראי. פשוט תעשה את שווים חיץ char האופי. ואז, כאשר יש לך חיץ שם - ג'ייסון הירשהורן: המתן. תו חיץ? אז לא כוכב? סטודנט 60: כן. להוציא את הכוכב. שווה אופי אקראי. ג'ייסון הירשהורן: אישור. אז תן לי אחד. סטודנט 60: אוהב או משהו. ולאחר מכן כאשר יש לך חיץ שם, אתה משתמש - סטודנט 61: כוכבים? הו לא, האמפרסנד. סטודנט 60: השתמש באמפרסנד. ג'ייסון הירשהורן: אישור. ומה לגבי בfwrite? סטודנט 60: השתמש בתו החיבור שוב. ג'ייסון הירשהורן: בסדר. אז הרעיון שלך הוא, שאנו יוצרים ותו לשים משהו בזה, ולאחר מכן לכתוב לתו זה. סטודנט 60: כן. ג'ייסון הירשהורן: מה אין אנשים חושבים? סטודנט 62: זה מפותל. ג'ייסון הירשהורן: אישור. בואו לצייר את זה. אז הפעם, אני הולך לצייר את זה ב אדום על הערימה כאן, ולאחר מכן אנחנו יהיה - אוו! סליחה. אז הפעם יש לנו משהו שנקרא חיץ, וזה בערימה. לתקן? ואנחנו חוסכים בזה, בהתחלה. אז יש לנו השיחה שלנו לfread. מה fread עושה זה לוקח מבתים הקובץ ו מעמיד אותו במקום. זה מכניס בכל מה שזה דבר זה מצביע. ובכן, לפני שהיו לנו כתובת זו - 0x0. עכשיו מה כתובת יש לנו? סטודנט 63: לא משנה מה חיץ כתובת הוא. ג'ייסון הירשהורן: לא משנה מה חיץ כתובת הוא. זה כנראה הולך להיות משהו כזה. כנראה הולך להתחיל עם B ו f, ואז יש לי שש אחרות ספרות הקסדצימלי. לא משנה. כתובת מסוימת. ואנחנו עוברים פנימה כתובת ואנחנו הולכים לשים אחד שלנו דבר בתים בכתובת הזאת. אז אנחנו הולכים לשים אחד שלנו דבר בייט בתוך כאן. ואז אנחנו הולכים לכתוב מ מה אי פעם בתוך כאן. האם יש למישהו שאלות על זה? מי חושב את הקוד הזה יעבוד? הרם את היד שלך אם אתה חושב קוד זה יעבוד. אתה צריך לנקוט עמדה. ומי שחושב את הקוד הזה לא יעבוד? הרם את ידך. כולם צריך להיות מרים את היד שלהם. על אישור. מייקל, שבו אתם עומדים? מיכאל: אני לא יכול להחליט. סוג של באמצע. ג'ייסון הירשהורן: אתה באמצע. בחר אחד. מיכאל: יהיה לי אמונה ואומר שזה יעבוד. ג'ייסון הירשהורן: אישור. יהיה לך אמונה ואומר שזה עובד? מה קרה? [קולות חציצה] ג'ייסון הירשהורן: לא באשמת צינוק. כיצד אנו יכולים לבדוק כדי לראות אם שני דברים שווים? שני קבצים שווים. סטודנט 64: השוואת גרסאות. ג'ייסון הירשהורן: השוואת גרסאות. בדיקות הבדל להבדלים בין שני קבצים, ואם הוא חוזר שום דבר, הם זהים. ואם אנחנו פותחים, אנחנו מקבלים הקובץ שלנו. אז זה היה הפתרון הנכון. בואו נסתכל אחורה על זה עוד פעם אחת. אנחנו בעצם לא עשינו אפילו צריך לאתחל אותו. כנראה שזה היה נראה קצת נקי אם אתה לא שם משהו אקראי לשם. להיות הנקודה, אתה צריך ליצור כמה מקום כדי לאחסן משהו מן fread ולקחת משהו מתוך fwrite. והדבר שהייתי צריך להיות או מקומי משתנה על הערימה - אתה יכל malloc'd קצת מרחב. אז יש לנו באמת יכולים malloc כתב כאן, ו שהיה עובד. ואז היינו כבר אחסון הדברים שלנו אי שם בערימה. אבל זה באמת, כנראה, הפתרון האלגנטי ביותר. פשוט ליצור שטח במחסנית לדברים האלה ללכת. שיהיה לי שתי הערות אחרות. אם היית לוקח את תורו בזה, ו לאחר מכן לקבל הבקיע על זה, ההערות שלי יהיה כדלקמן. 1 אלה כאן, לי, תראו כמו מספרי קסם. זה 1, במונחים של fread, הגיוני. זה מספר דברים כדי לקרוא או לכתוב. אבל צריך את זה ממש כאן כנראה יהיה משהו אחר. אז מה פתרון אחד? סטודנט 65: גודל של בתים. ג'ייסון הירשהורן: כמו זה? סטודנט 65: גודל של char. ג'ייסון הירשהורן: גודל של char. כן, בתים הוא לא סוג. אז גודל של עבודות char. אפשר שיש לנו, בחלק העליון של הקוד, # הגדיר את זה. קרא BYTE ומשהו זה באמת char. למעשה, גישה אפילו טובה יותר אולי היה זה - uint. מישהו יודע מה זה? סליחה. יש לי אותו לאחור. חכה, לא. לאיזה כיוון זה הולך? מישהו יודע מה זה? כן. סטודנט 67: אמור לעזור לתקנן על פני דברים, כי מערכות יש לי - כמו מספרים שלמים שאינם חתומים שיש להם 8 בתים? ג'ייסון הירשהורן: זה בדיוק נכון. על מכונות שונות, בגודל של char - בדרך כלל לא char. תווים הם בדרך כלל בייט אחד. אבל בגודל של סוגי נתונים אחרים הם בגדלים שונים במחשב 32 סיביות לעומת מכונה 64 סיביות. Uint8_t תמיד 8 ביטים - תמיד בייט אחד. ואני צריך לכלול כי קובץ כותרת int סטנדרטי. אז עכשיו, זה כנראה היה הדרך הטובה ביותר לכתוב את הקוד הזה. אז אוכל להיפטר ממספרי הקסם. ויש לי גם יותר הגיוני הקלד לחיץ. זה לא פשוט char, זה בייט, וזה מה שאנו מצפים שזה יהיה. ועד כאן, יש לנו בעצם היה קצת חזק יותר. אנחנו לא קוראים לזה char, אשר - אולי, מי יודע - יכול להיות שונה גודל על מכונות שונות. אנחנו בעצם אומרים זה בדיוק בית אחד, תמיד, לא משנה מה. ואם אנחנו מסתכלים כאן, אנחנו עושים cp. אוי לא. מה קרה? סטודנט 68: זה יכול להיות מופעל. ג'ייסון הירשהורן: מה? סטודנט 69: האם זה? סטודנט 70: אתה לא להגדיר את זה כסוג. סטודנט 71: אבל זה צריך להיות מוגדר בתקן. סטודנט 72: מה קורה? סטודנט 73: צריך להגדיר להיות כל כמוסות? ג'ייסון הירשהורן: אז זה לא # define. למעשה, במקרה זה, אני הולך להשתמש typedef. בגלל שאנחנו משתמשים בו בתור סוג במיקום אחד. אז במקרה הזה, אנחנו בעצם רוצים typedef כאילו אנחנו מדפיסים סוג חדש בתים, וזה, בעצם, זה. זה קצת שונה מ# define. ועכשיו, הקוד שלנו עובד בצורה מושלמת. אז, שוב, # define לוקח משהו, מחליף אותו בכל מקום עם הדבר האחר. זה פשוט מאקרו - קצרנות להיפטר מספרי קסם. אבל במקרה הזה, בגלל שאנחנו שימוש בו כסוג - ממש כאן - כדי שזה יעבוד, אנחנו צריכים לtypedef כל בתים הוא. ואנחנו מגדירים אותו ממש כאן. זה לא struct, זה בעצם רק מספר שלם לא חתום. זה זמן רב בייט אחד. קוד זה יהיה זמין באינטרנט, ו יש כל מה שאתה צריך את זה עכשיו. אז יש לנו - מושלם - 13 דקות עזבו ללכת בעיה מעל להגדיר 5. אני רוצה ללכת דרך copy.c יחד, ואז נדבר בקצרה על חלקים האחרים הבעיה מוגדרת. אז תן לי להרים את copy.c. והדבר מגניב הוא, יש לנו בעצם כבר כתב הרבה קוד זה. הקוד שכתבנו ממש פשוט יצאתי מכאן כשאני היה כותב את זה בעצמי. אבל זה copy.c, מהווה את הבסיס לשתי החלקים הראשונים של הבעיה שנקבעה לwhodunit.c, אשר אתה צריך לכתוב, וresize.c. Recover.c, שהוא שלישי ואחרון חלק להגדיר בעיה, אינו מבוסס על הנחה של קובץ זה. אתה הולך צריך לכתוב את הקובץ, אנחנו נותנים לך תבנית לכי להגיש, אבל אין לזה שום לעשות עם copy.c. אבל בגלל copy.c הוא הבסיס ל שני החלקים הראשונים, אנחנו הולכים כדי לעבור את זה עכשיו, אז יש לך תחושה טובה של מה שהיא עושה. וההערות לתת חלק ממנו משם. אנחנו כבר כתבנו כמה מזה. ראשית, אנו מוודאים אנחנו מקבלים שלוש טענות. שלב הבא, אנחנו זוכרים את שם הקובץ. אז אנחנו מדלגים על שלב זה, כאשר קדדנו את הדבר שלנו - כאשר cp שלנו. אבל כאן, הם עושים זה קצת יותר נקי. הם בודקים כדי לוודא שני הקבצים הם טובים, ב בנוסף לפתיחתם. אנחנו כתבנו את כל הקוד הזה רק עכשיו, ולכן אני לא הולך להתעכב על הקוד הזה. הבא הוא כמה דברים שהוא ייחודי ל את סוגי קבצים שאנחנו משתמשים, אשר הם קבצי מפת סיביות. יש קבצי מפת סיביות כמה metadata הקשורים בהם. אז כמה בתים הראשונים לספר לך על הקובץ. הם לא בצבעים של פיקסל בתמונה. הם יספרו לך על הקובץ. ואם אתה קורא דרך להגדיר את הבעיה, יהיה לך הרבה יותר מידע על אילו סוגים של מבנים מטה כלולים במפה סיבית. אבל בגלל זה יש לנו את זה קודם סט של - קוד זה ממש כאן. אנו קוראים מטה - שתי חתיכות של מטה - הקובץ כותרת עליונה וכותרת המידע. ואנחנו בודקים כמה חלקים ממנה ל לוודא שזה קובץ מפת סיביות אמיתי לפני שתמשיך. ושוב, אלה הם פרטים שאנו לא צריך להיכנס לחברה. אם אתה קורא דרך להגדיר את הבעיה, אתה תבין אלה. סיפור ארוך קצר, אלה רק אומרים, זה הוא קובץ מפת סיביות, ו מאשר את זה. שלב הבא, אנחנו כותבים אותם לקובץ החוצה. אנחנו רואים את זה כאן. אנו כותבים כדי המצביע החוצה. שלב הבא, אנחנו קביעת ריפוד. אז שוב, כפי שהוא ייחוד עם קובץ מפת סיביות, כוללים כמה שורות ריפוד בסוף. ואם אתה קורא דרך להגדיר את הבעיה, תוכל ללמוד עוד על ריפוד. זוהי הנוסחה למצוא ריפוד. חשוב לזכור - כאשר אתה משנה את הגודל של מפת סיביות קובץ, שינויי הריפוד. כשאתה משנה את הגודל של קובץ, שינויי הריפוד. זה אף פעם לא הולך להיות יותר מ 3 - זה יהיה 0 עד 3, ועד בכלל. אבל כאשר אתה משנה את הגודל של משהו, שינויי הריפוד. אם יש לי רק פיקסל אחד באותה שורה, אני צריכים שלושה בתים של ריפוד, כי כל שורה צריכה להיות בכפולות של ארבעה ביטים ארוכים בקובץ מפת סיביות. אבל אם אני אכפיל את זה, ללכת מפיקסל אחד לשני פיקסל, כל אחת מהן, נניח, הוא בייט, אז אני צריך שני בתים של ריפוד לעשות ששווה לארבעה. לכן, כאשר אני משנה את הגודל של משהו, אני צריך לשנות את הסכום של ריפוד יש לי. האם זה הגיוני לכולם? בשלב בא, אנו לחזר על כל שורה, או דרך כל השורות. ואז אנחנו איטרציות כל עמודה בכל שורה. אנחנו מטפלים בזה כמו מפת סיביות רשת, כמו שאנחנו כבר טופלו הלוח ב15. כמו שטפלנו בלבנים כש הדפסנו אותם על המסך. רשת של שורות ועמודות. ואז - ראינו את זה. אנחנו בעצם רק בקידוד זה. אנחנו יצרנו כמה אחסון זמני. אנו קוראים שם, ולאחר מכן אנחנו כותבים את זה. זה בדיוק מה שאנחנו עשינו זה עתה. בשלב הבא, מכיוון שאמרתי כל שורה מסתיים בחלק הריפוד, אנחנו לדלג על ריפוד ש-- הריפוד הישן. ואז להוסיף אותו בחזרה. במקרה זה, שאנו יוצרים את אותו קובץ מדויק. אנחנו רק מעתיקים אותו. אז הקו הזה הוא סוג של טיפשי. אנחנו יכולים, פשוטו כמשמעו, רק לשים את הריפוד פנימה אבל אם אתה משנה את גודלו של הקובץ, האם אתה עדיין רוצה את הקו הזה? אז אם נשנינו את הגודל של קובץ, אנחנו עדיין רוצים לדלג על הריפוד הישן? סטודנט 74: כן. ג'ייסון הירשהורן: אז אנחנו עושים. בגלל זה, שוב, עסקות עם קובץ המקור. לא אכפת לנו על הריפוד מקובץ המקור. אנחנו רוצים ללכת לשורה הבאה. אבל אנחנו לא פשוט לשים בחזרה הסכום הישן של ריפוד. אנחנו צריכים להחזיר את סכום חדש של ריפוד. לכן, כאשר אנו משנים את הגודל של קובץ, אנחנו עדיין רוצים לדלג על ריפוד בקובץ הישן - מה אנחנו קוראים מ. אבל מה שאנחנו כותבים כדי, אנחנו הולכים צריך להחזיר קצת שונה מספר הריפוד כי אנחנו כבר נקבעו. כן. סטודנט 75: הסדר של שני אלה קווים לא משנה, נכון? מכיוון שאתה מטפל קבצים שונים. ג'ייסון הירשהורן: בדיוק. הסדר של שתי שורות אלה לא משנה. אנחנו כותבים את הקו הזה. זה כאן לקבלת הקובץ אנחנו כותבים. זה חשוב, ולכן אנחנו מקבלים את כמות נכונה של ריפוד. זו יש להתמודד עם הקובץ ב. אנחנו רוצים לדלג תקין על הריפוד. אנחנו לא רוצים לקרוא - אם אנחנו קוראים בייט בכל פעם, אנחנו לא אכפת להם הבתים ריפוד אלה. אנחנו רוצים לעבור לשורה הבאה. לבסוף בדיוק כמו לוסי נתנה לנו, אנחנו סוגרים את הקבצים ולהחזיר 0. אז זה copy.c. ואנחנו באמת כתבנו - בילינו את רוב סעיף כותב את זה, בעצם. אתם גרמת לזה. אז אני מקווה שיש לך תחושה טובה של מה שקורה כאן. ההבדל הגדול, בכנות, הוא פשוט חלק ראשון זה העוסק ב ייחוד של קבצי מפת סיביות. אז יש לי כמו השקופית הבאה שלי, מה אנחנו צריכים לעשות? ובכן, בואו נחשוב על מי עשה. ובשביל מישהו שקורא דרך להגדיר את הבעיה, מה לעשות שאנחנו צריך לעשות במי עשה? כל שעליך לעשות. Aleja. Aleja: אתה יכול להוציא את החלק של כל פיקסל שמציין אדום. ולאחר מכן - סוג של? ג'ייסון הירשהורן: אישור. אז לקחת את החלק של כל אחד פיקסל שמציין אדום. זה קרוב, אבל לא את כולה. סטודנט 76: ובכן, יש דרכים שונות לעשות את זה. ג'ייסון הירשהורן: אישור. תן לי אחד בדרך. סטודנט 76: קח את כל האדומה ו לאחר מכן להדגיש את כחול וירוק. ג'ייסון הירשהורן: אישור. אז נתן שני הדרכים האלה - זה נשמע כמו שאנחנו נותנים לו פיקסל, זה יש רמה אדומה, כחולה וירוק. אנחנו רוצים לשנות את הרמות היחסית של אדום, כחול, וירוק, בהתאם על פיקסל זה. איפה בקוד זה אנחנו צריכים לשנות יחסית אדום, כחול וירוק רמות של פיקסל נתון. אחרי שקראנו את זה - לפני שאנחנו כותבים את זה? תן לי את מספר הקו. סטודנטים מרובים: 83. ג'ייסון הירשהורן: 83. אז כאן. עבור מי עשה, את הקוד אתה צריך כתיבה צריכה ללכת ממש שם. וזה רק הקוד אתה צריך לכתוב. כי, כמו ששמענו, כל מה שאתה צריך לעשות הוא לשנות כחול יחסית אלה, רמות אדומות וירוקים מכל פיקסל. יצאתי לך לקרוא אותו, ועכשיו אתה הולך לכתוב את זה. כיצד אוכל לקבל - אם יש לי את הדבר הזה בשם משולש, ממש כאן, וזה של הקלד RGBTRIPLE - ובכן, אם היינו מסתכל בbmp.h, מה הוא RGBTRIPLE? סטודנט 77: זה struct. ג'ייסון הירשהורן: RGBTRIPLE הוא struct. אנחנו רואים את זה נכון כאן למטה. ולכן אם אני רוצה גישה, נניח, רמה אדומה של struct, איך אני לגשת לרמה האדומה של struct זה? [CLASS ממלמלת] סטודנט 78: RGBTRIPLE.rgbtred? ג'ייסון הירשהורן: האם זה נכון? סטודנט 79: זה צריך להיות משולש נקודה, במקום RGBTRIPLE נקודה? ג'ייסון הירשהורן: חדר לשלושה. שלושה הוא המשתנה המקומי, ולכן כאן, אין מצביעים כאן. אז אנחנו פשוט להשתמש בסימון הנקודה. זה ייתן לי את הרמה של אדום. אם אני רוצה לשנות את זה, אני פשוט להגדיר זה שווה למשהו שונה. אז שוב, את הקו הזה של קוד כניסות משתנה זה בתוך struct זה, ו אנו יכולים להגדיר אותו למשהו חדש. אז עבור מי עשית, שוב, זה הוא, במהות, מה שאנחנו צריכים לעשות. פשוט מאוד. רק לשנות כמה רמות יחסי, ו זה מקום שבו הקוד שהולך. שינוי גודל, ומצד שני, זה קצת יותר מסובך. למעשה, שינוי הגודל הוא כנראה החלק הקשה ביותר של בעיה זו מוגדרת. יש לנו שלוש דקות לסיום על זה. אבל שוב, כבר נכתב רוב הקוד הזה, ולכן אנחנו צריך להיות די מוכר. מה הם כמה דברים שאנחנו רוצים לעשות ב לשנות את הגודל, אם יצאת לך לקרוא על בעיה להגדיר? אם אתה נותן לי אותם, אנחנו אפשר לדבר עליהם. מה הם כמה דברים שאנחנו רוצים לעשות? סטודנט 80: אנכי - ולכן אתה צריך לשנות את גודלו אופקי, אבל במאונך לשנות את גודלו, כמו גם? ג'ייסון הירשהורן: אז אם אנחנו נתנו פיקסל, ואנחנו רוצים לשנות את גודלו על ידי פקטור של שתיים, עכשיו זה צריך להיות לשנות את הגודל אופקי ולשנות את הגודל במאונך. האם זה הגיוני? כן. אז זה כנראה האתגר הגדול ביותר. ונדבר על זה בשניות. כן. סטודנט 81: הדרך שחשבתי על זה היה לך צורך להדפיס אותו - ג'ייסון הירשהורן: המתן. אל תגידו לנו את מה שעשה. אנחנו הולכים לדבר בהיגיון. סטודנט 81: אישור. מה הייתה השאלה? ג'ייסון הירשהורן: אתה פשוט הרים את היד שלך. לא הייתה שום שאלה. הרשה לי להציג אותה. תן לי רק בקצרה זה. אז יש לנו פיקסל אחד, אנחנו רוצים לשכפל אותו, הן אופקי והן במאונך. אז באופן אידיאלי מה שאנחנו עושים כאן הוא, שאנחנו לקרוא בפיקסל שלנו, אנו כותבים אותו אולם רב של פעמים. אבל אז יש לנו הטריק שלנו כאן, כי אז אנחנו רוצים לדלג השורה הבאה ולכתוב את זה ב תחילת השורה הבאה. אז אם אנחנו רוצים לשכפל את שני אופקי ואנכי, מה שהוא דרך אחת טובה לעשות את זה - אחד טוב אם כי כדי לעשות את זה? ולכן אנחנו לא צריכים לחפש כל הזמן סביב הקובץ שלנו למקם את הדברים. השאלה שאולי אין לי הגיוני, אבל אני חושב תשובה לזה יעזור. סטודנט 82: יצירת מערך? ג'ייסון הירשהורן: אז בואו נחשוב של כל קובץ כרצף. בואו נחשוב במונחים של שורות. אם יש לנו בשורה הראשונה שלנו מקטן שלנו תמונה, אנחנו יכולים לעשות את אותה השורה לשורה גדולה מתמונה גדולה, ולאחר מכן לשכפל את השורה שאולם פעמים רבות הוא צריך להיות משוכפל, ולא הולכים על ידי פיקסל פיקסל, אשר מקבל מבלבל כאשר התמודדות עם קבצים. כי אם היו לנו - אני פועל מתוך שטח. אם זה הקובץ שלנו, ויש לנו כי פיקסל אחד שם, ואנחנו רוצים לשים את זה ממש שם, עדיין יש לנו כמה דברים שצורך ללכת לשם כשאנחנו כתיבה ויצירת הקובץ החדש שלנו - הקובץ שלנו זה גדול פי שניים. אבל זה ממש קשה עם פונקציות קובץ כדי לדלג סביב לקווים חדשים ככה, ואז לחזור לכאן ולשים את הדברים שם. זה כמעט בלתי אפשרי לעשות משהו ככה, אם זה נשמע הגיוני. אז אם אנחנו חושבים במונחים של שורות, אנחנו יכולים לקחת השורה שלנו, ואז לשים אותו - לשכפל את השורות בצורה אנכית. וזה איך אנחנו מתמודדים עם שינוי הגודל אנכי ולא אופקי. זה היה סוג של מהיר, ו קצת מבלבל. למרבה הצער הזמן שלנו נגמר. אני אעמוד מחוץ לאלו מכם כאן יש להם שאלות על סט בעיה, כולל להתאושש. אז בואו לדחות לעת עתה. ושוב, אם יש לך שאלות, אנחנו יכולים לשוחח בחוץ.