1 00:00:00,000 --> 00:00:02,730 [Powered by Google Translate] [Розділ 5: менш комфортно] 2 00:00:02,730 --> 00:00:05,180 [Nate Хардісон, Гарвардський університет] 3 00:00:05,180 --> 00:00:08,260 [Це CS50.] [CS50.TV] 4 00:00:08,260 --> 00:00:11,690 Так що ласкаво просимо, хлопці. 5 00:00:11,690 --> 00:00:16,320 Ласкаво просимо до розділу 5. 6 00:00:16,320 --> 00:00:20,220 На даний момент, закінчивши тест 0 і побачивши, як ви зробили, 7 00:00:20,220 --> 00:00:25,770 сподіваюся, ви відчуваєте себе дійсно добре, тому що я був дуже вражений бали в цьому розділі. 8 00:00:25,770 --> 00:00:28,050 Для наших глядачів онлайн, у нас було кілька питань 9 00:00:28,050 --> 00:00:33,680 Про двох останніх проблем на проблеми набору - або на тест, а. 10 00:00:33,680 --> 00:00:39,690 Так що ми збираємося перейти на тих, хто дійсно швидко, так що кожен бачить те, що сталося 11 00:00:39,690 --> 00:00:45,060 і як йти через саме рішення, а не просто перегляд самого рішення. 12 00:00:45,060 --> 00:00:50,330 Ми збираємося піти за останні кілька проблем дуже швидко, 32 і 33. 13 00:00:50,330 --> 00:00:53,240 Тільки, знову ж таки, так що онлайн-глядачі можуть побачити це. 14 00:00:53,240 --> 00:00:59,080 >> Якщо ви звернетеся до вашої проблеми 32, яка знаходиться на сторінці 13, 15 00:00:59,080 --> 00:01:02,730 13 з 16, 32, проблема все про свопи. 16 00:01:02,730 --> 00:01:05,010 Це все про обмін двох цілих чисел. 17 00:01:05,010 --> 00:01:08,740 Це проблема, що ми перейшли пару раз в лекції. 18 00:01:08,740 --> 00:01:13,590 І тут, що ми просимо вас зробити, це швидко сліду пам'яті. 19 00:01:13,590 --> 00:01:17,000 Для заповнення значень змінних, так як вони знаходяться на стеку 20 00:01:17,000 --> 00:01:20,250 як код проходить через цю функцію підкачки. 21 00:01:20,250 --> 00:01:24,500 Зокрема, те, що ми шукаємо - я збираюся поставити цю Ipad вниз - 22 00:01:24,500 --> 00:01:29,650 Зокрема, те, що ми дивимося на цей рядок з номером 6 прямо тут. 23 00:01:29,650 --> 00:01:36,740 І це номером 6, тільки зіткнення з попередньої задачі. 24 00:01:36,740 --> 00:01:41,720 Те, що ми хочемо зробити, це показати або позначення стану пам'яті 25 00:01:41,720 --> 00:01:46,090 як це в той час, коли ми виконуємо цю лінію № 6, 26 00:01:46,090 --> 00:01:52,540 який фактично є повернення з наших своп функції прямо тут. 27 00:01:52,540 --> 00:01:59,450 Якщо ми прокрутити вниз тут, ми побачили, що всі адреси в пам'яті була надана для нас. 28 00:01:59,450 --> 00:02:02,540 Це дуже ключа; ми повернемося до цього через хвилину. 29 00:02:02,540 --> 00:02:09,240 А потім тут на дні, у нас було небагато схема пам'яті, які ми збираємося посилатися. 30 00:02:09,240 --> 00:02:12,490 Насправді я зробив це на моєму iPad. 31 00:02:12,490 --> 00:02:20,720 Так що я буду чергувати назад і вперед між IPad і цей код просто для довідки. 32 00:02:20,720 --> 00:02:26,540 >> Давайте почнемо. По-перше, давайте зосередимося на перших двох лініях основний прямо тут. 33 00:02:26,540 --> 00:02:30,220 Для початку, ми збираємося, щоб ініціалізувати х 1 і у 2. 34 00:02:30,220 --> 00:02:33,040 Таким чином, ми маємо два цілочисельних змінних, вони обидва будуть поміщені в стек. 35 00:02:33,040 --> 00:02:36,050 Ми збираємося поставити 1 і 2 в них. 36 00:02:36,050 --> 00:02:43,150 Так що якщо я перевернутися на мій IPad, сподіваюся, давайте подивимося, - 37 00:02:43,150 --> 00:02:48,660 Apple TV дзеркальне відображення, і ми йдемо. Добре. 38 00:02:48,660 --> 00:02:51,670 Так що якщо я перевернутися на мій IPad, 39 00:02:51,670 --> 00:02:56,220 Я хочу, щоб ініціалізувати х 1 і у 2. 40 00:02:56,220 --> 00:03:00,580 Ми робимо це досить просто, написавши 1 в коробку з написом х 41 00:03:00,580 --> 00:03:07,730 і 2 в графі у. Досить просто. 42 00:03:07,730 --> 00:03:11,620 Отже, тепер давайте повернемося до ноутбука, подивимося, що буде далі. 43 00:03:11,620 --> 00:03:15,810 Так що наступна рядок, де все стає складніше. 44 00:03:15,810 --> 00:03:28,110 Ми передаємо адресу х і адресу у як параметри А і В у своп функції. 45 00:03:28,110 --> 00:03:32,380 Адреса х і адресу у речі, які ми не можемо обчислити 46 00:03:32,380 --> 00:03:36,360 без посилання на ці кулі вказує прямо тут. 47 00:03:36,360 --> 00:03:39,750 І, на щастя, перші два пункти говорять нам саме те, що відповіді на них. 48 00:03:39,750 --> 00:03:44,740 Адреса х в пам'яті 10, і адресу у в пам'яті 14. 49 00:03:44,740 --> 00:03:51,870 Так що ті цінності, які отримують передається в якості і б нагорі в нашій своп функції. 50 00:03:51,870 --> 00:04:00,760 Таким чином, знову перейти назад на нашу схему, я можу написати 10 в 51 00:04:00,760 --> 00:04:07,400 і 14 в б. 52 00:04:07,400 --> 00:04:11,610 Тепер ця точка, де ми продовжуємо підкачки. 53 00:04:11,610 --> 00:04:14,520 Таким чином, гортати назад в ноутбук знову, 54 00:04:14,520 --> 00:04:21,079 ми бачимо, що шлях підкачки працює, я спочатку разименовать і зберегти результат в TMP. 55 00:04:21,079 --> 00:04:27,650 Таким чином, оператор разименованія говорить: "Привіт. Лікувати вміст змінної в якості адреси. 56 00:04:27,650 --> 00:04:33,830 Перейти до того, що зберігається за цією адресою, і завантажити його. " 57 00:04:33,830 --> 00:04:41,720 Що ви завантажуєте з змінної будуть зберігатися в нашій TMP змінна. 58 00:04:41,720 --> 00:04:45,150 Подавати назад в iPad. 59 00:04:45,150 --> 00:04:51,690 Якщо ми підемо за рішенням 10, ми знаємо, що адреса 10 є varible х 60 00:04:51,690 --> 00:04:55,480 тому що нам сказали, що наші кулі, що адресу х в пам'ять 10. 61 00:04:55,480 --> 00:05:00,180 Так що ми можемо піти туди, отримати значення його, що 1, як ми бачимо на наших Ipad, 62 00:05:00,180 --> 00:05:06,300 і завантажити в TMP. 63 00:05:06,300 --> 00:05:08,250 Знову ж таки, це не остаточний зміст. 64 00:05:08,250 --> 00:05:14,350 Ми збираємося пройти і ми повернемося до наших кінцевим станом програми в кінці. 65 00:05:14,350 --> 00:05:17,210 Але зараз у нас є значення 1 зберігається в TMP. 66 00:05:17,210 --> 00:05:19,210 >> І є швидкий питання тут. 67 00:05:19,210 --> 00:05:23,980 [Олександр] Є оператором разименованія - це тільки зірки прямо перед змінною? 68 00:05:23,980 --> 00:05:27,600 >> Да. Таким чином, оператор разименованія, як ми перевернути назад в наш ноутбук ще раз, 69 00:05:27,600 --> 00:05:33,780 ця зірка прямо перед. 70 00:05:33,780 --> 00:05:37,460 У цьому сенсі, це - ви порівняти її з оператором множення 71 00:05:37,460 --> 00:05:42,400 яка вимагає двох речей; разименовать оператор унарний оператор. 72 00:05:42,400 --> 00:05:46,130 Тільки стосовно до одного значення, а не бінарний оператор, 73 00:05:46,130 --> 00:05:48,810 де ви подаєте заявку на два різні значення. 74 00:05:48,810 --> 00:05:52,080 Так що те, що відбувається в цій лінії. 75 00:05:52,080 --> 00:05:58,390 Ми завантажили значення 1 і зберігати його в наш тимчасовий цілої змінної. 76 00:05:58,390 --> 00:06:05,800 У наступному рядку, ми зберігаємо вміст б у - 77 00:06:05,800 --> 00:06:12,630 або, скоріше, ми зберігаємо вміст, б вказує на в місце, де вказує. 78 00:06:12,630 --> 00:06:17,690 Якщо ми проаналізуємо цю справа наліво, ми будемо разименованія б, 79 00:06:17,690 --> 00:06:23,580 Ми маємо намір звернутися 14, ми збираємося захопити ціле число, яке є, 80 00:06:23,580 --> 00:06:26,900 а потім ми збираємося перейти за адресою 10, 81 00:06:26,900 --> 00:06:34,240 і ми збираємося кинути результат нашої разименованія б у цей простір. 82 00:06:34,240 --> 00:06:40,080 Подавати до нашої Ipad, де ми можемо зробити це трохи більш конкретним, 83 00:06:40,080 --> 00:06:44,070 це може допомогти, якщо я напишу номери на всі адреси тут. 84 00:06:44,070 --> 00:06:53,820 Отже, ми знаємо, що при в, ми знаходимося на адресу 14, х знаходиться за адресою 10. 85 00:06:53,820 --> 00:07:00,180 Коли ми починаємо на б, ми разименованія б, ми збираємося, щоб захопити значення 2. 86 00:07:00,180 --> 00:07:08,320 Ми збираємося захопити це значення, тому що це цінність, яка мешкає за адресою 14. 87 00:07:08,320 --> 00:07:15,700 І ми збираємося помістити його в змінний, який мешкає за адресою 10, 88 00:07:15,700 --> 00:07:19,160 який тут же, відповідна нашої змінної х. 89 00:07:19,160 --> 00:07:21,810 Так що ми можемо зробити трохи перезапису тут 90 00:07:21,810 --> 00:07:35,380 де ми позбудемося 1 і замість цього написати 2. 91 00:07:35,380 --> 00:07:39,560 Так що все добре, і гарний у світі, хоча ми перезаписані х зараз. 92 00:07:39,560 --> 00:07:44,890 Ми зберегли старе значення х в нашій TMP змінна. 93 00:07:44,890 --> 00:07:50,210 Таким чином, ми можемо завершити своп з нового рядка. 94 00:07:50,210 --> 00:07:53,030 Подавати до нашого ноутбука. 95 00:07:53,030 --> 00:07:58,150 Тепер все, що залишається взяти вміст з нашого тимчасового цілої змінної 96 00:07:58,150 --> 00:08:05,630 і зберігати їх в змінну, яка мешкає за адресою, що б тримає. 97 00:08:05,630 --> 00:08:10,230 Так що ми збираємося ефективно разименованія б одержати доступ до змінної 98 00:08:10,230 --> 00:08:14,340 тобто за адресою, що б проводить у ньому, 99 00:08:14,340 --> 00:08:19,190 і ми збираємося, щоб наповнити значенням, TMP тримається в ній. 100 00:08:19,190 --> 00:08:23,280 Подавати назад в IPad ще раз. 101 00:08:23,280 --> 00:08:31,290 Я можу стерти це значення тут, 2, 102 00:08:31,290 --> 00:08:41,010 , А замість цього ми будемо копіювати на 1 прямо в нього. 103 00:08:41,010 --> 00:08:43,059 Тоді наступна рядок, яка виконує, звичайно, - 104 00:08:43,059 --> 00:08:47,150 якщо перевернути назад в ноутбук - це пункт 6, 105 00:08:47,150 --> 00:08:52,500 , Яка є точкою, в якій ми хотіли, щоб наш схема повністю заповнені. 106 00:08:52,500 --> 00:08:58,940 Таким чином, гортати назад в IPad ще раз, тільки так можна побачити закінчену схему, 107 00:08:58,940 --> 00:09:06,610 Ви можете бачити, що у нас 10 в, 14-В, 1 в TMP, 2-х та 1 в у. 108 00:09:06,610 --> 00:09:11,000 Є запитання з цього приводу? 109 00:09:11,000 --> 00:09:14,640 Чи має це сенс, пройшовши через це? 110 00:09:14,640 --> 00:09:24,850 Зробити менше сенсу? Сподіваюся, що ні. Добре. 111 00:09:24,850 --> 00:09:28,230 >> Покажчики є дуже складний предмет. 112 00:09:28,230 --> 00:09:33,420 Один з хлопців, з якими ми працюємо має дуже поширена приказка: 113 00:09:33,420 --> 00:09:36,590 "Щоб зрозуміти, покажчики, ви повинні спочатку зрозуміти покажчиків". 114 00:09:36,590 --> 00:09:40,530 Який я думаю, що це дуже вірно. Це займе деякий час, щоб звикнути до нього. 115 00:09:40,530 --> 00:09:45,360 Жеребкування фотографій, малювання великим обсягом пам'яті діаграм, як цей дуже корисний, 116 00:09:45,360 --> 00:09:49,480 і після того, як ви йдете через, наприклад, після приклад за прикладом, 117 00:09:49,480 --> 00:09:54,450 він почне робити трохи більше сенсу і трохи більше сенсу і трохи більше сенсу. 118 00:09:54,450 --> 00:10:01,560 Нарешті, в один прекрасний день, ви будете мати все це повністю освоєні. 119 00:10:01,560 --> 00:10:13,800 Будь-які питання, перш ніж ми перейдемо до наступної проблеми? Добре. 120 00:10:13,800 --> 00:10:18,840 Так перевернути назад в ноутбук. 121 00:10:18,840 --> 00:10:23,300 Наступна проблема, у нас це проблема номер 33 на файл I / O. 122 00:10:23,300 --> 00:10:26,350 Збільшити на це небагато. 123 00:10:26,350 --> 00:10:28,710 Завдання 33 - Так? 124 00:10:28,710 --> 00:10:32,110 >> [Даниїл] Я тільки що був швидкий питання. Ця зірка, або зірочки, 125 00:10:32,110 --> 00:10:35,590 це називається разименованія при використанні зірочки раніше. 126 00:10:35,590 --> 00:10:38,820 Як це називається, коли ви використовуєте амперсанд раніше? 127 00:10:38,820 --> 00:10:43,140 >> Амперсанд, перш ніж це адреса-оператора. 128 00:10:43,140 --> 00:10:45,880 Так що давайте прокрутити назад. 129 00:10:45,880 --> 00:10:49,310 Ой. Я в режим масштабування, тому я не можу дійсно прокрутки. 130 00:10:49,310 --> 00:10:52,780 Якщо ми подивимося на цей код дуже швидко, прямо тут, 131 00:10:52,780 --> 00:10:54,980 знову, те ж саме відбувається. 132 00:10:54,980 --> 00:10:59,180 Якщо ми подивимося на цей код прямо тут, на цій лінії, де ми зробити дзвінок, щоб поміняти, 133 00:10:59,180 --> 00:11:10,460 амперсанд просто кажу "отримати адресу, за якою змінна х життя". 134 00:11:10,460 --> 00:11:14,460 Якщо ваш компілятор компілює код, 135 00:11:14,460 --> 00:11:20,590 вона має насправді фізично виділити місце в пам'яті для всіх ваших змінних, щоб жити. 136 00:11:20,590 --> 00:11:24,910 І те, що компілятор може зробити, як тільки ви зібрали всі, 137 00:11:24,910 --> 00:11:31,110 він знає: "О, я поклав х на адресу 10. Я поклав у на адресу 14". 138 00:11:31,110 --> 00:11:34,640 Він може заповнити ці значення для вас. 139 00:11:34,640 --> 00:11:44,740 Таким чином, ви можете - він може потім передати це в проході і і у в а. 140 00:11:44,740 --> 00:11:50,730 Ці хлопці отримати адресу, але вони також, коли ви передаєте їх у своп функції, 141 00:11:50,730 --> 00:11:55,690 цей тип інформації, цей Int * прямо тут, говорить компілятору, 142 00:11:55,690 --> 00:12:01,350 "Добре, ми збираємося інтерпретації цю адресу як адресу цілої змінної". 143 00:12:01,350 --> 00:12:05,900 На адресу INT, який відрізняється від адреси символьної змінної 144 00:12:05,900 --> 00:12:09,930 тому що Int займає, на 32-бітної машині, займає 4 байти простору, 145 00:12:09,930 --> 00:12:13,310 в той час як характер тільки займає 1 байт. 146 00:12:13,310 --> 00:12:17,310 Тому дуже важливо знати і те, що є - те, що живе, який тип значення 147 00:12:17,310 --> 00:12:20,340 мешкає за адресою, який отримав пройшло дюйма 148 00:12:20,340 --> 00:12:22,020 Або адресу, яку ви маєте справу. 149 00:12:22,020 --> 00:12:29,020 Таким чином, ви знаєте, скільки байтів інформації насправді завантажити з оперативної пам'яті. 150 00:12:29,020 --> 00:12:31,780 І потім, так, це оператор разименованія, як ви просили, 151 00:12:31,780 --> 00:12:37,200 йде і доступ до інформації за певною адресою. 152 00:12:37,200 --> 00:12:42,820 Так він каже, з цієї змінної тут, належать зміст, адреса, 153 00:12:42,820 --> 00:12:47,880 піти на цю адресу, і витягнути, завантажити в процесор, навантаження в регістр 154 00:12:47,880 --> 00:12:56,340 Фактичні значення або змісту, які живуть за цією адресою. 155 00:12:56,340 --> 00:12:59,620 Є ще питання? Це хороші питання. 156 00:12:59,620 --> 00:13:01,650 Це багато нової термінології теж. 157 00:13:01,650 --> 00:13:09,800 Це також вид фанк, бачачи & * і в різних місцях. 158 00:13:09,800 --> 00:13:13,180 >> Добре. 159 00:13:13,180 --> 00:13:18,530 Отже, повернемося до задачі 33, файловий ввід / вивід 160 00:13:18,530 --> 00:13:22,540 Це була одна з тих проблем, які я думаю, що пару речей відбулося. 161 00:13:22,540 --> 00:13:25,400 Один з них, це досить нова тема. 162 00:13:25,400 --> 00:13:30,590 Він був представлений досить скоро перед вікторини, 163 00:13:30,590 --> 00:13:33,400 і тоді я думаю, це було щось начебто однієї з тих текстових задач з математики 164 00:13:33,400 --> 00:13:39,720 де вони дають вам багато інформації, але ви насправді не до кінця того, щоб використовувати тонни цього. 165 00:13:39,720 --> 00:13:44,060 У першій частині цієї проблеми опису того, що файл CSV є. 166 00:13:44,060 --> 00:13:50,620 Тепер, файлів CSV, у відповідності з описом, є значень, розділених комами файл. 167 00:13:50,620 --> 00:13:55,300 Причина це взагалі цікаво, і з цієї причини ви ніколи не використовуєте їх, 168 00:13:55,300 --> 00:14:00,800 це, тому що, як багато хто з вас коли-небудь використовували такі речі, як Excel? 169 00:14:00,800 --> 00:14:03,240 Малюнок більшість з вас, напевно, чи буде використовувати в якийсь момент у вашому житті. 170 00:14:03,240 --> 00:14:06,430 Ви будете використовувати щось на зразок Excel. 171 00:14:06,430 --> 00:14:10,940 Для того, щоб отримати дані з таблиці Excel або зробити який-небудь обробці з ним, 172 00:14:10,940 --> 00:14:17,240 якби ви хотіли, щоб написати програму C або Python програми, Java програми, 173 00:14:17,240 --> 00:14:20,070 мати справу з даними, що зберігаються там, 174 00:14:20,070 --> 00:14:23,170 одним з найбільш поширених способів отримати його в файл CSV. 175 00:14:23,170 --> 00:14:26,850 І ви можете відкрити Excel і коли ви йдете в "Зберегти як" діалог, 176 00:14:26,850 --> 00:14:32,840 Ви можете вийти з поточного файлу CSV. 177 00:14:32,840 --> 00:14:35,890 >> Handy знати, як мати справу з цими речами. 178 00:14:35,890 --> 00:14:42,010 Як це працює в тому, що це схоже на - я маю на увазі, вона, по суті, імітуючи таблицю, 179 00:14:42,010 --> 00:14:47,590 де, як ми бачимо тут, у самому лівому шматок, 180 00:14:47,590 --> 00:14:49,910 у нас є всі прізвища. 181 00:14:49,910 --> 00:14:54,670 Отже, ми маємо Малан, то Хардісон, а потім Боуден, MacWilliam, а потім Чан. 182 00:14:54,670 --> 00:14:59,470 Всі прізвища. І тоді кома відокремлює прізвищ з перших імен. 183 00:14:59,470 --> 00:15:02,970 Давид, Nate, Роб, Томмі і Zamyla. 184 00:15:02,970 --> 00:15:06,850 Я завжди змішувати Роббі і Тома. 185 00:15:06,850 --> 00:15:10,940 І ось, нарешті, третій стовпець адреси електронної пошти. 186 00:15:10,940 --> 00:15:18,500 Як тільки ви зрозумієте, що інша частина програми досить простий в реалізації. 187 00:15:18,500 --> 00:15:23,850 Що ми зробили для того, щоб імітувати цю ж структуру в нашій програмі C 188 00:15:23,850 --> 00:15:27,510 це ми використовували структуру. 189 00:15:27,510 --> 00:15:30,520 Ми почнемо грати з цим трохи більше, а також. 190 00:15:30,520 --> 00:15:35,790 Ми бачили їх у перший трохи в проблемі набір 3, коли ми маємо справу зі словниками. 191 00:15:35,790 --> 00:15:40,290 Але це співробітники структура зберігає прізвище, ім'я та електронну пошту. 192 00:15:40,290 --> 00:15:44,500 Так само, як наш файл CSV був зберігання. 193 00:15:44,500 --> 00:15:47,950 Так що це просто конвертації з одного формату в іншій. 194 00:15:47,950 --> 00:15:54,630 Ми повинні перетворити, в цьому випадку, співробітники структур в лінію, 195 00:15:54,630 --> 00:15:59,060 розділених комами лінії, як і що. 196 00:15:59,060 --> 00:16:01,500 Чи має це сенс? Ви, хлопці, всі прийняті вікторини, 197 00:16:01,500 --> 00:16:07,680 так що я думаю, ви по крайней мере, було деякий час, щоб подумати про це. 198 00:16:07,680 --> 00:16:16,410 >> У прокат функції, завдання вимагає від нас, щоб взяти в - МИ збільшити на цьому небагато - 199 00:16:16,410 --> 00:16:22,480 прийняти в штатну структуру, персонал структури, з ім'ям S, 200 00:16:22,480 --> 00:16:30,900 і додати його вміст нашого файлу staff.csv. 201 00:16:30,900 --> 00:16:34,230 Виявляється, що це досить простий у використанні. 202 00:16:34,230 --> 00:16:37,430 Ми видів пограти з цими функціями трохи більше сьогодні. 203 00:16:37,430 --> 00:16:44,510 Але в даному випадку, Fprintf функція дійсно є ключовою. 204 00:16:44,510 --> 00:16:51,960 Так що з Fprintf, ми можемо надрукувати, як і ви, хлопці, вже використовують Printf весь цей термін. 205 00:16:51,960 --> 00:16:55,050 Ви можете Printf рядок у файл. 206 00:16:55,050 --> 00:16:59,030 Таким чином, замість того щоб просто зробити звичайну Printf виклик, де ви даєте йому рядок формату 207 00:16:59,030 --> 00:17:05,380 , А потім замінити всі змінні з наступними аргументами, 208 00:17:05,380 --> 00:17:11,290 з Fprintf, ваш перший аргумент, замість файлу, який ви хочете записати. 209 00:17:11,290 --> 00:17:21,170 Якщо ми подивимося на це в прилад, наприклад, людина Fprintf, 210 00:17:21,170 --> 00:17:25,980 ми можемо побачити різницю між Printf і Fprintf. 211 00:17:25,980 --> 00:17:28,960 Я збільшити тут небагато. 212 00:17:28,960 --> 00:17:33,140 Так що з Printf, ми даємо йому рядок формату, а потім наступні міркування 213 00:17:33,140 --> 00:17:37,580 Тут всі змінні для заміни або підстановки в нашому форматі рядки. 214 00:17:37,580 --> 00:17:47,310 У той час як з Fprintf, перший аргумент насправді цей файл * називається потоком. 215 00:17:47,310 --> 00:17:51,800 >> Повертаючись сюди, щоб наш прокат, 216 00:17:51,800 --> 00:17:54,550 Ми вже отримали наш файл * потік відкритий для нас. 217 00:17:54,550 --> 00:17:57,810 Це те, що це перша лінія робить, він відкриває файл staff.csv, 218 00:17:57,810 --> 00:18:01,690 воно відкривається в режимі додавання, і все, що залишилося для нас зробити, це 219 00:18:01,690 --> 00:18:08,640 написати штатної структури в файл. 220 00:18:08,640 --> 00:18:10,870 І, давайте подивимося, я хочу використовувати IPad? 221 00:18:10,870 --> 00:18:17,900 Я буду використовувати iPad. У нас є порожнеча - Давайте поставимо це на стіл, щоб я міг написати трохи краще - 222 00:18:17,900 --> 00:18:33,680 анулювати оренду і бере в один аргумент, штатна структура називається с. 223 00:18:33,680 --> 00:18:44,120 Є наші дужки, ми отримали наш файл * називається файл, 224 00:18:44,120 --> 00:18:48,380 у нас є Еореп лінії нам дано, 225 00:18:48,380 --> 00:18:51,890 а я просто пишу це як точки, так як це вже в Pedia. 226 00:18:51,890 --> 00:19:00,530 І тоді на нашій наступній рядку, ми збираємося зробити дзвінок в Fprintf 227 00:19:00,530 --> 00:19:03,700 і ми збираємося пройти в файл, який ми хочемо друкувати, 228 00:19:03,700 --> 00:19:10,290 і тоді наша рядок формату, який - 229 00:19:10,290 --> 00:19:14,300 Я повідомлю вам, хлопці скажіть мені, що він виглядає. 230 00:19:14,300 --> 00:19:20,500 Як щодо вас, Стела? Ви знаєте, що перша частина рядка формату виглядає? 231 00:19:20,500 --> 00:19:24,270 [Stella] Я не впевнений. >> Не соромтеся задавати Джиммі. 232 00:19:24,270 --> 00:19:27,690 Чи знаєте ви, Джиммі? 233 00:19:27,690 --> 00:19:31,000 [Джиммі] Чи буде це просто бути в останній раз? Я не знаю. Я не зовсім впевнений. 234 00:19:31,000 --> 00:19:39,020 >> Добре. Як щодо того, хто-небудь отримати правильне на іспиті? 235 00:19:39,020 --> 00:19:41,770 Ні, все в порядку. 236 00:19:41,770 --> 00:19:47,920 Виявляється, що тут все, що ми повинні зробити, це ми хочемо, щоб кожна частина нашої штатної структури 237 00:19:47,920 --> 00:19:53,290 бути роздруковані у вигляді рядка в нашому файлі. 238 00:19:53,290 --> 00:19:59,900 Ми просто використовувати рядок символів заміни трьох різних разів, тому що у нас є прізвища 239 00:19:59,900 --> 00:20:07,160 з подальшою комою, то ім'я слід кома, 240 00:20:07,160 --> 00:20:12,430 і, нарешті, адресу електронної пошти, який слід - що не 241 00:20:12,430 --> 00:20:15,140 установки на екрані - але за ним слідує символ нового рядка. 242 00:20:15,140 --> 00:20:20,060 Так що я збираюся писати тільки там. 243 00:20:20,060 --> 00:20:23,560 А потім після нашого формату рядка, 244 00:20:23,560 --> 00:20:27,880 ми просто повинні заміни, які ми отримуємо доступ допомогою точкової нотації 245 00:20:27,880 --> 00:20:31,370 що ми бачили в проблемі набору 3. 246 00:20:31,370 --> 00:20:48,820 Ми можемо використовувати s.last, s.first, і s.email 247 00:20:48,820 --> 00:20:58,990 замінити в цих трьох цінностей в нашому форматі рядки. 248 00:20:58,990 --> 00:21:06,190 Так як все пройшло? Сенс? 249 00:21:06,190 --> 00:21:09,700 Так? Ні? Можливо? Добре. 250 00:21:09,700 --> 00:21:14,180 >> Остання річ, що ми робимо, після того як ми друкованих та після того як ми відкрили наш файл: 251 00:21:14,180 --> 00:21:17,370 всякий раз, коли ми відкрили файл, ми завжди повинні пам'ятати, щоб закрити його. 252 00:21:17,370 --> 00:21:19,430 Тому що інакше ми в кінцевому підсумку витік пам'яті, 253 00:21:19,430 --> 00:21:22,500 з використанням до файлових дескрипторів. 254 00:21:22,500 --> 00:21:25,950 Таким чином, щоб закрити його, які функції ми використовуємо? Деніел? 255 00:21:25,950 --> 00:21:30,120 [Даниїл] Fclose? >> Fclose, точно. 256 00:21:30,120 --> 00:21:37,520 Таким чином, остання частина цієї проблеми було правильно закрити файл, використовуючи Fclose функції, 257 00:21:37,520 --> 00:21:40,370 який виглядає так. 258 00:21:40,370 --> 00:21:43,880 Не надто божевільним. 259 00:21:43,880 --> 00:21:46,990 Cool. 260 00:21:46,990 --> 00:21:49,520 Так що це проблема 33 на вікторину. 261 00:21:49,520 --> 00:21:52,480 Ми повинні, безумовно, більш файлового введення / виводу йдуть вгору. 262 00:21:52,480 --> 00:21:55,130 Ми зробимо трохи більше в сьогоднішній лекції, або в розділі сьогодні, 263 00:21:55,130 --> 00:22:01,710 тому що це те, що збирається складають основну частину цієї майбутньої PSET. 264 00:22:01,710 --> 00:22:05,020 Давайте перейдемо від вікторину в цій точці. Так? 265 00:22:05,020 --> 00:22:10,880 >> [Charlotte]] Чому Fclose (файл), а Fclose (staff.csv)? 266 00:22:10,880 --> 00:22:19,100 >> Ач. Бо виходить, що - так що питання, яке є більшим, 267 00:22:19,100 --> 00:22:27,800 Ось чому, коли ми пишемо Fclose, ми письмово Fclose (файлу) змінної зірки 268 00:22:27,800 --> 00:22:33,680 на відміну від імен файлів, staff.csv? Хіба це правильно? Так. 269 00:22:33,680 --> 00:22:39,570 Отже, давайте подивимося. Якби я повернутися до моїх ноутбуком, 270 00:22:39,570 --> 00:22:45,040 і давайте подивимося на Fclose функції. 271 00:22:45,040 --> 00:22:51,460 Так Fclose функція закриває потік, і він приймає в покажчик на потік, що ми хочемо закрити, 272 00:22:51,460 --> 00:22:57,010 на відміну від фактичного імені файлу, який ми хочемо закрити. 273 00:22:57,010 --> 00:23:01,620 І це тому, що за лаштунками, коли ви робите виклик Еореп, 274 00:23:01,620 --> 00:23:12,020 коли ви відкриваєте файл, ви насправді виділення пам'яті для зберігання інформації про файл. 275 00:23:12,020 --> 00:23:16,380 Таким чином, у вас є файл покажчик, який містить інформацію про файл, 276 00:23:16,380 --> 00:23:23,080 таких, як він відкритий, його розмір, де ви знаходитеся в даний момент файлу, 277 00:23:23,080 --> 00:23:29,100 так що ви можете зробити читання і запис викликів, що особливе місце у файлі. 278 00:23:29,100 --> 00:23:38,060 Ви в кінцевому підсумку закриття покажчика замість закриття файлу. 279 00:23:38,060 --> 00:23:48,990 >> Так? [Даниїл] Таким чином, для того, щоб використовувати прокат, ви скажете - як це отримати дані, введені користувачем? 280 00:23:48,990 --> 00:23:53,830 Хіба Fprintf діяти як GetString в тому сенсі, що це буде просто чекати введення користувача 281 00:23:53,830 --> 00:23:57,180 і просимо вас ввести цей - або чекати, поки ви вводите ці три речі? 282 00:23:57,180 --> 00:24:00,480 Або вам потрібно використовувати щось для здійснення оренди? 283 00:24:00,480 --> 00:24:04,100 >> Да. Так що ми не - питання було, як ми можемо отримати дані, введені користувачем 284 00:24:04,100 --> 00:24:09,220 З метою реалізації оренду? І те, що ми маємо тут справу з зухвалою прокату, 285 00:24:09,220 --> 00:24:17,690 Пройшло в цьому штаті структура з усіма даними, що зберігаються в структурі вже. 286 00:24:17,690 --> 00:24:22,990 Так Fprintf може просто написати, що дані безпосередньо у файлі. 287 00:24:22,990 --> 00:24:25,690 Там немає очікуванні введення користувача. 288 00:24:25,690 --> 00:24:32,110 Користувач вже дав вхідний належним чином поставивши його в цьому штаті структури. 289 00:24:32,110 --> 00:24:36,510 І все, звичайно, було б зламатися, якщо будь-який з цих покажчиків були нульові, 290 00:24:36,510 --> 00:24:40,370 таким чином, ми прокрутити назад тут, і ми дивимося на нашу структуру. 291 00:24:40,370 --> 00:24:43,640 У нас є остання стрічка, стрічка перше, рядки електронній пошті. 292 00:24:43,640 --> 00:24:48,530 Ми тепер знаємо, що всі ці насправді, під капотом, це символ змінних *. 293 00:24:48,530 --> 00:24:53,470 Це може або не може бути направлений до нуля. 294 00:24:53,470 --> 00:24:55,800 Вони можуть бути спрямовані на пам'ять в купі, 295 00:24:55,800 --> 00:24:59,650 Може бути, пам'ять на стеку. 296 00:24:59,650 --> 00:25:04,580 Ми дійсно не знаємо, але якщо будь-який з цих покажчиків дорівнюють нулю, або недійсним, 297 00:25:04,580 --> 00:25:08,120 , Що неодмінно аварії нашому прокаті функції. 298 00:25:08,120 --> 00:25:11,050 Це було щось, що було частково виходить за рамки іспиту. 299 00:25:11,050 --> 00:25:16,440 Ми не турбуватися про це. 300 00:25:16,440 --> 00:25:22,170 Великий. Добре. Таким чином, переходячи від вікторини. 301 00:25:22,170 --> 00:25:25,760 >> Давайте закриємо цей хлопець, і ми будемо дивитися на PSET 4. 302 00:25:25,760 --> 00:25:34,700 Так що, якщо ви, хлопці, подивіться на специфікації PSET, як тільки ви можете отримати до нього доступ, cs50.net/quizzes, 303 00:25:34,700 --> 00:25:42,730 Ми збираємося пройти через кілька розділу сьогоднішні проблеми. 304 00:25:42,730 --> 00:25:52,240 Я прокрутка вниз - розділ питань починається на третій сторінці PSET спец. 305 00:25:52,240 --> 00:25:57,800 І перша частина просить вас піти і подивитися короткий на перенаправлення та труб. 306 00:25:57,800 --> 00:26:02,820 Який був частково прохолодно Коротше кажучи, показує деякі нові, прохолодно командного рядка трюків, які ви можете використовувати. 307 00:26:02,820 --> 00:26:06,050 І тоді у нас є кілька питань до вас. 308 00:26:06,050 --> 00:26:10,860 Це перше питання про потоки, в яких Printf пише за замовчуванням, 309 00:26:10,860 --> 00:26:15,920 ми частково торкнулися тільки трохи хвилину тому. 310 00:26:15,920 --> 00:26:22,380 Це Fprintf, що ми тільки що обговорювали займає в потік файлу * в якості аргументу. 311 00:26:22,380 --> 00:26:26,580 Fclose займає в потік файлу *, а також, 312 00:26:26,580 --> 00:26:32,660 і значення, що повертається Еореп дає вам файл потоку *, а також. 313 00:26:32,660 --> 00:26:36,060 Тому ми не бачили тих, хто раніше, коли ми мали справу з Printf 314 00:26:36,060 --> 00:26:39,450 Тому Printf за замовчуванням має потоці. 315 00:26:39,450 --> 00:26:41,810 І за замовчуванням потік, в який він записує 316 00:26:41,810 --> 00:26:45,190 Ви дізнаєтеся про в короткостроковій. 317 00:26:45,190 --> 00:26:50,080 Таким чином, безумовно, поглянемо на це. 318 00:26:50,080 --> 00:26:53,010 >> У розділі Сьогодні, ми збираємося поговорити трохи про те, GDB, 319 00:26:53,010 --> 00:26:57,720 тому що чим більше ви знайомі з нею, тим більше практики ви отримуєте разом з ним, 320 00:26:57,720 --> 00:27:01,390 краще ви будете насправді вистежити помилки у власному коді. 321 00:27:01,390 --> 00:27:05,540 Це прискорює процес налагодження до надзвичайно. 322 00:27:05,540 --> 00:27:09,230 Таким чином, за допомогою Printf, кожен раз, коли ви робите, що вам доведеться перекомпілювати ваш код, 323 00:27:09,230 --> 00:27:13,000 Ви повинні запустити його знову, іноді ви повинні рухатися Printf виклик усьому, 324 00:27:13,000 --> 00:27:17,100 закоментувати код, він просто займає деякий час. 325 00:27:17,100 --> 00:27:20,850 Наша мета, щоб спробувати переконати вас, що з GDB, ви можете істотно 326 00:27:20,850 --> 00:27:26,810 Printf нічого в будь-якій точці вашого коду і вам ніколи не доведеться перекомпілювати. 327 00:27:26,810 --> 00:27:35,120 Ви ніколи не повинні починатися і гадати, де Printf наступному. 328 00:27:35,120 --> 00:27:40,910 Перше, що потрібно зробити, це скопіювати цей рядок і отримати код секції від стінки. 329 00:27:40,910 --> 00:27:47,530 Я копіюванні цей рядок коду, яка говорить: "Wget http://cdn.cs50.net". 330 00:27:47,530 --> 00:27:49,510 Я хочу, щоб скопіювати його. 331 00:27:49,510 --> 00:27:55,950 Я збираюся перейти на мій прилад, масштаб таким чином, ви можете бачити, що я роблю, 332 00:27:55,950 --> 00:28:01,890 вставивши туди, і коли я вдарив Enter, ця команда буквально Wget є веб отримаєте. 333 00:28:01,890 --> 00:28:06,210 Це збирається знести цей файл з мережі Інтернет, 334 00:28:06,210 --> 00:28:11,790 і він збирається зберегти його в поточному каталозі. 335 00:28:11,790 --> 00:28:21,630 Тепер, якщо я перераховую моєму поточному каталозі ви можете побачити, що я отримав цю section5.zip файл прямо там. 336 00:28:21,630 --> 00:28:25,260 Щоб справитися з цим хлопцем, щоб розпакувати його, 337 00:28:25,260 --> 00:28:27,650 Це можна зробити в командному рядку, як це. 338 00:28:27,650 --> 00:28:31,880 Section5.zip. 339 00:28:31,880 --> 00:28:36,980 Це буде розпакувати його, створіть папку для мене, 340 00:28:36,980 --> 00:28:40,410 роздмухувати весь вміст, покласти їх туди. 341 00:28:40,410 --> 00:28:47,410 Так що тепер я можу піти в мій розділ 5 каталозі за допомогою компакт-диска команди. 342 00:28:47,410 --> 00:28:58,310 Очистити екран за допомогою ясно. Таким чином очистити екран. 343 00:28:58,310 --> 00:29:02,280 Тепер у мене є хороший чистий термінал справу. 344 00:29:02,280 --> 00:29:06,200 >> Тепер, якщо я список всіх файлів, які я бачу в цьому каталозі, 345 00:29:06,200 --> 00:29:12,270 Ви бачите, що в мене є чотири файли: buggy1, buggy2, buggy3, і buggy4. 346 00:29:12,270 --> 00:29:16,180 Я також отримав відповідні. С файлами. 347 00:29:16,180 --> 00:29:20,400 Ми не збираємося дивитися на. Файли з на даний момент. 348 00:29:20,400 --> 00:29:24,140 Замість цього, ми збираємося використовувати їх, коли ми відкриваємо GDB. 349 00:29:24,140 --> 00:29:28,220 Ми тримали їх навколо так, що ми маємо доступ до вихідного коду, коли ми використовуємо GDB, 350 00:29:28,220 --> 00:29:32,740 але мета цієї частини розділу возитися навколо з GDB 351 00:29:32,740 --> 00:29:40,370 і подивитися, як ми можемо використовувати його, щоб з'ясувати, що відбувається не так з кожною з цих чотирьох програм баггі. 352 00:29:40,370 --> 00:29:43,380 Таким чином, ми тільки збираємося в кімнаті дуже швидко, 353 00:29:43,380 --> 00:29:47,000 і я збираюся попросити кого-небудь запустити одну з програм баггі, 354 00:29:47,000 --> 00:29:54,730 а потім ми підемо в групу через GDB, і ми побачимо, що ми можемо зробити, щоб виправити ці програми, 355 00:29:54,730 --> 00:29:58,460 або, принаймні визначити, що відбувається не так у кожному з них. 356 00:29:58,460 --> 00:30:04,760 Давайте почнемо тут з Даніелем. Чи будете ви балотуватися buggy1? Давайте подивимося, що відбувається. 357 00:30:04,760 --> 00:30:09,470 [Даниїл] Він каже, що є додаток вина. >> Да. Саме так. 358 00:30:09,470 --> 00:30:12,460 Так що, якщо я біжу buggy1, я отримую сегменті вина. 359 00:30:12,460 --> 00:30:16,210 На даний момент, я можу піти і відкрити buggy1.c, 360 00:30:16,210 --> 00:30:19,450 спробувати з'ясувати, що відбувається не так, 361 00:30:19,450 --> 00:30:22,000 але одна з найнеприємніших речей про цю помилку сегменті вина 362 00:30:22,000 --> 00:30:27,610 те, що він не скаже вам про те, що рядок програми речі насправді пішло не так і зламався. 363 00:30:27,610 --> 00:30:29,880 Ви начебто повинні дивитися на код 364 00:30:29,880 --> 00:30:33,990 і з'ясувати, використання припущення і перевірити чи Printf щоб побачити, що відбувається не так. 365 00:30:33,990 --> 00:30:37,840 Одна з кращих речей про GDB є те, що це дуже, дуже легко 366 00:30:37,840 --> 00:30:42,170 щоб з'ясувати лінія, на якій збою програми. 367 00:30:42,170 --> 00:30:46,160 Це повністю стоїть того, щоб його використовувати, навіть якщо тільки для цього. 368 00:30:46,160 --> 00:30:56,190 Таким чином, для завантаження GDB, я типу GDB, а потім я даю йому шлях до виконуваного файлу, що я хочу працювати. 369 00:30:56,190 --> 00:31:01,960 Тут я друкую GDB ./buggy1. 370 00:31:01,960 --> 00:31:06,600 Натисніть Enter. Дає мені все це інформація про авторські права, 371 00:31:06,600 --> 00:31:13,000 і тут ви побачите цей рядок, яка говорить: "Читання символів з / Головна / 372 00:31:13,000 --> 00:31:17,680 jharvard/section5/buggy1 ". 373 00:31:17,680 --> 00:31:22,060 І якщо все піде добре, ви побачите, що виведіть повідомлення, яке виглядає наступним чином. 374 00:31:22,060 --> 00:31:25,500 Він буде читати символи, він скаже: "Я читаю символи з виконуваного файлу" 375 00:31:25,500 --> 00:31:29,900 , А потім вона буде мати це "зроблено" повідомлення тут. 376 00:31:29,900 --> 00:31:35,410 Якщо ви бачите деякі інші варіації цього, чи ви бачите його не могли знайти символи 377 00:31:35,410 --> 00:31:41,460 або щось на зразок того, що це означає, що ви просто ще не складено виконуваний файл належним чином. 378 00:31:41,460 --> 00:31:49,980 При компіляції програми для роботи з GDB, ми повинні використовувати цю спеціальну г-прапор, 379 00:31:49,980 --> 00:31:54,540 і що робиться за замовчуванням, якщо ви компілюєте ваші програми, просто набравши зробити 380 00:31:54,540 --> 00:31:59,320 або роблять помилки або роблять відновити, будь-який з них. 381 00:31:59,320 --> 00:32:07,800 Але якщо ви збираєте вручну за допомогою Clang, то вам доведеться піти і включати, що г-прапор. 382 00:32:07,800 --> 00:32:10,310 >> На даний момент, тепер у нас є GDB рядку 383 00:32:10,310 --> 00:32:12,310 це досить просто запустити програму. 384 00:32:12,310 --> 00:32:19,740 Ми можемо або ввести перспективі, або ми можемо просто Type-R. 385 00:32:19,740 --> 00:32:22,820 Більшість команд GDB може бути скорочена. 386 00:32:22,820 --> 00:32:25,940 Зазвичай тільки один чи пару букв, який є досить хорошим. 387 00:32:25,940 --> 00:32:30,980 Так Саад, якщо ви Type R і натисніть Enter, що відбувається? 388 00:32:30,980 --> 00:32:39,390 [Саад] Я отримав SIGSEGV, помилки сегментації, а потім все це абракадаброю. 389 00:32:39,390 --> 00:32:43,650 >> Да. 390 00:32:43,650 --> 00:32:47,990 Як ми бачимо на екрані прямо зараз, і, як Саад сказав: 391 00:32:47,990 --> 00:32:53,430 коли ми вводимо пробігу або R і натисніть Enter, ми до сих пір отримати той же сегмент вина. 392 00:32:53,430 --> 00:32:55,830 Таким чином, використання GDB не вирішує наші проблеми. 393 00:32:55,830 --> 00:32:59,120 Але це дає нам деякий абракадабру, і виявляється, що це абракадаброю 394 00:32:59,120 --> 00:33:03,080 насправді говорить нам, де це відбувається. 395 00:33:03,080 --> 00:33:10,680 Для розбору цього небагато, це перший біт є функцією, в якій все відбувається не так. 396 00:33:10,680 --> 00:33:20,270 Там ця __ strcmp_sse4_2, і він говорить нам, що відбувається в цьому файлі 397 00:33:20,270 --> 00:33:29,450 називається sysdeps/i386, все це, знову ж, вид безлад - але лінія 254. 398 00:33:29,450 --> 00:33:31,670 Це свого роду важко розібрати. Зазвичай, коли ви бачите такі речі, як це, 399 00:33:31,670 --> 00:33:38,770 , Що означає, що вона сегментам розломів в одній із системних бібліотек. 400 00:33:38,770 --> 00:33:43,220 Так що щось робити з STRCMP. Ви, хлопці, бачили STRCMP раніше. 401 00:33:43,220 --> 00:33:52,730 Не надто божевільним, але це означає, що STRCMP зламаний або що є проблема з STRCMP? 402 00:33:52,730 --> 00:33:57,110 Як ви думаєте, Олександре? 403 00:33:57,110 --> 00:34:04,890 [Олександр] Це що - становить 254 ліній? І - не двійковий, але це не їх стелі, 404 00:34:04,890 --> 00:34:10,590 а там інша мова для кожної функції. Хіба що 254 у цій функції, або -? 405 00:34:10,590 --> 00:34:21,460 >> Це лінія 254. Схоже, що в цьому немає. Файл с, так що це, ймовірно, зборка код. 406 00:34:21,460 --> 00:34:25,949 >> Але, я думаю, більш насущні речі є, тому що ми отримали сегменті вина, 407 00:34:25,949 --> 00:34:29,960 і, схоже, це йде від STRCMP функції, 408 00:34:29,960 --> 00:34:38,030 це має на увазі, те, що STRCMP не працює? 409 00:34:38,030 --> 00:34:42,290 Це не повинно, ми сподіваємося. Таким чином, тільки тому, що у вас є помилки сегментації 410 00:34:42,290 --> 00:34:49,480 В одній з функцій системи, як правило, це означає, що ви просто не називати його правильно. 411 00:34:49,480 --> 00:34:52,440 Найшвидший, що потрібно зробити, щоб з'ясувати, що відбувається насправді 412 00:34:52,440 --> 00:34:55,500 коли ви бачите щось божевільний, як це, коли ви бачите сегмент вина, 413 00:34:55,500 --> 00:34:59,800 Особливо, якщо у вас є програма, яка використовує більше, ніж просто основний, 414 00:34:59,800 --> 00:35:03,570 це використовувати трасування. 415 00:35:03,570 --> 00:35:13,080 Я скорочую слід у письмовій формі BT, на відміну від повного слова трасування. 416 00:35:13,080 --> 00:35:16,510 Але Шарлотта, що відбувається, коли ви набираєте BT і натисніть Enter? 417 00:35:16,510 --> 00:35:23,200 [Charlotte] Він показує мені два рядки, 0 лінією і лінією 1. 418 00:35:23,200 --> 00:35:26,150 >> Да. Таким чином, лінія 0 і лінії 1. 419 00:35:26,150 --> 00:35:34,560 Ці фактичні кадри стека, що в даний час в грі, коли ваша програма розбився. 420 00:35:34,560 --> 00:35:42,230 Починаючи з верхнього кадру, кадр 0 і, підійшовши до самої нижньої, яка є кадр 1. 421 00:35:42,230 --> 00:35:45,140 Наша верхня рама STRCMP кадру. 422 00:35:45,140 --> 00:35:50,080 Ви можете думати про це як же, проблема, яку ми робили тільки на вікторину з покажчиками, 423 00:35:50,080 --> 00:35:54,890 де ми поміняти стек поверх основного кадру стека, 424 00:35:54,890 --> 00:35:59,700 і у нас були змінні, які підкачки використовує у верхній частині змінних, основним використовую. 425 00:35:59,700 --> 00:36:08,440 Тут наша аварії сталися в нашій STRCMP функція, яка отримала назву нашої основної функції, 426 00:36:08,440 --> 00:36:14,370 і трасування дає нам не тільки функції, в якому речі не вдалося, 427 00:36:14,370 --> 00:36:16,440 але це також говорить нам, де все було викликано. 428 00:36:16,440 --> 00:36:18,830 Так що якщо я виділіть на трохи більше правої, 429 00:36:18,830 --> 00:36:26,110 ми бачимо, що так, ми були на лінії 254 цього STRCMP-sse4.s файл. 430 00:36:26,110 --> 00:36:32,540 Але дзвінок був зроблений на buggy1.c, рядок 6. 431 00:36:32,540 --> 00:36:35,960 Таким чином, це означає, що ми можемо зробити, - це ми можемо просто піти перевірити і подивитися, що відбувається на 432 00:36:35,960 --> 00:36:39,930 в buggy1.c, рядок 6. 433 00:36:39,930 --> 00:36:43,780 Знову ж таки, є кілька способів зробити це. Один з них, щоб вийти з GDB 434 00:36:43,780 --> 00:36:49,460 або ваш код відкритий в іншому вікні і перехресні посилання. 435 00:36:49,460 --> 00:36:54,740 Це, само по собі, це дуже зручно, тому що тепер, якщо ви знаходитеся в офісі годин 436 00:36:54,740 --> 00:36:57,220 і у вас є сегменти вина і ваша TF це цікаво, де все було ламати, 437 00:36:57,220 --> 00:36:59,710 Ви можете просто сказати: "О, рядок 6. Я не знаю, що відбувається, 438 00:36:59,710 --> 00:37:03,670 але щось в рядку 6 є причиною моєї програми зламати ". 439 00:37:03,670 --> 00:37:10,430 Інший спосіб зробити це, ви можете використовувати цю команду називали список в GDB. 440 00:37:10,430 --> 00:37:13,650 Ви також можете скорочувати його з л. 441 00:37:13,650 --> 00:37:18,910 Таким чином, якщо ми потрапили л, що ми сюди потрапили? 442 00:37:18,910 --> 00:37:21,160 Ми отримуємо цілу купу дивних речей. 443 00:37:21,160 --> 00:37:26,030 Це фактичний код збірки 444 00:37:26,030 --> 00:37:29,860 , Який знаходиться в strcmp_sse4_2. 445 00:37:29,860 --> 00:37:32,440 Це виглядає роду фанки, 446 00:37:32,440 --> 00:37:36,520 і причина, ми отримуємо це тому, що зараз, 447 00:37:36,520 --> 00:37:40,160 GDB має нас в кадрі 0. 448 00:37:40,160 --> 00:37:43,070 >> Так що в будь-який час ми дивимося на змінні, в будь-який час подивитися на вихідний код, 449 00:37:43,070 --> 00:37:50,530 ми дивимося на вихідний код, який відноситься до кадру стека ми в даний час дюйма 450 00:37:50,530 --> 00:37:53,200 Так що для того, щоб отримати щось значиме, ми повинні 451 00:37:53,200 --> 00:37:57,070 перейти в стеці, що має більше сенсу. 452 00:37:57,070 --> 00:38:00,180 У цьому випадку, основною фрейм стеку б зробити трохи більше сенсу, 453 00:38:00,180 --> 00:38:02,680 тому що це було насправді код, який ми написали. 454 00:38:02,680 --> 00:38:05,330 Чи не STRCMP код. 455 00:38:05,330 --> 00:38:08,650 Те, як ви можете переміщатися між кадрами, в даному випадку, тому що у нас є два, 456 00:38:08,650 --> 00:38:10,430 у нас є 0 і 1, 457 00:38:10,430 --> 00:38:13,650 Ви робите це з вгору і вниз команди. 458 00:38:13,650 --> 00:38:18,480 Якщо я переїду один кадр, 459 00:38:18,480 --> 00:38:21,770 Зараз я в основному фреймі стека. 460 00:38:21,770 --> 00:38:24,330 Я можу рухатися вниз, щоб повернутися туди, де я був, 461 00:38:24,330 --> 00:38:32,830 йти знову, знову спуститися, і піднятися знову. 462 00:38:32,830 --> 00:38:39,750 Якщо ви коли-небудь зробити свою програму в GDB, ви отримуєте аварії, ви отримаєте слід, 463 00:38:39,750 --> 00:38:42,380 і ви побачите, що це в деякому файлі, який ви не знаєте, що відбувається. 464 00:38:42,380 --> 00:38:45,460 Ви намагаєтеся списку, код виглядає не знайомі вам, 465 00:38:45,460 --> 00:38:48,150 погляньте на ваші кадри і з'ясувати, де ви знаходитеся. 466 00:38:48,150 --> 00:38:51,010 Ви, напевно, не в тому фрейм стеку. 467 00:38:51,010 --> 00:38:58,760 Або, принаймні, ти в кадрі стека, що не один, що ви дійсно можете налагоджувати. 468 00:38:58,760 --> 00:39:03,110 Тепер, коли ми знаходимося у відповідному кадрі стека, ми в основному, 469 00:39:03,110 --> 00:39:08,100 Тепер ми можемо використовувати команду списку, щоб з'ясувати, які лінії було. 470 00:39:08,100 --> 00:39:13,590 І ви можете бачити його, він надрукував його для нас прямо тут. 471 00:39:13,590 --> 00:39:19,470 Але ми можемо вдарити перерахувати все те ж саме, і список дає нам цю гарну роздруківку 472 00:39:19,470 --> 00:39:23,920 фактичного вихідного коду, що відбувається тут. 473 00:39:23,920 --> 00:39:26,420 >> Зокрема, ми можемо подивитися на рядку 6. 474 00:39:26,420 --> 00:39:29,330 Ми бачимо, що відбувається тут. 475 00:39:29,330 --> 00:39:31,250 І, схоже, ми робимо порівняння рядків 476 00:39:31,250 --> 00:39:41,050 між рядків "CS50 породи" і ARGV [1]. 477 00:39:41,050 --> 00:39:45,700 Щось у цьому було збоїв. 478 00:39:45,700 --> 00:39:54,120 Таким чином, Міссі, чи є у вас думки про те, що може бути тут відбувається? 479 00:39:54,120 --> 00:39:59,400 [Missy] Я не знаю, чому це збій. >> Ти не знаєш, чому це збій? 480 00:39:59,400 --> 00:40:02,700 Джиммі, які думки? 481 00:40:02,700 --> 00:40:06,240 [Джиммі] я не зовсім впевнений, але в останній раз ми використовували порівняння рядків, 482 00:40:06,240 --> 00:40:10,260 або STRCMP, у нас були як три різних випадках під ним. 483 00:40:10,260 --> 00:40:12,800 У нас не було ==, я не думаю, що прямо в першому рядку. 484 00:40:12,800 --> 00:40:16,700 Замість цього він був розділений на три, а один був == 0, 485 00:40:16,700 --> 00:40:19,910 один був <0, я думаю, і один> 0. 486 00:40:19,910 --> 00:40:22,590 Тому, можливо, щось в цьому роді? >> Да. Так що це питання 487 00:40:22,590 --> 00:40:27,200 про ми робимо порівняння правильно? 488 00:40:27,200 --> 00:40:31,660 Stella? Будь-які думки? 489 00:40:31,660 --> 00:40:38,110 [Stella] Я не впевнений. >> Не впевнений. Деніел? Думки? Добре. 490 00:40:38,110 --> 00:40:44,770 Виявляється, те, що відбувається прямо тут, коли ми запустили програму 491 00:40:44,770 --> 00:40:48,370 і ми отримали сегменті провини, коли ви запускаєте програму в перший раз, Данило, 492 00:40:48,370 --> 00:40:50,800 ти дати йому ніяких аргументів командного рядка? 493 00:40:50,800 --> 00:40:58,420 [Даниїл] Немає >> Ні. У такому випадку, що є значенням ARGV [1]? 494 00:40:58,420 --> 00:41:00,920 >> Існує ніякого значення. >> Праві. 495 00:41:00,920 --> 00:41:06,120 Ну, немає відповідного значення рядка. 496 00:41:06,120 --> 00:41:10,780 Але є деяке значення. Що таке значення, яке отримує зберігається там? 497 00:41:10,780 --> 00:41:15,130 >> Сміття значення? >> Це або сміття вартості, або, в даному випадку, 498 00:41:15,130 --> 00:41:19,930 В кінці масиву ARGV завжди закінчується нульовим. 499 00:41:19,930 --> 00:41:26,050 Так що ж насправді є там зберігаються дорівнює нулю. 500 00:41:26,050 --> 00:41:30,810 Іншого способу вирішити цю проблему, а не думати його до кінця, 501 00:41:30,810 --> 00:41:33,420 полягає в спробі друку його. 502 00:41:33,420 --> 00:41:35,880 Це де я говорив, що за допомогою GDB є більшим, 503 00:41:35,880 --> 00:41:40,640 тому що ви можете роздрукувати всі змінні, всі значення, які ви хочете 504 00:41:40,640 --> 00:41:43,230 за допомогою цього зручного денді з командою. 505 00:41:43,230 --> 00:41:48,520 Так що якщо я типу Р, а потім я вводжу значення змінної або ім'я змінної, 506 00:41:48,520 --> 00:41:55,320 кажуть, агдс, я бачу, що агдс 1. 507 00:41:55,320 --> 00:42:01,830 Якщо я хочу, щоб роздрукувати ARGV [0], я можу зробити це просто так. 508 00:42:01,830 --> 00:42:04,840 І, як ми бачили, ARGV [0] завжди є ім'ям вашої програми, 509 00:42:04,840 --> 00:42:06,910 Завжди ім'я виконуваного файлу. 510 00:42:06,910 --> 00:42:09,740 Тут ви бачите, він отримав повне ім'я. 511 00:42:09,740 --> 00:42:15,920 Я також можете роздрукувати ARGV [1] і подивитися, що відбувається. 512 00:42:15,920 --> 00:42:20,890 >> Тут ми отримали таке містичне значення. 513 00:42:20,890 --> 00:42:23,890 Ми отримали цю 0x0. 514 00:42:23,890 --> 00:42:27,850 Пам'ятаєте, на початку семестру, коли ми говорили про шістнадцяткових чисел? 515 00:42:27,850 --> 00:42:34,680 Або що мало хто сумнівається в кінці PSET 0 про те, як складати 50 в шістнадцятковій? 516 00:42:34,680 --> 00:42:39,410 Як ми писати шістнадцяткові числа в CS, тільки щоб не плутати себе 517 00:42:39,410 --> 00:42:46,080 з десятковою числа, ми завжди їх з префіксом 0x. 518 00:42:46,080 --> 00:42:51,420 Так що цей префікс 0x завжди просто означає, інтерпретувати наступним число як шістнадцяткове число, 519 00:42:51,420 --> 00:42:57,400 а не як рядок, а не як десяткове число, а не як двійкові числа. 520 00:42:57,400 --> 00:43:02,820 Так як число 5-0 є дійсним числом в шістнадцятковій. 521 00:43:02,820 --> 00:43:06,240 І це число в десятковій, 50. 522 00:43:06,240 --> 00:43:10,050 Так що це тільки, як ми неоднозначність. 523 00:43:10,050 --> 00:43:14,860 Так 0x0 засобів шістнадцятковому 0, який також є десятковій 0, двійковий 0. 524 00:43:14,860 --> 00:43:17,030 Це тільки значення 0. 525 00:43:17,030 --> 00:43:22,630 Виявляється, що це те, що нульові, власне, в пам'яті. 526 00:43:22,630 --> 00:43:25,940 Null просто 0. 527 00:43:25,940 --> 00:43:37,010 Тут елемент зберігається в ARGV [1] дорівнює нулю. 528 00:43:37,010 --> 00:43:45,220 Таким чином, ми намагаємося порівняти наші "CS50 скелі" рядок порожній рядок. 529 00:43:45,220 --> 00:43:48,130 Так разименованія NULL, намагається отримати доступ до речі в нуль, 530 00:43:48,130 --> 00:43:55,050 ті, як правило, збирається викликати якусь несправність сегментації або інших поганих речей. 531 00:43:55,050 --> 00:43:59,350 І виявляється, що STRCMP не перевірити 532 00:43:59,350 --> 00:44:04,340 або не ви пройшли в значення, яке нульовий. 533 00:44:04,340 --> 00:44:06,370 Швидше за все, він просто йде вперед, намагається робити свою справу, 534 00:44:06,370 --> 00:44:14,640 і якщо він сегментам недоліки, він сегментам недоліки, і це ваша проблема. Ви повинні піти виправити. 535 00:44:14,640 --> 00:44:19,730 Дійсно швидко, як ми могли б вирішити цю проблему? Шарлотта? 536 00:44:19,730 --> 00:44:23,540 [Charlotte] Ви можете перевірити, якщо використання. 537 00:44:23,540 --> 00:44:32,240 Так що, якщо ARGV [1] є недійсним, == 0, то повертається 1, або щось в [нерозбірливо]. 538 00:44:32,240 --> 00:44:34,590 >> Да. Так ось один відмінний спосіб зробити це, як ми можемо перевірити, 539 00:44:34,590 --> 00:44:39,230 Значення, яке ми збираємося перейти в STRCMP, ARGV [1], його недійсним? 540 00:44:39,230 --> 00:44:45,830 Якщо це нуль, то можна сказати, добре, перервати. 541 00:44:45,830 --> 00:44:49,450 >> Більш поширений спосіб зробити це полягає у використанні агдс значення. 542 00:44:49,450 --> 00:44:52,040 Ви можете подивитися прямо тут, на самому початку головний, 543 00:44:52,040 --> 00:44:58,040 ми опустили, що перший тест, який ми зазвичай робимо, коли ми використовувати аргументи командного рядка, 544 00:44:58,040 --> 00:45:05,240 яка полягає в перевірці чи наші агдс значення те, що ми очікували. 545 00:45:05,240 --> 00:45:10,290 У цьому випадку, ми очікуємо, принаймні, два аргументи, 546 00:45:10,290 --> 00:45:13,660 Назва програми плюс одна іншу. 547 00:45:13,660 --> 00:45:17,140 Тому що ми збираємося використовувати другий аргумент прямо тут. 548 00:45:17,140 --> 00:45:21,350 Таким чином, за якийсь тест заздалегідь, до нашого STRCMP виклику 549 00:45:21,350 --> 00:45:37,390 що тести, чи дійсно ARGV по крайней мере 2, буде робити те ж саме роду речі. 550 00:45:37,390 --> 00:45:40,620 Ми бачимо, що працює, запустивши програму знову. 551 00:45:40,620 --> 00:45:45,610 Ви завжди можете перезавантажити програму в GDB, який дійсно хороший. 552 00:45:45,610 --> 00:45:49,310 Ви можете запустити, і коли ви проходите в якості аргументів вашої програми, 553 00:45:49,310 --> 00:45:53,060 Ви передаєте їх, коли ви подзвоните працювати, а не при завантаженні GDB. 554 00:45:53,060 --> 00:45:57,120 Таким чином, ви можете зберегти виклику програми з різними аргументами кожен раз. 555 00:45:57,120 --> 00:46:08,080 Так біжіть, або знову ж таки, я можу Type R, і давайте подивимося, що станеться, якщо набрати "привіт". 556 00:46:08,080 --> 00:46:11,140 Він завжди буде питати вас, якщо ви хочете, щоб почати з самого початку ще раз. 557 00:46:11,140 --> 00:46:17,490 Як правило, ви хочете, щоб почати з самого початку ще раз. 558 00:46:17,490 --> 00:46:25,010 І в цей момент, вона запускає його знову, він друкує 559 00:46:25,010 --> 00:46:28,920 Програма, яку ми біжимо, buggy1 з аргументом привіт, 560 00:46:28,920 --> 00:46:32,720 і це виводить з цього стандарту, він говорить: "Ви отримуєте D," сумне обличчя. 561 00:46:32,720 --> 00:46:37,610 Але ми не сегментам вина. Він сказав, що процес завершився нормально. 562 00:46:37,610 --> 00:46:39,900 Так що виглядає досить добре. 563 00:46:39,900 --> 00:46:43,050 Немає більше сегменті вина, ми зробили це минуле, 564 00:46:43,050 --> 00:46:48,190 так що схоже, що це дійсно помилка сегменті вина, що ми отримували. 565 00:46:48,190 --> 00:46:51,540 На жаль, це говорить нам, що ми отримуємо D. 566 00:46:51,540 --> 00:46:54,090 >> Ми можемо повернутися назад і подивитися на вихідний код і подивитися, що там відбувається 567 00:46:54,090 --> 00:46:57,980 щоб з'ясувати, що було - чому воно було говорити нам, що ми отримали D. 568 00:46:57,980 --> 00:47:03,690 Давайте подивимося, от це було Printf кажуть, що ви отримали D. 569 00:47:03,690 --> 00:47:08,540 Якщо ми введемо список, як ви тримаєте введення списку, він тримає ітерації вниз через вашу програму, 570 00:47:08,540 --> 00:47:10,940 так що покажу Вам декілька перших рядків програми. 571 00:47:10,940 --> 00:47:15,450 Тоді покажу вам кілька рядків, а на наступний шматок і наступний шматок. 572 00:47:15,450 --> 00:47:18,240 І він буде намагатися йти вниз. 573 00:47:18,240 --> 00:47:21,180 А тепер ми повернемося до "лінії номер 16 знаходиться поза діапазону". 574 00:47:21,180 --> 00:47:23,940 Тому що він має тільки 15 ліній. 575 00:47:23,940 --> 00:47:30,310 Якщо ви дійшли до цієї точки, і ваші ставите питанням: "Що робити?" Ви можете використовувати команду допомоги. 576 00:47:30,310 --> 00:47:34,340 Використовуйте допомогу, а потім дати йому ім'я команди. 577 00:47:34,340 --> 00:47:36,460 І ви бачите, GDB дає нам всі такого роду речі. 578 00:47:36,460 --> 00:47:43,870 Він говорить: "Без аргументів, перераховує десять рядків після або у всьому попередньому лістингу. 579 00:47:43,870 --> 00:47:47,920 List - список десяти рядків раніше - " 580 00:47:47,920 --> 00:47:52,960 Так давайте спробуємо використовувати список мінус. 581 00:47:52,960 --> 00:47:57,000 І в якому перераховані 10 рядків попередньої, ви можете пограти зі списком небагато. 582 00:47:57,000 --> 00:48:02,330 Ви можете зробити список, список - ви можете навіть дати перерахувати ряд, як і список 8, 583 00:48:02,330 --> 00:48:07,500 і вона буде перерахувати 10 ліній навколо лінії 8. 584 00:48:07,500 --> 00:48:10,290 І ви можете бачити, що відбувається тут, у вас є простий, якщо інше. 585 00:48:10,290 --> 00:48:13,980 Якщо ви наберете в CS50 скелі, він друкує "Ви отримуєте А." 586 00:48:13,980 --> 00:48:16,530 В іншому випадку вона виводить "Ви отримуєте D." 587 00:48:16,530 --> 00:48:23,770 Ледар міста. Добре. Так? 588 00:48:23,770 --> 00:48:26,730 >> [Даниїл] Тому, коли я намагався робити CS50 порід без лапок, 589 00:48:26,730 --> 00:48:29,290 він говорить: "Ви отримуєте D." 590 00:48:29,290 --> 00:48:32,560 Я потребував в лапки, щоб змусити його працювати, чому це? 591 00:48:32,560 --> 00:48:38,490 >> Да. Виявляється, що коли - це ще одна кумедна ласий шматочок - 592 00:48:38,490 --> 00:48:47,900 При запуску програми, якщо ми запустимо його, і ми ввести CS50 порід, 593 00:48:47,900 --> 00:48:50,800 так само, як Данило говорив він зробив, і ви натиснете Enter, 594 00:48:50,800 --> 00:48:52,870 він як і раніше говорить, що ми отримаємо D. 595 00:48:52,870 --> 00:48:55,580 І питання в тому, чому це відбувається? 596 00:48:55,580 --> 00:49:02,120 І виявляється, що обидва наших терміналів і GDB розібрати їх як два окремих аргументів. 597 00:49:02,120 --> 00:49:04,800 Тому що, коли є простір, який має на увазі як 598 00:49:04,800 --> 00:49:08,730 Перший аргумент закінчився, а на наступний аргумент ось-ось почнеться. 599 00:49:08,730 --> 00:49:13,260 Спосіб поєднати ці дві, чи вибачте, в один аргумент, 600 00:49:13,260 --> 00:49:18,510 є використання лапок. 601 00:49:18,510 --> 00:49:29,560 Так що тепер, якщо покласти його в лапки і запустити його знову, ми отримаємо A. 602 00:49:29,560 --> 00:49:38,780 Так просто, щоб резюмувати, без лапок, CS50 і гірських порід обробляються як два окремих аргументів. 603 00:49:38,780 --> 00:49:45,320 З лапками, він обробляється як один аргумент в цілому. 604 00:49:45,320 --> 00:49:53,070 >> Ми бачимо це з точки зупину. 605 00:49:53,070 --> 00:49:54,920 До цих пір ми були працює наша програма, і вона працює вже 606 00:49:54,920 --> 00:49:58,230 до тих пір поки або він сегментам несправності або помилки хіти 607 00:49:58,230 --> 00:50:05,930 або поки він не завершиться, і все було в повному порядку. 608 00:50:05,930 --> 00:50:08,360 Це не обов'язково найкорисніша річ, тому що іноді 609 00:50:08,360 --> 00:50:11,840 у вас є помилки в вашій програмі, але це не викликає помилку сегментації. 610 00:50:11,840 --> 00:50:16,950 Це не викликає вашу програму, щоб зупинити або що-небудь подібне. 611 00:50:16,950 --> 00:50:20,730 Спосіб отримати GDB, щоб призупинити програму в конкретній точці 612 00:50:20,730 --> 00:50:23,260 , Щоб встановити точки зупину. 613 00:50:23,260 --> 00:50:26,520 Ви можете зробити це, встановивши точку зупину на ім'я функції 614 00:50:26,520 --> 00:50:30,770 або ви можете встановити точки зупину на певний рядок коду. 615 00:50:30,770 --> 00:50:34,450 Я хотів би встановити точки зупину на функцію імен, тому що - легко запам'ятати, 616 00:50:34,450 --> 00:50:37,700 і якщо ви насправді піти і змінити свій вихідний код вгору небагато, 617 00:50:37,700 --> 00:50:42,020 то ваша точка останову буде фактично залишатися на тому ж місці в коді. 618 00:50:42,020 --> 00:50:44,760 Беручи до уваги, якщо ви використовуєте номера рядка і номера рядка зміниться 619 00:50:44,760 --> 00:50:51,740 тому що ви додати або видалити частину коду, то ваші точки зупину все повністю облажався. 620 00:50:51,740 --> 00:50:58,590 Один з найпоширеніших речей, які я зробити, це встановити точки зупину на основні функції. 621 00:50:58,590 --> 00:51:05,300 Часто я буду завантажувати GDB, я типу В головній, ударив Enter, і що буде встановити точки зупину 622 00:51:05,300 --> 00:51:10,630 на головною функцією якого просто говорить: "Пауза програми, як тільки ви починаєте бігати" 623 00:51:10,630 --> 00:51:17,960 і, таким чином, коли я запускаю мою програму, скажімо, CS50 порід як два аргументи 624 00:51:17,960 --> 00:51:24,830 і натиснути Enter, він потрапляє в основні функції і зупиняється прямо на самій першій лінії, 625 00:51:24,830 --> 00:51:30,620 Право, перш ніж він оцінює STRCMP функції. 626 00:51:30,620 --> 00:51:34,940 >> Так як я зупинився, тепер я можу почати відведенням навколо і побачивши, що відбувається 627 00:51:34,940 --> 00:51:40,250 з усіма різних змінних, які передаються в моїй програмі. 628 00:51:40,250 --> 00:51:43,670 Тут я можу роздрукувати ARGC і подивитися, що відбувається. 629 00:51:43,670 --> 00:51:50,030 Дивіться, що агдс 3, тому що він отримав 3 різні значення в ньому. 630 00:51:50,030 --> 00:51:54,060 Він отримав назву програми, він отримав перший аргумент, а другий аргумент. 631 00:51:54,060 --> 00:52:09,330 Ми можемо надрукувати ті з дивлячись на ARGV [0], ARGV [1], і ARGV [2]. 632 00:52:09,330 --> 00:52:12,030 Так що тепер ви можете зрозуміти, чому цей виклик STRCMP збирається потерпіти невдачу, 633 00:52:12,030 --> 00:52:21,650 тому що ви бачите, що він розділений CS50 і скелі на дві окремі аргументи. 634 00:52:21,650 --> 00:52:27,250 На даний момент, як тільки ви потрапили останову, ви можете продовжити послідовне виконання програми 635 00:52:27,250 --> 00:52:32,920 рядок за рядком, на відміну від запуску програми знову. 636 00:52:32,920 --> 00:52:35,520 Так що, якщо ви не хочете, щоб запустити програму знову і просто продовжувати звідси, 637 00:52:35,520 --> 00:52:41,970 Ви можете використовувати команду тривають і як і раніше буде виконувати програму до кінця. 638 00:52:41,970 --> 00:52:45,010 Так само, як це зробив тут. 639 00:52:45,010 --> 00:52:54,880 Однак, якщо я перезапустити програму, CS50 скелі, він потрапляє моєї точки останову знову, 640 00:52:54,880 --> 00:52:59,670 і на цей раз, якщо я не хочу, щоб просто пройти весь шлях через іншу частину програми, 641 00:52:59,670 --> 00:53:08,040 Я можу використовувати наступну команду, яку я також скорочення з п. 642 00:53:08,040 --> 00:53:12,960 І це буде крок у рамках програми рядок за рядком. 643 00:53:12,960 --> 00:53:17,530 Таким чином, ви можете спостерігати, як речі виконувати, як змінні зміни, як речі оновлюється. 644 00:53:17,530 --> 00:53:21,550 І це дуже приємно. 645 00:53:21,550 --> 00:53:26,570 Інші Відмінна річ, а не повторювати ту ж команду знову і знову, і знову, 646 00:53:26,570 --> 00:53:30,670 якщо ви просто натисніть Enter - так що тут ви бачите, що я не набрав ні в чому - 647 00:53:30,670 --> 00:53:33,780 якщо я просто натисніть Enter, він буде повторювати попередню команду, 648 00:53:33,780 --> 00:53:36,900 або попередньої команди GDB, що я просто вставив 649 00:53:36,900 --> 00:53:56,000 Я можу тримати удар, і саме буду тримати покрокового свій код рядок за рядком. 650 00:53:56,000 --> 00:53:59,310 Я хотів би закликати вас, хлопці, щоб піти перевірити інші програми баггі, а також. 651 00:53:59,310 --> 00:54:01,330 У нас немає часу, щоб пройти через всі з них сьогодні в розділі. 652 00:54:01,330 --> 00:54:05,890 Вихідний код є, так що ви можете почасти бачити, що відбувається на 653 00:54:05,890 --> 00:54:07,730 за кулісами, якщо Ви дійсно застрягли, 654 00:54:07,730 --> 00:54:11,940 але, принаймні, тільки практика завантаженні GDB, 655 00:54:11,940 --> 00:54:13,940 виконання програми поки не зламається на вас, 656 00:54:13,940 --> 00:54:18,260 отримання зворотного трасування, з'ясувати, які функції обвал стався в, 657 00:54:18,260 --> 00:54:24,450 якій лінії він був, виводячи деяких значень змінних, 658 00:54:24,450 --> 00:54:30,140 тільки так ви відчуєте це, тому що дійсно допоможе вам в майбутньому. 659 00:54:30,140 --> 00:54:36,340 На даний момент, ми збираємося вийти з GDB, якій ви використанням кинути або просто ц. 660 00:54:36,340 --> 00:54:40,460 Якщо ваша програма знаходиться в середині працює досі, і вона не вийшла, 661 00:54:40,460 --> 00:54:43,510 він завжди запитає вас: «Ви впевнені, що справді хочете вийти?" 662 00:54:43,510 --> 00:54:48,770 Ви можете просто натиснути да. 663 00:54:48,770 --> 00:54:55,250 >> Тепер ми будемо дивитися на наступна проблема у нас є, що кішка програми. 664 00:54:55,250 --> 00:54:59,880 Якщо ви подивитеся на короткий перенаправлення і труби, ви побачите, що Томмі використовує цю програму 665 00:54:59,880 --> 00:55:07,540 , Що в основному друкує всі вихідні файлу на екран. 666 00:55:07,540 --> 00:55:12,660 Так що, якщо я біжу кішка, це насправді вбудованої програми в прилад, 667 00:55:12,660 --> 00:55:16,860 і якщо у вас є Macs ви можете зробити це на вашому Mac теж, якщо ви відкриваєте термінал. 668 00:55:16,860 --> 00:55:25,630 А ми - кішки, скажімо, cp.c, і натисніть Enter. 669 00:55:25,630 --> 00:55:29,640 Те, що це зробили, якби ми прокручування вгору трохи і подивитися, де ми провели лінію, 670 00:55:29,640 --> 00:55:40,440 або там, де ми запустили кішку команду, він буквально роздрукувати вміст cp.c на нашому екрані. 671 00:55:40,440 --> 00:55:44,140 Ми можемо запустити його знову, і ви можете покласти в декількох файлах. 672 00:55:44,140 --> 00:55:49,880 Таким чином, ви можете зробити кішці cp.c, і тоді ми можемо також об'єднувати cat.c файл, 673 00:55:49,880 --> 00:55:53,250 яка є програма, яку ми збираємося писати, 674 00:55:53,250 --> 00:55:58,140 і він буде друкувати як файли назад, щоб повернутися в наш екран. 675 00:55:58,140 --> 00:56:05,490 Тому, якщо ми прокручування вгору небагато, ми бачимо, що коли ми запустили цей кіт cp.c, cat.c, 676 00:56:05,490 --> 00:56:17,110 Спочатку він розпечатав ф файл, а потім під ним, він розпечатав cat.c файл прямо тут. 677 00:56:17,110 --> 00:56:19,650 Ми збираємося використовувати це, щоб просто отримати наші ноги мокрі. 678 00:56:19,650 --> 00:56:25,930 Пограйте з простої друку на термінал, подивимося, як це працює. 679 00:56:25,930 --> 00:56:39,170 Якщо ви, хлопці відкривають з Gedit cat.c, натисніть Enter, 680 00:56:39,170 --> 00:56:43,760 Ви можете побачити програми, які ми збираємося писати. 681 00:56:43,760 --> 00:56:48,980 Ми включили це хороша плита котла, тому ми не доведеться витрачати час на введення все це. 682 00:56:48,980 --> 00:56:52,310 Ми також перевіряємо кількість аргументів, переданих дюйма 683 00:56:52,310 --> 00:56:56,910 Ми роздрукувати гарне сполучення використанні. 684 00:56:56,910 --> 00:57:00,950 >> Це така штука, що, знову ж, як ми вже говорили, 685 00:57:00,950 --> 00:57:04,490 це майже як м'язова пам'ять. 686 00:57:04,490 --> 00:57:07,190 Тільки не забудьте зберегти робити те ж саме роду речі 687 00:57:07,190 --> 00:57:11,310 і завжди роздруківку свого роду корисними повідомлення 688 00:57:11,310 --> 00:57:17,670 так, що люди знають, як управляти вашої програми. 689 00:57:17,670 --> 00:57:21,630 З кішкою, це досить просто, ми просто збираємося пройти через всі різні аргументи 690 00:57:21,630 --> 00:57:24,300 , Які були передані нашої програми, і ми збираємося для друку 691 00:57:24,300 --> 00:57:29,950 їх вміст, щоб на екрані по одному. 692 00:57:29,950 --> 00:57:35,670 Для того, щоб друкувати файли з до екрану, ми збираємося зробити щось дуже схоже 693 00:57:35,670 --> 00:57:38,120 до того, що ми зробили в кінці вікторини. 694 00:57:38,120 --> 00:57:45,350 В кінці вікторини, які наймають програми, ми повинні були відкрити файл, 695 00:57:45,350 --> 00:57:48,490 і тоді ми повинні були друкувати на ньому. 696 00:57:48,490 --> 00:57:54,660 У цьому випадку, ми збираємося відкрити файл, і ми будемо читати з нього замість цього. 697 00:57:54,660 --> 00:58:00,630 Тоді ми йдемо до друку, а не в файл, ми збираємося друкувати на екрані. 698 00:58:00,630 --> 00:58:05,830 Таким чином, друк на екрані ви все робили з Printf. 699 00:58:05,830 --> 00:58:08,290 Так що це не надто божевільним. 700 00:58:08,290 --> 00:58:12,190 Але читання файлів дивно. 701 00:58:12,190 --> 00:58:17,300 Ми будемо пройти через це трохи за один раз. 702 00:58:17,300 --> 00:58:20,560 Якщо ви, хлопці повернутися до цієї останньої проблеми на вашій вікторини, завдання 33, 703 00:58:20,560 --> 00:58:27,280 перша лінія, що ми збираємося тут робити, відкриття файлу, дуже схожі на те, що ми там робили. 704 00:58:27,280 --> 00:58:36,370 Таким чином, Стелла, що робить цю лінію виглядати, коли ми відкриваємо файл? 705 00:58:36,370 --> 00:58:47,510 [Stella] Столиця FILE *, файл - >> Добре. >> - Рівно Еореп. >> Да. 706 00:58:47,510 --> 00:58:55,980 Які в цьому випадку? Це в коментарі. 707 00:58:55,980 --> 00:59:06,930 >> Це в коментарях? ARGV [я] і г? 708 00:59:06,930 --> 00:59:11,300 >> Саме так. Прямо на. Так Stella абсолютно праві. 709 00:59:11,300 --> 00:59:13,720 Це те, що лінія виглядає. 710 00:59:13,720 --> 00:59:19,670 Ми збираємося, щоб отримати змінний потік файлу, зберегти його у файлі *, так що всі кришки, 711 00:59:19,670 --> 00:59:25,720 FILE *, і ім'я цієї змінної буде файл. 712 00:59:25,720 --> 00:59:32,250 Ми могли б назвати це все, що ми хотіли. Ми могли б назвати це first_file, або file_i, що б ми хотіли. 713 00:59:32,250 --> 00:59:37,590 І тоді ім'я файлу був прийнятий в командному рядку цієї програми. 714 00:59:37,590 --> 00:59:44,450 Таким чином, він зберігається в ARGV [я], і потім ми збираємося відкрити цей файл в режимі читання. 715 00:59:44,450 --> 00:59:48,100 Тепер, коли ми відкрили файл, що те, що ми завжди повинні пам'ятати, щоб зробити 716 00:59:48,100 --> 00:59:52,230 всякий раз, коли ми відкрили файл? Закрийте її. 717 00:59:52,230 --> 00:59:57,220 Таким чином, Міссі, як ми закрити файл? 718 00:59:57,220 --> 01:00:01,020 [Missy] Fclose (файл) >> Fclose (файл). Саме так. 719 01:00:01,020 --> 01:00:05,340 Великий. Добре. Якщо ми подивимося на це, щоб зробити коментар прямо тут, 720 01:00:05,340 --> 01:00:11,940 він говорить, "Відкриті ARGV [я] і роздрукувати його вміст на стандартний вивід". 721 01:00:11,940 --> 01:00:15,460 >> Стандартний вихід це дивне ім'я. Stdout це просто спосіб сказати нашим 722 01:00:15,460 --> 01:00:22,880 Ми хочемо, щоб роздрукувати його на термінал, ми хочемо, щоб роздрукувати його в стандартний вихідний потік. 723 01:00:22,880 --> 01:00:26,450 Ми можемо насправді позбутися від цього коментаря прямо тут. 724 01:00:26,450 --> 01:00:36,480 Я збираюся скопіювати його і вставити його, так як це те, що ми і зробили. 725 01:00:36,480 --> 01:00:41,290 На даний момент, тепер у нас є, щоб прочитати файл по шматочках. 726 01:00:41,290 --> 01:00:46,300 Ми обговорили кілька способів читання файлів. 727 01:00:46,300 --> 01:00:51,830 Які ваші улюблені досі? 728 01:00:51,830 --> 01:00:57,960 Які способи ви бачили або ви пам'ятаєте, для читання файлів? 729 01:00:57,960 --> 01:01:04,870 [Даниїл] FREAD? >> FREAD? Так FREAD один. Джиммі, ви знаєте, будь-які інші? 730 01:01:04,870 --> 01:01:12,150 [Джиммі] Немає >> Добре. Ні. Шарлотта? Олександр? Будь-які інші? Добре. 731 01:01:12,150 --> 01:01:20,740 Таким чином, інші є fgetc, це той, який ми будемо використовувати багато. 732 01:01:20,740 --> 01:01:26,410 Там також fscanf, ви, хлопці, бачити зразок тут? 733 01:01:26,410 --> 01:01:29,170 Всі вони починаються з F. Все, що робити з файлом. 734 01:01:29,170 --> 01:01:35,260 Там в FREAD, fgetc, fscanf. Ці всі функції читання. 735 01:01:35,260 --> 01:01:49,120 Для розміщення у нас є FWRITE, у нас є fputc замість fgetc. 736 01:01:49,120 --> 01:01:58,250 Ми також Fprintf, як ми бачили на вікторину. 737 01:01:58,250 --> 01:02:01,680 Так як це є проблемою, яка включає в себе читання з файлу, 738 01:02:01,680 --> 01:02:04,940 Ми збираємося використовувати одну з цих трьох функцій. 739 01:02:04,940 --> 01:02:10,890 Ми не збираємося використовувати ці функції тут. 740 01:02:10,890 --> 01:02:14,880 Всі ці функції в стандартній бібліотеці введення / виводу. 741 01:02:14,880 --> 01:02:17,510 Так що, якщо ви подивитеся на верхню частину цієї програми, 742 01:02:17,510 --> 01:02:24,110 Ви можете бачити, що ми вже включений файл заголовка для стандартної бібліотеки вводу / виводу. 743 01:02:24,110 --> 01:02:27,120 Якщо ми хочемо, щоб з'ясувати, який ми хочемо використовувати, 744 01:02:27,120 --> 01:02:29,690 ми завжди можемо відкривати людині сторінок. 745 01:02:29,690 --> 01:02:34,350 Таким чином, ми може ввести людину STDIO 746 01:02:34,350 --> 01:02:43,180 і прочитати все про STDIO вхідний і вихідний функції в C. 747 01:02:43,180 --> 01:02:49,870 І ми вже бачимо, ой, дивися. Це згадка fgetc, це згадка fputc. 748 01:02:49,870 --> 01:02:57,220 Таким чином, ви можете розгорнути трохи і подивимося на, скажімо, fgetc 749 01:02:57,220 --> 01:03:00,060 і подивіться на його сторінці. 750 01:03:00,060 --> 01:03:03,430 Ви можете бачити, що він йде разом з цілою купою інших функцій: 751 01:03:03,430 --> 01:03:12,640 fgetc, ЕдеЬз, ЕОКП, GetChar отримує, UNGETC, і його введення символів і рядків. 752 01:03:12,640 --> 01:03:19,180 Так що це, як ми читаємо в символи і рядки з файлів зі стандартного вводу, 753 01:03:19,180 --> 01:03:21,990 яка є по суті від користувача. 754 01:03:21,990 --> 01:03:24,780 І це, як ми це робимо в реальному C. 755 01:03:24,780 --> 01:03:30,850 Так що це не використання GetString і GetChar функцій 756 01:03:30,850 --> 01:03:36,840 , Які ми використовували з CS50 бібліотеки. 757 01:03:36,840 --> 01:03:39,710 Ми збираємося зробити цю проблему декількома способами 758 01:03:39,710 --> 01:03:43,430 так що ви можете побачити два різні способи зробити це. 759 01:03:43,430 --> 01:03:48,490 І FREAD функції, що Данило згадується і fgetc хороші способи зробити це. 760 01:03:48,490 --> 01:03:53,790 Я думаю, що fgetc трохи легше, тому що це тільки має, як бачите, 761 01:03:53,790 --> 01:03:59,660 один аргумент, FILE *, що ми намагаємося прочитати символ з, 762 01:03:59,660 --> 01:04:02,740 і її значення, що повертається Int. 763 01:04:02,740 --> 01:04:05,610 І це трохи дивно, чи не так? 764 01:04:05,610 --> 01:04:11,450 >> Тому що ми отримуємо характер, так чому б не це повернення символів? 765 01:04:11,450 --> 01:04:18,700 Ви, хлопці, є які-небудь ідеї про те, чому це не може повернути символ? 766 01:04:18,700 --> 01:04:25,510 [Missy відповіді, нерозбірливо] >> Да. Так Missy абсолютно праві. 767 01:04:25,510 --> 01:04:31,570 Якщо це ASCII, то це число може бути зіставлений з фактичними символ. 768 01:04:31,570 --> 01:04:33,520 Може бути ASCII символів, і це правильно. 769 01:04:33,520 --> 01:04:36,220 Це саме те, що відбувається. 770 01:04:36,220 --> 01:04:39,190 Ми використовуємо Int просто тому, що він має більше бітів. 771 01:04:39,190 --> 01:04:44,750 Це більше, ніж символ, наш символ має тільки 8 біт, що 1 байт на наш 32-бітних машин. 772 01:04:44,750 --> 01:04:48,520 І Int має варто все 4 байти "простір. 773 01:04:48,520 --> 01:04:50,940 І виявляється, що шлях fgetc працює, 774 01:04:50,940 --> 01:04:53,940 якщо прокрутити вниз в нашу резюме в цій людині сторінці небагато, 775 01:04:53,940 --> 01:05:05,000 Прокрутіть вниз до упору. Виявляється, що вони використовують це спеціальне значення, зване EOF. 776 01:05:05,000 --> 01:05:09,640 Це спеціальна постійна, значення, що повертається функцією fgetc 777 01:05:09,640 --> 01:05:14,570 всякий раз, коли ви потрапили в кінець файлу або якщо ви отримуєте повідомлення про помилку. 778 01:05:14,570 --> 01:05:18,170 І виявляється, що для виконання цих порівнянь з EOF належним чином, 779 01:05:18,170 --> 01:05:24,060 Ви хочете, що додатковий обсяг інформації, яку ви маєте на Int 780 01:05:24,060 --> 01:05:28,420 в порівнянні з використанням символів змінної. 781 01:05:28,420 --> 01:05:32,130 Навіть якщо fgetc ефективно отримувати персонаж з файлу, 782 01:05:32,130 --> 01:05:38,450 Ви хочете, щоб пам'ятати, що вона повертається щось таке, що типу Int до вас. 783 01:05:38,450 --> 01:05:41,360 Тим не менш, він досить простий у використанні. 784 01:05:41,360 --> 01:05:44,960 Це дасть нам характер, тому все, що ми повинні зробити, це продовжувати задавати файл, 785 01:05:44,960 --> 01:05:48,440 "Дайте мені наступний символ, дай мені наступний символ, дай мені наступну характер», 786 01:05:48,440 --> 01:05:51,400 поки ми не отримаємо до кінця файлу. 787 01:05:51,400 --> 01:05:54,730 І це буде тягнути в один символ за один раз з нашого файлу, 788 01:05:54,730 --> 01:05:56,250 і тоді ми можемо робити все, що ми хотіли з нею. 789 01:05:56,250 --> 01:06:00,160 Ми можемо зберегти його, ми можемо додати його в рядок, ми можемо роздрукувати його. 790 01:06:00,160 --> 01:06:04,630 Виконайте одну з цього. 791 01:06:04,630 --> 01:06:09,600 >> Збільшення назад і повернутися до наших cat.c програми, 792 01:06:09,600 --> 01:06:16,170 якщо ми збираємося використовувати fgetc, 793 01:06:16,170 --> 01:06:21,710 як ми могли б підійти до цієї наступного рядка коду? 794 01:06:21,710 --> 01:06:26,020 Ми збираємося використовувати - FREAD буде робити щось трохи відрізняється. 795 01:06:26,020 --> 01:06:32,600 І на цей раз, ми просто збираємося використовувати fgetc, щоб отримати один символ за один раз. 796 01:06:32,600 --> 01:06:40,910 Щоб обробити весь файл, що ми могли б робити? 797 01:06:40,910 --> 01:06:44,030 Скільки персонажів є у файлі? 798 01:06:44,030 --> 01:06:47,390 Є багато. Таким чином, ви, ймовірно, хочете, щоб отримати один 799 01:06:47,390 --> 01:06:49,860 , А потім отримати іншу і отримати іншу і отримати іншу. 800 01:06:49,860 --> 01:06:53,330 Який алгоритм ви думаєте, ми могли б використати тут? 801 01:06:53,330 --> 01:06:55,470 Який тип - [Олександр] для циклу? >> Саме так. 802 01:06:55,470 --> 01:06:57,500 Деякі типи циклу. 803 01:06:57,500 --> 01:07:03,380 Цикл насправді великий, і в цьому випадку. 804 01:07:03,380 --> 01:07:08,620 І, як ви кажете, це звучить, як ви хочете петлю на весь файл, 805 01:07:08,620 --> 01:07:11,820 отримати символ за один раз. 806 01:07:11,820 --> 01:07:13,850 Будь-які пропозиції про те, як це може виглядати? 807 01:07:13,850 --> 01:07:22,090 [Олександра, нерозбірливо] 808 01:07:22,090 --> 01:07:30,050 >> Добре, тільки скажи мені, англійською мовою, що ви намагаєтеся зробити? [Олександра, нерозбірливо] 809 01:07:30,050 --> 01:07:36,270 Таким чином, в даному випадку, схоже, ми просто намагаємося петлю на весь файл. 810 01:07:36,270 --> 01:07:45,330 [Олександр] Так я <розмір Int? >> Розмір -? 811 01:07:45,330 --> 01:07:49,290 Я припускаю, що розмір файлу, вірно? Розмір - МИ просто написати це так. 812 01:07:49,290 --> 01:07:57,470 Розмір файлу в даний час, я + +. 813 01:07:57,470 --> 01:08:04,610 Ось і виходить, що те, як ви це за допомогою fgetc, і це нове, 814 01:08:04,610 --> 01:08:10,460 в тому, що не існує простий спосіб, щоб просто отримати розмір файлу 815 01:08:10,460 --> 01:08:16,979 з цим "SizeOf" типу побудуємо, що ви бачили раніше. 816 01:08:16,979 --> 01:08:20,910 Коли ми використовуємо цю функцію fgetc, ми представляємо якийсь 817 01:08:20,910 --> 01:08:29,069 новий, фанк синтаксис для цього циклу, де замість використання тільки основний лічильник 818 01:08:29,069 --> 01:08:33,920 піти по одному символу, ми збираємося вивести один символ за один раз, 819 01:08:33,920 --> 01:08:37,120 по одному символу за один раз, і то, як ми знаємо, що ми в кінці 820 01:08:37,120 --> 01:08:41,290 Не тоді, коли ми вважали певну кількість символів, 821 01:08:41,290 --> 01:08:49,939 Але коли ми характері витягнути те, що спеціальна символ кінця файлу. 822 01:08:49,939 --> 01:08:58,689 Таким чином, ми можемо зробити це, - я називаю це гол, і ми збираємося його ініціалізації 823 01:08:58,689 --> 01:09:08,050 наш перший виклик, щоб отримати перший символ з файлу. 824 01:09:08,050 --> 01:09:14,979 Таким чином, ця частина прямо тут, це буде отримати символ з файлу 825 01:09:14,979 --> 01:09:20,840 і зберігати його в змінної гл. 826 01:09:20,840 --> 01:09:25,420 Ми збираємося продовжувати робити це, поки ми дійдемо до кінця файлу, 827 01:09:25,420 --> 01:09:41,170 що ми і робимо, тестуючи для персонажа не рівні, що спеціальний символ EOF. 828 01:09:41,170 --> 01:09:48,750 І тоді замість того, щоб робити CH + +, яка б просто збільшити значення, 829 01:09:48,750 --> 01:09:52,710 тому, якщо ми читаємо з файлу, капітал, скажімо, 830 01:09:52,710 --> 01:09:56,810 CH + + дасть нам б, і тоді ми отримаємо С, а потім р. 831 01:09:56,810 --> 01:09:59,310 Це явно не те, що ми хочемо. Що ми хочемо тут 832 01:09:59,310 --> 01:10:05,830 У цьому останньому біт ми хочемо отримати наступний символ з файлу. 833 01:10:05,830 --> 01:10:09,500 >> Так як ми можемо отримати наступний символ з файлу? 834 01:10:09,500 --> 01:10:13,470 Як ми можемо отримати перший символ з файлу? 835 01:10:13,470 --> 01:10:17,200 [Студент] fgetfile? >> Fgetc, або, вибачте, ви мали цілковиту рацію. 836 01:10:17,200 --> 01:10:20,470 Я неправильно його прямо там. Так що так. 837 01:10:20,470 --> 01:10:26,240 Тут замість того, щоб робити CH + +, 838 01:10:26,240 --> 01:10:29,560 Ми просто будемо називати fgetc (файл) знову 839 01:10:29,560 --> 01:10:39,180 і зберегти результат в наших же змінної гл. 840 01:10:39,180 --> 01:10:43,730 [Студент питання, нерозбірливо] 841 01:10:43,730 --> 01:10:52,390 >> Це де ці хлопці FILE * є спеціальними. 842 01:10:52,390 --> 01:10:59,070 Те, як вони працюють, вони - при першому відкритті - коли ви спочатку переконайтеся, що Еореп виклику, 843 01:10:59,070 --> 01:11:04,260 FILE * ефективно служить в якості покажчика на початок файлу. 844 01:11:04,260 --> 01:11:12,830 І тоді кожен раз, коли ви дзвоните fgetc, вона рухається по одному символу за допомогою файлу. 845 01:11:12,830 --> 01:11:23,280 Тому, коли ви називаєте це, ви збільшуючи покажчик на один символ. 846 01:11:23,280 --> 01:11:26,210 І коли ви fgetc знову, ви рухаєтеся це інший персонаж 847 01:11:26,210 --> 01:11:28,910 і інший характер і інший характер і інший персонаж. 848 01:11:28,910 --> 01:11:32,030 [Студент питання, нерозбірливо] >> А that's - так. 849 01:11:32,030 --> 01:11:34,810 Це свого роду ця чарівна під капотом. 850 01:11:34,810 --> 01:11:37,930 Ви просто продовжуйте збільшуючи до кінця. 851 01:11:37,930 --> 01:11:46,510 На даний момент, ви зможете насправді працювати з характером. 852 01:11:46,510 --> 01:11:52,150 Отже, як ми могли б роздрукувати це на екрані, зараз? 853 01:11:52,150 --> 01:11:58,340 Ми можемо використовувати ті ж Printf річ, яку ми використовували раніше. 854 01:11:58,340 --> 01:12:00,330 Те, що ми вже використали весь семестр. 855 01:12:00,330 --> 01:12:05,450 Ми можемо назвати Printf, 856 01:12:05,450 --> 01:12:21,300 і ми можемо перейти в характері просто так. 857 01:12:21,300 --> 01:12:27,430 Ще один спосіб зробити це швидше, ніж при використанні Printf і мають для цього формату рядка, 858 01:12:27,430 --> 01:12:29,490 ми також можемо використовувати одну з інших функцій. 859 01:12:29,490 --> 01:12:40,090 Ми можемо використовувати fputc, яка виводить символ на екран, 860 01:12:40,090 --> 01:12:52,580 винятком випадків, коли ми дивимося на fputc - дозвольте мені масштаб небагато. 861 01:12:52,580 --> 01:12:56,430 Ми бачимо, що приємно, він приймає в характері, що ми читаємо, використовуючи fgetc, 862 01:12:56,430 --> 01:13:05,100 але тоді ми повинні дати йому потік в друк. 863 01:13:05,100 --> 01:13:11,850 Ми також можемо використовувати ріЬспаг функцію, яка наноситься безпосередньо на стандартний вивід. 864 01:13:11,850 --> 01:13:16,070 Таким чином, існує ціла купа різних варіантів, які ми можемо використовувати для друку. 865 01:13:16,070 --> 01:13:19,580 Вони всі в стандартній бібліотеці введення / виводу. 866 01:13:19,580 --> 01:13:25,150 Всякий раз, коли ви хочете надрукувати - так Printf, за замовчуванням, будуть друкуватися на спеціальній стандартні з потоку, 867 01:13:25,150 --> 01:13:27,910 яких є те, що стандартний вивід. 868 01:13:27,910 --> 01:13:41,300 Таким чином, ми можемо просто посилатися на нього як виду цієї магічне значення, стандартний висновок тут. 869 01:13:41,300 --> 01:13:48,410 Ой. Поставити крапку з комою зовні. 870 01:13:48,410 --> 01:13:52,790 >> Це багато нового, наляканий інформацією тут. 871 01:13:52,790 --> 01:13:58,600 Багато це дуже ідіоматичні, в тому сенсі, що це код 872 01:13:58,600 --> 01:14:05,700 що написано таким чином тільки тому, що це чисто читати, легко читається. 873 01:14:05,700 --> 01:14:11,520 Є багато різних способів зробити це, багато різних функцій, які ви можете використовувати, 874 01:14:11,520 --> 01:14:14,680 але ми, як правило, просто виконайте ці ж моделі знову і знову. 875 01:14:14,680 --> 01:14:20,180 Так що не дивуйтеся, якщо побачите такий код придумати знову і знову. 876 01:14:20,180 --> 01:14:25,690 Добре. На даний момент, ми повинні розірвати протягом дня. 877 01:14:25,690 --> 01:14:31,300 Спасибі, що прийшли. Дякую за перегляд, якщо ви знаходитеся в мережі. І ми побачимося наступного тижня. 878 01:14:31,300 --> 01:14:33,890 [CS50.TV]