[Powered by Google Translate] [Тиждень 4, продовження]
[David J. Малан - Гарвардський університет]
[Це CS50. - CS50.TV]
>> Це CS50, і це в кінці тижня 4.
Таким чином, деякі гарні новини і погані новини.
Ні лекції в понеділок, не проблема встановити на наступному тижні. [Оплески студентів]
Ви не сподобається, де це відбувається.
Але у нас є це, а в наступну середу,
і є також в програмі 1 лекція п'ятницю в наступну п'ятницю, так що ми можемо залишитися на трасі.
Але все буде знятий, як зазвичай, так що не турбуйтеся.
>> І в зв'язку з вікторину 0 Що ми будемо робити ближче до кінця тижня
буде розміщувати на домашній сторінці cs50.net курсу пояснень
, Якого роду очікування ви повинні мати, коли справа доходить до першої вікторини.
Загалом, це буде множинний вибір, вірно-невірно, коротка відповідь, короткий кодування проблеми.
Ви не будете чекати для реалізації еквівалентних
проблеми, які ви бачите на PSET, для яких у вас є комп'ютер
і відладчик і тому подібне, але там буде невелика кодування проблеми.
>> І дійсно, краще керівництво, щоб отримати уявлення про те, що CS50 вікторини, як
це зайти на cs50.net, перейдіть на посилання вікторини,
і ви можете побачити останні декілька років стоїть вікторини.
Просто розумію, що навчальні програми не завжди було незмінним протягом багатьох років.
Іноді ми додамо, іноді віднімати,
тому якщо ви бачите якусь тему на одному з тих старих вікторини
що ви поняття не маєте, що це говорить про те, що це або те, що ми не покрити її
або що ми не покриває його.
Але у вигляді відгуків, в це неділю, понеділок і вівторок
а також хід всієї сесії з проведення огляду в ніч на неділю -
Час і місце будуть оголошені на домашній сторінці курсу -
Ви все маєте можливість ознайомитися з викладанням курсу стипендіати
Матеріал у цьому році, як і в розділі якості повноправного класу,
, І вони будуть зняті, як зазвичай, а також.
>> Добре. Отже, без подальших церемоній, в одному з коментарів на залік / незалік і введення / виводу.
Можливо, ви бачили мої замітки минулої ночі, і це дійсно просто деякі додаткові запевнення
що якщо ви належите до числа тих, хто особливо менш комфортно або десь посередині
і ви відчуваєте себе просто трохи більш ніж у вашій голові,
розуміють, що насправді цілком нормально, і є достатня структури підтримки на місці,
один з яких прийомні години були наміри щодо поліпшення тим більше за мою електронну пошту минулої ночі,
і розумію, що теж варіант, як годен / не придатний для класу, як це
насправді мається на увазі в якості механізму, зняти гостроту курсу, як це,
так що знову, якщо ви витрачаєте ті 10, 15, 20 годин
просто намагаюся отримати деякі PSET працювати і ви знаєте, що 90-95% від туди
але ви не можете знайти прокляту помилку, в залік / незалік модель, яка начебто нормально.
>> Ідея полягає в тому, що з цим механізмом ви можете піти уваги на інших psets
або спати або що це таке, що ви хочете, щоб зосередитися.
Так розумію, що у вас є, поки це найближчий вівторок - технічно 5-й понеділок,
але це свято, так що це найближчий вівторок - перейти від придатний / не придатний до градуйований або навпаки.
І якщо ви дійсно на краю прірви, і думає падіння в цілому,
Будь ласка, злови мене після лекції або напишіть мені записку.
Ми хотіли б, принаймні чату перед вами попрощатися.
Добре. Таким чином, ми почали приймати підготовки коліс в минулий раз.
Зокрема, ми звернули увагу на рядок.
Струнний є те, що оголошені в бібліотеці CS50,
зокрема в тому, що файл з ім'ям cs50.h яких ми почнемо дивитися на цей тиждень і наступний.
Але рядок насправді просто спрощення щось
, Що трохи більше arcanely описано як символ *.
Char, що ми знайомі. Це всього лише один символ.
Але * станом на понеділок позначається як? >> [Студент] покажчик.
Покажчика. І що покажчик? >> [Студент] адресу.
>> Це все одно, адреса, місце в пам'яті.
Що адресу або місце чи пам'ять?
Знову ж таки, у всіх нас є ноутбуки з концерту або 2 гігабайти оперативної пам'яті, швидше за все, в ці дні,
і це означає, що у вас є мільярд або 2 млрд. байт стоїть пам'яті.
І це дійсно не має значення, що це фізично виглядає,
але прийняти на віру, що ви можете порахувати всі окремі байти, що ваш власний ноутбук -
це байт 0, це 1 байт, це байт 2 млрд. -
і це саме те, що комп'ютер робить.
Коли ви виділити місце для одного символу, наприклад,
він, очевидно, повинен жити десь в пам'яті комп'ютера,
і може бути, це на номер 12345 байт,
і що десь тут, в пам'яті комп'ютера.
І адресу, то цього символу 12345.
>> Тепер, на тиждень від 0 до тепер досі, ми дійсно не дбали
, Де в пам'яті зберігаються речі, тому що ми зазвичай використовують символи,
Змінні та масиви насправді отримати на нашому даних.
Але, як в понеділок, а тим більше сьогодні, ви тепер будете мати
Тим більше виразні можливості при написанні програм
щоб дійсно управляти пам'яттю комп'ютера як ви вважаєте за потрібне,
як для благих цілей і погано,
помилки бути дуже загальний результат на даний момент у вивченні цього матеріалу.
Але що це насправді означає бути символ *?
Давайте підемо далі назад в - і ми повернемося до Бінки як і обіцяв сьогодні.
Підемо простим прикладом тут.
Дозвольте мені зберегти цей файл як compare.c, і дозвольте мені просто отримати код шаблону тут
тому включати stdio.h, дозвольте мені також віддати себе включати cs50.h. Я збільшити там.
Дозвольте мені почати писати основні INT, основних (недійсними), і тепер я хочу зробити щось на зразок цього:
Е ("Дайте мені рядки:"), а потім я буду використовувати рядки з одержує GetString
, Щоб отримати рядок від користувача, то я збираюся запитати користувача на інший.
("Дайте мені ще рядки:"), і я збираюся попросити їх через GetString, щоб отримати це.
Я буду називати його, тому що т т приходить після с і з це хороша назва для рядка, якщо це досить загальний характер.
Так GetString, і тепер я просто хочу зробити загальний контроль, і я збираюся сказати,
Якщо (S == т), то я просто хочу, щоб повідомити користувачеві Е ("Ви ввели те ж саме, \ п");
ще я хочу, щоб роздрукувати щось подібне ("Ви ввели щось інше! \ п")
або що вирок буде. Таким чином, щось на зразок цього.
Потім, як звичайно, я буду повертати 0, який просто означав, що нічого поганого не сталося,
і я збираюся йти вперед і скомпілювати і запустити цю програму.
>> Але в понеділок ми запустили цю програму,
і насправді було сказано, що ПРИВІТ НЕ Здрастуй і прощай не прощає.
Поведінка, яке ми бачили, було трохи більше, як це.
Відпустіть мене в мій вихідний каталог, збільшити тут, і давайте зробимо зробити порівняння.
Укладач порядку. Дозвольте мені виконати порівняння. Дайте мені рядки: Доброго.
Дайте мені інший рядок: Доброго.
Ви ввели щось інше!
Ну, давайте я спробую що-небудь простіше, як 50, 50. Ви ввели щось інше!
привіт, привіт. Таким чином, ясно, що щось тут відбувається.
Але яке ж було пояснення, чому?
Мабуть, лінія 12 повністю функціонує.
Яка основна проблема тут? Так. >> [Студент] Це порівняння адрес.
Так, саме так. Це насправді порівняння адрес
, В якому ПРИВІТ ПРИВІТ і зберігаються.
Це не порівняння букв ПРИВІТ знову і знову,
тому що те, що відбулося насправді, весь цей час ми використовували GetString -
Це дошці знову пам'яті нашого комп'ютера,
і скажемо, я називаю GetString після оголошення змінної с.
Що означає моя пам'ять схожа?
Давайте довільно сказати, що з виглядає наступним чином. Це квадрат.
І в значній мірі будь-який час я намалював шматок пам'яті на екрані
якщо це 32 біт, я був малюнок квадратів, як це, тому що дійсно в прилад,
покажчик, адреса, становить 32 біт. Це так само, як Int.
Це може варіюватися залежно від комп'ютерної системи.
Ті з вас, хто смутно знайомі з тим фактом, що ваш Mac або PC складає 64 біт,
що насправді означає, що ваш комп'ютер використовує 64-розрядні покажчики,
64-розрядні адреси, а серед розквитатися цього ваш комп'ютер
може мати набагато більше пам'яті, ніж минулого.
Коротше кажучи, ще в той день, коли комп'ютери використовуються тільки 32 біт
для представлення адрес, найбільша кількість байт ви могли б представляти
У цьому випадку було те, що якщо у вас є 32 біт?
Таким чином, 4 млрд, праві, тому що від 2 до 32, 4 мільярди доларів.
Це число було повторення в курсі.
>> Так що якщо у вас є тільки 32 біта, найбільше число ви можете розраховувати на приблизно 4 мільярди доларів.
Але це було фундаментальне обмеження комп'ютерів, поки кілька років тому
тому що якщо ви можете розраховувати тільки досягати 4 млрд.
це не має значення, якщо ви купуєте 8 гігабайт оперативної пам'яті або навіть 5 гігабайт оперативної пам'яті;
Ви не можете розраховувати, що високий, так що це було марно.
Ви можете отримати доступ тільки до перших 3 або 4 гігабайтами пам'яті комп'ютера.
Це менш важливою проблемою в даний час, і ви можете купити MacBook Pros і Dells
з 8 гігабайтами оперативної пам'яті або навіть більше в ці дні.
Але якщо я просто виділити в цій програмі покажчик, покажчик називається S,
це може виглядати це на екрані, тому що дійсно нам потрібно відігніть цей шар.
Я постійно говорю рядки, але за станом на понеділок, рядок дійсно символ *,
Адреса деякий характер.
Так що давайте вважати, що навчання колеса відключається, навіть якщо ми будемо продовжувати використовувати GetString на даний момент.
Так що я оголосив їй, і це частина пам'яті, 32 біт.
Що тут у пам'ять за замовчуванням? >> [Нерозбірливо відповідь студента]
Що це? >> [Студент] Garbage. >> Garbage. Саме так.
Якщо ви програміст не ставимо значення у змінній, хто знає, що це таке?
Іноді вам щастить, і це 0, яка є своєрідною хороший, чистий значення за замовчуванням,
але, як ми бачили понеділок, іноді це повна маячня,
деякі дійсно великі позитивні або негативні числа, які прийшли з де?
Так. >> [Студент] Функція раніше. >> Да.
>> Часто функції, які отримав колл раніше, тому що пам'ятаю,
як ви називаєте функції в пам'яті, вони займають все більше і більше простору знизу вгору,
і як тільки функція повертає, що пам'ять отримує повторно
на наступний хлопець, який викликається, хто використовує ваші ж шматок пам'яті.
І якщо ви залишили сміття там, попередні значення,
ми могли б переплутати з як має деяке значення, коли насправді ми не кладіть нічого немає.
Таким чином, наші оперативної пам'яті на даний момент виглядає наступним чином.
Тепер на правій стороні рядка 7 ми називаємо GetString,
які ми робимо зараз протягом тижнів, а то, що GetString насправді?
GetString написано CS50 персонал трохи інтелектуального
в тому, що, як тільки користувач починає вводити ключі і хітів Enter,
GetString цифри, скільки натискань клавіш зробив користувач хіт,
скільки символів я повинен виділити RAM для.
А де, що RAM приходить, хто знає?
Це десь в 2 комп'ютери гігабайт і ще багато чого з пам'яті.
Але давайте припустимо, що комп'ютер знайшов місце для слова ПРИВІТ прямо тут.
Я набрав слово було Н-Е-Л-Л-О.
І якщо ми проведемо це як послідовність символів, ми могли б зробити це так.
Але мені потрібно зробити 1 додаткову річ. Те, що належить в кінці будь рядки в C?
Нульовий символ, який ми пишемо, як \ 0.
Це технічно число 0, а зворотна коса риса робить все чітко
що це буквально число 0, ціле число 0;
це не так, наприклад, цитата-кінець цитати 0, що можна ввести з клавіатури.
Так що це HELLO.
>> І що ж ми говоримо в понеділок, що функції, як GetString
насправді повертаються всі ці тижні?
Це не повертаються рядки як такої, тому що насправді не мають сенс
Оскільки рядки не існує. Вони начебто виготовлення в CS50 бібліотеки.
Що насправді є рядком, більш технічно? >> [Студент] Це перший символ.
Саме так. Це досить просто адресу першого символу, який користувач ввів дюйма
Так що, якщо мої слова ПРИВІТ закінчує його в байт 123 номери, а потім з байта номер 124,
125, 126, і так далі, якщо я просто мій номер байта від 0 до о,
що насправді GetString повертається буквально номер 123.
Таким чином, те, що можна покласти в и це номер 123, а не буква H, не то слово HELLO,
просто адреса, за якою я можу знайти першу букву HELLO.
Але це не здається достатньо. Я запитав вас за рядком, а не характер.
Так як же нам або комп'ютер знаємо, що ELLO виду приходять разом з H?
Що роду угоди в нас є? Так.
[Студент] Він продовжує говорити сам знайти ще кілька символів. >> Саме так.
>> Там є людина-комп'ютер конвенції якій коли ви маєте справу з рядками,
інакше відомий тепер як символ зірки, ви просто повинні з'ясувати,
де в кінці кожного рядка в житті є насправді просто ітерації по його цикл,
час циклу, що завгодно, так що, коли ви знаходите кінці рядка
Тепер ви можете укласти з цього, ой, ціле слово було HELLO.
Ті з вас, з досвідом програмування може знати в Java
Ви можете просто подзвонити. Довжину і на інших мовах можна назвати довжину або аналогічний.
Це тому, що в багатьох мовах, зокрема, що називається об'єктно-орієнтованих мов,
Довжина щось подібне інкапсульовані всередині частини самих даних,
багато, як ми інкапсульовані ідентифікатори та імена і вдома всередині студента в понеділок.
Але C набагато більш низькому рівні. Є ніяких об'єктів або класів, якщо ви чули ці терміни раніше.
Все, що вам дійсно адрес пам'яті.
Так що це свого роду старомодним способом представлення цікавої структури даних.
У вас є початкове значення, як адресу першого символу
, А потім лише деякі довільні конвенції, що всі згодні з тим, щоб слідувати.
Отже, як довжина рядка реалізовані, не ми пропонуємо?
STRLEN, StrLen, що деякі з вас вже використали кілька разів. Це досить просто, чи не так?
Це як 2 рядки коду.
Це в значній мірі за цикл якийсь, може бути, з додатковою локальної змінної.
Але StrLen просто повинен взяти покажчик, а потім починають шукати \ 0.
>> І як тільки він знаходить його, він може повертати загальна кількість кроків, які він взяв у цьому рядку.
Таким чином, ми можемо укласти з цього, що відбувається далі.
Нехай тоді я заявляю, т як я зробив у рядку 10.
Це якась фігня значення. Хто знає, в першу чергу?
Але на правій стороні лінії 10 я дзвоню GetString знову.
Хто знає, де це закінчується?
Давайте як завгодно говорити про те, що операційна система знайшла місце для нього шляху сюди.
Я, трапляється, випадково типу Н-Е-Л-Л-О знову,
і таким чином, ми можемо зробити таку ж картину.
Але те, що у мене перемалювати цю картину навмисного
тому що це інший ПРИВІТ, ніж цей.
Так от, це може бути розташування 456, це 457, і так далі.
Таким чином, те, що можна поставити, де знак питання було раніше?
У цьому випадку 456.
Ми вибираючи ці цифри довільно, тому що насправді після того, як сьогодні
Ми не збираємося так турбуватися про те, що адреса нічого.
Все, що ми дбаємо про те, що ми можемо з'ясувати адресу деякої частини даних, як HELLO.
>> Так насправді те, що більшість людей в області комп'ютерної науки, коли йдеться про пам'ять адреси
і говорити про покажчиків зокрема,
, А не турбуватися з'ясовуючи 123 - кого це хвилює, де ці речі насправді,
ми просто знаємо, що це в деякій числовій адресу -
ми спрощуємо світ і просто сказати, що з указує на цього персонажа
і т вказує на цього персонажа.
А те, що це стрілка цілком навмисною
тому що буквально зараз з указує на H і T вказує на іншу H
тому що в кінці кінців, це не має значення, що адреса,
але це не справа, що у нас є можливість, щоб висловити, що адресу з деякими шматок коду.
Ми дійсно не маніпулював цими адресами тільки поки
так що подивимося, де ми можемо вставляти і як би робити речі з покажчиками,
але зараз в рядку 12 буквальному які цінності ми порівняно
відповідно з цією історією в рядку 12?
Ми говоримо, що становить 123 рівних рівними до 456? І це безумовно не той випадок.
І навіть концептуально, цей покажчик, безумовно, не так само, як це
тому що ви називали GetString двічі, і GetString не намагатися бути супер розумним,
вона не намагається зрозуміти, ой, ви набрали ПРИВІТ 5 хвилин назад;
Дозвольте мені дати вам той же покажчик, як я дав тобі раніше,
він просто виділяє новий блок пам'яті кожен раз, коли ви це називаєте.
>> Так як же нам вирішити цю проблему?
Якщо високому рівні я хочу порівняти рядки привіт і привіт -
Я не дбаю про покажчики - як я можу йти про відповідаючи на запитання,
ж користувач введіть те ж саме? Що тут необхідна? Так.
[Студент] Використовуйте функцію. >> Я можу використовувати функції з коробки.
Я можу використовувати функцію під назвою STRCMP, с-т-р-с-т-р,
тільки скорочену версію кажучи порівняння рядків.
І якщо ми йдемо в, наприклад, порівняти 2, який є одним з роздавальних матеріалів сьогоднішньому
Я роблю саме це.
Я тримав все інше те ж саме від лінії 1 на до 26 або близько того,
і тепер помічаю цю частину змінилася лише трохи.
Давайте ігнорувати лінії 28 на мить і зосередитися тільки на цьому.
Що ми говоримо в понеділок, що, вул порівняння робить?
Він відповідає за процес прийняття 2 покажчиків, з і т в цьому випадку,
роду практично поклавши руку на ці 2 листи,
і що він повинен зробити щось подібне петлі під час або цикл,
і він говорить ці ж саме? Якщо це так, вона рухається пальців або покажчиків вперед.
Це ті ж, це те ж саме, це те ж саме,
це те ж саме, це те ж саме? І ох, я в кінці рядка на обох з і т.
Я не знайшов жодних протиріч. Так, ці рядки однакові.
А що значить вул порівняти повернення, якщо 2 рядки ті ж, мабуть? Zero.
Таким чином, 0 хороша в цьому випадку, тому що якщо він повертає -1 або +1,
це означає, що просто відбувається постати перед т в алфавітному порядку або після т.
І чому б, що б корисно мати функцію, яка говорить вам, які рядки передує
або після того, як в словнику?
[Студент] Пошук. >> Пошуку і сортування.
>> Так що ви можете робити речі, як двійковий пошук або бульбашкового сортування та сортування злиттям
де ви повинні порівняти речі.
До цих пір ми начебто скоротити деякі кути і говорили тільки про сортування
в контексті номера, тому що це легко і приємно поговорити,
але можна, звичайно, порівнювати рядки, яблуко і банан,
тому що, якщо яблуко, як відомо, приходять до банана, аналогічно,
Ви можете переміщатися по всьому рядків в пам'яті так само, як Роб зробив з сортування злиттям в відео
і ми зробили тут, на сцені з вибором сортування, сортування вставкою, і бульбашкового сортування.
Так де ж ще ми можемо прийняти це? Давайте спробуємо це.
Давайте роду забувати, що урок на хвилину і спробуйте зараз і скопіювати 1.c зробити наступне.
У рядку 21 Я те говорю, друку,
Потім я отримую рядок від користувача,
Потім я перевіряю це.
Ми ще не отримали в цій звичці немає, але давайте тепер зробити це.
Давайте насправді відігніть цей шар. Це дійсно символ *. Цей хлопець дійсно символ *.
Отже, що ж означає бути перевірка, якщо з == NULL?
Виявляється, що при виклику функції, як GetString
або взагалі просто запитати комп'ютера, щоб дати вам деяку кількість пам'яті,
щось може піти не так.
Ви могли б бути божевільним, і попросити комп'ютер на терабайт пам'яті
, Просячи трильйонів байт пам'яті, які просто не існують в комп'ютері,
але GetString та інші функції потрібно якимось чином кричати на вас
якщо ви просили занадто багато.
І те, як GetString робить це, якщо ви попросили більше пам'яті
, Чим є в комп'ютері, навіть якщо це супер, супер низької ймовірності
тому що ніхто з нас не збирається вводити трлн символів, а потім натисніть Enter,
але низька ймовірність хоча це може бути, я все ще хочу, щоб перевірити його на всякий випадок,
і спеціальне значення, яке GetString, відповідь, та інші функції повертається
якщо щось пішло не є NULL великими літерами.
>> А що таке NULL? NULL просто так трапляється являють собою покажчик. Це 0 адреса пам'яті.
Світ вирішив, що довільно, якщо це пам'ять мого комп'ютера - ви знаєте, що? -
ми збираємося, щоб вкрасти тільки 1 байт пам'яті кожного комп'ютера, і це положення 0.
Ми збираємося дати йому прізвисько NULL, і ми збираємося обіцяти
що ми ніколи не будуть ставити реальні дані є
тому що ми просто довільно потрібно спеціальне значення 0, інакше NULL,
так що ми можемо кричати на користувачів, якщо щось піде не так.
В іншому випадку ви можете не знати зовсім 0 означають, покласти щось тут
або це значить щось пішло не так?
Ми повинні всі погодитися, що NULL нічого засобів була повернута,
немає фактичної адреси були повернуті.
Тепер, ось, я просто прийнявши моє людське з'їзді я повертаюся 1 від основної
якщо щось піде не так.
Це тому, що повернення основної конвенції в тому, щоб повертати 0, якщо добре,
1 або інше значення, якщо погане.
Але GetString і будь-яка функція, яка займається в пам'ять повертає NULL, якщо щось іде погано.
>> Добре. Тому, на жаль, рядок 27, супер просто, хоча це, абсолютно не скопіювати рядок.
Чому? У цьому можна переконатися наступним чином.
Я стверджуючи, у рядку 27 слід зробити копію з і т називаючи його.
Так що я не прошу у користувача 2 рядки на цей раз, я просто кажу значення в и
повинен бути поміщений в т а.
Так що тепер просто щоб продемонструвати, як зламані це, у рядку 29 вперед те, що я роблю?
Перший я перевіряю, якщо довжина т більше, ніж 0.
Там якась рядок там. Користувач ввів щось дюйма
Що таке лінія 32 роблять, мабуть?
[Нерозбірливо відповідь студента] >> праві. Ви можете види вивести його з того, що я сказав, що це робить.
Але технічно, те, що це робить? T [0] представляє те, що?
[Студент] характер нульовий. >> [Малан] характер нульовий.
Або, що більш людського типу, перший символ в т, що б це, H, може бути, в цьому випадку.
І ToUpper робить те, що він говорить. Він капіталізує нульового символу т, і це міняє його.
Таким чином, це означає взяти на нульовому характером т, зробити її верхній регістр,
і поклав його назад в тому ж місці.
Так що, якщо я типу привіт в нижньому регістрі, це повинно змінити рядкові год до столиці H.
Але проблема в тому, що в рядках 35 та 36, що я збираюся зробити, це роздрукувати для нас з і т.
А що ваші здогадки?
Що я насправді відбувається, щоб побачити, якщо я набрав в привіт в нижньому регістрі?
Що буде надрукована? >> [Нерозбірливо відповідь студента] >> Що це таке?
[Студент] Big H, а інші маленькі. >> Великого H і інші невеликі, для яких, з або т?
[Студент], і інше. >> Інше. Саме так. Отже, давайте подивимося, що відбувається тут.
>> Дозвольте мені йти далі і зібрати це. Це copy1, так що copy1. Добре.
Збільшити масштаб Дозвольте мені йти вперед і працювати copy1, Enter Сказати що-небудь: привіт в нижньому регістрі.
Це капіталізуються копію, але він, очевидно, капіталізуються оригінальні, а також,
тому що те, що зараз відбувається в цій історії?
У рядку 27 я насправді не здається, копіювання рядка,
але навіть якщо ви, можливо, інтуїтивно сподівалася, що буде так,
якщо ви думаєте про цю картину, що насправді я зробив?
Половина картина та ж.
Так що давайте відкат у часі, так що т ще не існує в історії.
S може існувати в історії, але давайте нижній привіт в цей раз.
Отже, дозвольте мені виправити те, що я насправді ввели дюйма
У цьому випадку тут ми маємо ч-е-л-л-о.
Ми будемо малювати його як послідовність символів, поклав розділові лінії тут, і моя \ 0.
Так що це, де ми знаходимося, як тільки лінія від 1 до 24-іш, плюс-мінус, виконали.
Це фотографія моєї пам'яті.
Коли я добираюся до лінії 27, що відбувається?
Як і раніше, я отримую покажчик, який я намалюю, як цю площу.
Це називається тонн. І те, що його значення за замовчуванням? Хто знає? Деякі сміття значення.
>> Так що я буду абстрактним, що далеко, як знак питання.
І як тільки праву сторону лінії 27 виконує, що я покласти всередину т?
Те ж саме, що знаходиться в с.
Тому, якщо ми на мить видалити цю абстракцію, вказаному стрілкою, і ми говоримо,
О, це пам'ять адресу завантаження 123, коли ви говорите т отримує з, крапка з комою,
Ви буквально покласти 123 тут.
Тепер, якщо ми якось спростити наш світ знову з фотографіями,
те, що ви дійсно зробили просто додається ще одну стрілу в свій світ
який вказує с т в точно такий же рядок.
Тому, коли в рядку 31 і 32 я насправді йти про зміну т [0]
що T [0] мабуть синонімом зараз? з [0]
Так що все, що відбувається.
І хоча цей вид почуває себе трохи низькому рівні і таємні
і такого роду почуття, що, можливо, інтуїтивно це повинно було б просто працював -
Я зробив копії раніше, і він просто працював -
якщо ви насправді думаєте про те, що рядок насправді, це символ *.
Ну, що це таке? Це адресу деяких характеру.
Тоді, можливо, має сенс, коли ви намагаєтеся зробити щось
Супер здавалося б, простий, як це, все, що ви робите, копіювання адреси пам'яті.
Ви насправді не роблять нічого з самої рядки.
Так що навіть якщо ви поняття не маєте, як би ви вирішити цю проблему в коді,
високому рівні, концептуально, що ми повинні зробити для того, щоб та справжня копія з, мабуть?
Так. >> [Студент] дати йому нове місце? >> Саме так.
>> Ми повинні дати т новому місці.
Нам потрібно якимось чином створити світ, в якому ми отримуємо новий шматок пам'яті,
які просто для ясності я буду малювати прямо під цим, але це не повинні бути там.
Але вона повинна бути того ж розміру, так що я буду малювати ці вертикальні лінії в тому ж місці.
Це нормально, якщо це все фігня на початковому етапі. Хто знає, що там було?
Але крок 1 буде потрібно, дайте мені стільки пам'яті, скільки мені потрібно
, Щоб відповідати копію привіт, а потім з'ясувати, як скопіювати ч тут, електронну тут,
л Тут і так далі.
Але це вже повинні відчувати себе трохи очевидна, навіть якщо деякі деталі все ще абстрактно.
Щоб скопіювати цей рядок у цьому, це просто цикл або час циклу
або те, з чим ви стали все більш знайомим.
Так давайте спробуємо це. Відпустіть мене в copy2.c.
У copy2.c ми маємо майже ту ж програму, за винятком лінії 27.
Це виглядає трохи складним, але якщо ми розбити його по частинах,
ліва сторона те ж саме.
Char * т створює цю річ в пам'яті, хоча і зі знаком питання
тому що ми поняття не маємо, що там за замовчуванням.
З правого боку ми тепер введення нової функції, Танос,
на пам'ять виділити, дай мені пам'яті,
і він, очевидно, бере, скільки аргументів, скільки речей у дужках?
Я почув ремствування 1 і 2, але це всього лише 1.
Там немає коми, яка означає, що є тільки 1 річ у круглих дужках.
Хоча є інші дужки, дозвольте мені підкреслити
те, що всередині самої зовнішньої дужки, і саме цей вираз:
(StrLen (и) + 1) * SizeOf (Char).
Таким чином, якщо ми насправді думаю, що це до кінця, це говорить мені довжини с.
Чому я, правда, додавши 1 на довжині? >> [Нерозбірливо відповідь студента]
Саме так. Нам потрібно місце для цього хлопця в хвіст, шостий символ, який не має сенсу англійською
але є спеціальні програмні сенс.
>> Так що нам потрібно + 1 за це, тому StrLen повертає людину очікування довжини,
привіт чи 5, це не дає вам додаткові нульового символу.
Так що я вручну додати це з + 1.
І тоді це, * розмір (символ), ми не бачили цього раніше.
Це технічно не є функцією.
Це спеціальне ключове слово, яке просто говорить вам, що розмір деяких типів даних на комп'ютері
тому що насправді, деякі з нас мають 32-розрядних комп'ютерах.
У мене досить старий комп'ютер вдома, і він використовує тільки 32 біта для подання покажчиків.
І тому, якщо я зробив розмір типу даних, це може бути 32 біт.
Але якщо я використовую мій новий модний комп'ютер, я міг би повернути значення 64 біт
щось на зразок адреси.
Таким чином, в цьому випадку, просто, щоб бути супер безпечно, ми не збираємося на жорсткому щось подібне коду -
Ну, що розмір символів в залежності від того, що ми говорили досі?
Ми в значній мірі сказав усно, що це 1 байт, і, що дуже багато щирих через борт.
Але, знову ж, припущення, як правило, погано.
Вони призводять до помилки в програмному забезпеченні, якщо люди використовують програмне забезпечення таким чином, ви не маєте наміру.
Так що давайте це абстрактне, і прямо говорити в більш загальному
Мені це потрібно багато ділянок пам'яті
і кожен шматок пам'яті повинна бути еквівалентна розміру характеру,
який насправді дорівнює 1 в цьому випадку, але це більш загальний спосіб написання.
Таким чином, якщо слово привіт, скільки байт робить Танос мабуть виділити на що-небудь?
[Студент] Six. >> Шість. Рівно стільки, скільки ми маємо знаки питання на екрані.
А потім зробити припущення тепер заснована на ваше розуміння GetString
Що ж Танос, ймовірно, повернуться? >> [Студент] адресу.
Адреса який? З першого блоку пам'яті.
>> Ми поняття не маємо, що там, тому що деякі інші функції
можна було б за допомогою цієї пам'яті раніше.
Але Танос, як GetString повертає адреса першого байта пам'яті
що він виділив для вас.
Однак те, що воно не зробити, це заповнити цю прогалину з нульового символу зворотної косої межі
тому що виявляється, можна використовувати Танос виділити все що завгодно: цілі, рядки, масиви,
поплавці, студент структур.
Ви можете використовувати Танос повністю в загальних рисах.
Він не піклується чи повинні знати, що ви виділення пам'яті для.
Тому було б самовпевнено Танос поставити \ 0
В кінці кожного блоку пам'яті це дає вам
тому що це \ 0 річ просто конвенцію для рядків.
Це не для цілих чисел, він не використовується для поплавців, він не використовується для студентів.
І так Гоча з Танос в тому, що тягар повністю на вас програміст
згадати, скільки байтів виділяються і не коли-небудь використовувати для циклу
або петлю, і пройти повз кордону блоку пам'яті ви отримали.
Іншими словами, як тільки ви виділити пам'ять,
Ви не можете запитати операційної системи, ой, до речі, наскільки великий шматок пам'яті це було?
Це повністю залежить від вас, щоб пам'ятати, якщо ви маєте потребу в цьому цінність.
>> Отже, давайте подивимося, як я приступити до використання цієї пам'яті.
У рядку 28 і 29, чому я це роблю?
Тільки спільна перевірка осудності.
Тільки у випадку, якщо щось пішло не так, я прошу якийсь божевільний обсяг пам'яті
або я так багато працює на комп'ютері, що там просто не вистачає пам'яті,
щось на зразок цього, я принаймні хочете перевірити на NULL.
У дійсності, більшість комп'ютерів дасть вам ілюзію, що всі програми
Можна використовувати сукупність оперативної пам'яті,
але навіть у цьому випадку, якщо користувач вводить деякі божевільні довгий рядок, може бути, тому, що вони поганого хлопця
і вони насправді намагаються привести до збою програми чи зламати його,
Ви хочете, щоб принаймні перевірити повернене значення Танос і чи буде вона дорівнює нулю.
І якщо це так, давайте просто кинути прямо зараз, тому що я не знаю, що робити в цьому випадку.
Як скопіювати рядок? Там є кілька способів зробити це.
Є вул скопіювати функції в C, але це супер просто для нас, щоб зробити це старомодним способом.
>> Перш за все дозвольте мені з'ясувати, що довжина и їсти.
Я міг би зробити це в циклі, але замість цього я просто поклав його тут для ясності.
Таким чином, п тепер зберігає довжину вихідної рядки, мабуть, 5.
Тоді в моїй циклу я ітерації від 0о до п,
і на кожній ітерації я ставлю з [я] всередині т [I].
Так ось що я мав на увазі з моїми 2-ма пальцями, вказуючи на рядків до.
Як це цикл ітерації, як це, я збираюся бути копіювання ч в тут,
е в тут, я тут, тому що в цей с, це т.
І тоді, нарешті, в рядку 35, чому я це роблю?
Мені потрібно, щоб переконатися, що я в кінцевому рядок тонн.
І я зробив це таким чином, щоб бути супер явним.
Але пропоную, хтось, якщо б ви могли, різних способів зробити це.
Я дійсно не потрібна рядок 35. Там ще один спосіб зробити це.
Так. >> [Нерозбірливо відповідь студента] >> Скажи це голосніше.
[Студент] менше або дорівнює. >> Саме так.
Ми могли б просто сказати, менше або дорівнює N, яка в цілому була поганою
тому що майже завжди, коли ми йдемо в рівній речі ми розраховуємо
ми йдемо 1 крок занадто далеко.
Але пам'ятаєте, скільки байтів Чи ми виділити?
Ми виділили з StrLen с, тому 5 + 1 на загальну суму 6.
Так що в цьому випадку ми могли б зробити щось на зразок цього
так що ми копіювання не тільки привіт, але й \ 0 в самому кінці.
Крім того, ми могли б використовувати функцію вул копія, зЬгсру,
але це не було б майже так само весело.
Але це все, що він робить під капотом.
Тоді, нарешті, ми робимо те ж саме, що і раніше.
Я капіталізувати т, а потім я стверджую, що оригінальна виглядає наступним чином і копія виглядає так.
Так давайте спробуємо це зараз. Відпусти мене тут. Зробити copy2. Ми будемо збільшувати і запустити copy2.
Я збираюся ввести привіт в нижньому регістрі, та й я отримую нижній привіт, як оригінал
але капітал Привіт для копіювання.
Але я не зробив тільки поки. Мені потрібно зробити 1 остання річ тут.
46 і 47 чітко звільняючи оперативну пам'ять, але що це насправді означає?
Що я роблю, як ти думаєш, зателефонувавши за телефоном лінії 46 і лінії 47?
Які наслідки це має? Так.
[Нерозбірливо відповідь студента] >> Саме так.
>> Ви просто говорите операційної системи, привіт, дякую за цю пам'ять.
Тепер ви можете використовувати його для когось ще.
А ось прекрасний приклад сміття значення.
Я тільки що використовував цю пам'ять, щоб записати слово привіт в 2 місцях,
тут, тут, тут, і тут.
Таким чином, це ч-е-л-л-о-\ 0.
Але тоді я називаю лінією 46 і лінією 47, і ви знаєте, що там відбувається, з точки зору картина?
Насправді, почекайте, ця картина старого.
Як тільки ми зробити копію, цей хлопець насправді вказує тут,
так що давайте видалити цифри і просто абстрагуватися від, як наші стрілки знову.
Що відбувається в цій картині, коли я дзвоню безкоштовно?
[Нерозбірливо відповідь студента] >> Не парними.
Якщо я зателефоную безкоштовно на с і т - свого роду питання з підступом - це картина не змінюється на всіх
тому, що виклик і виклик з т просто говорить операційній системі,
агов, ви можете використовувати цю пам'ять знову, але це не змінює цього до нуля
або спеціальними символами, це не змінити,
це не змінює год або електронною або л або л або виведення в будь-якому місці ні з чим.
З точки зору картину, як тільки Ви телефонуєте безкоштовно, нічого не змінюється.
І в цьому полягає походження сміття значення, тому що якщо я потім у цій програмі
запитаєте операційної системи для додаткової пам'яті з GetString або Танос або щось на зразок того
і операційна система говорить, звичайно, у мене є 12 байт пам'яті тільки звільнили,
використовувати їх, що ви збираєтеся бути передані?
Ви збираєтеся бути передана частина пам'яті, що ми зазвичай використовують
з питальними знаками, але те, що ці знаки питання?
Вони, виявляється, ч-е-л-л-о, ч-е-л-л-о.
Це наші нові значення сміттям, як тільки ви звільнити цю пам'ять.
>> Там в реальному світі імплікації тут.
Це відбувається, робити з оперативною пам'яттю, але ваші комп'ютери
насправді зробити те ж саме з диска.
Ми поговоримо про це, зокрема, з майбутнім поставленої задачі, яка фокусується на судової експертизи.
Але те, що відбувається насправді якщо у вас є деякі чутливі фінансові файл на робочому столі
або деякі уривчасті JPEG, і ви перетягнете його в сміття,
що відбувається, коли ви перетягнете його в сміттєве відро або кошик?
Ви знали, що я говорю. [Сміх]
Що відбувається, коли ви витягли, що докази у кошики або відро для сміття?
[Нерозбірливо відповідь студента]
Ну, так що обережніше. Що відбувається, коли ви це робите?
Коротка відповідь: нічого, вірно?
Ескізні або чутливої ​​файл як і раніше просто сидів там десь на вашому жорсткому диску.
Більшість з нас хоча б навчилися на гіркому досвіді, що вам потрібно, щоб очистити ваше сміття
або кошики насправді видалення файлів.
І справді, коли ви клацніть правою кнопкою миші або клацніть на управління вашим відро для сміття
або виберіть Файл, Empty Trash або будь-який інший
і ви насправді очистити сміттєвий кошик або кошики, що насправді відбувається, то в цій картині?
Більше нічого. Отже нічого насправді відбувається на диску.
>> І якщо ми просто тимчасово відволіктися і писати - I'll просто використовувати задню цього.
Так що тепер історія змінюється від RAM, який є, де існують програми
в той час як ви працюєте них, на диску, який є, де вони зберігаються довгострокові
навіть тоді, коли влада йде, на даний момент - і ми повернемося до цього в майбутньому -
давайте просто робити вигляд, що це являє собою жорсткий диск всередині комп'ютера
тому що ще в той день вони звикли бути круглими дисками, так само, як дискети.
Так що якщо у вас є деякі чутливі файлів Excel, він може взяти на себе цю частину пам'яті
на диску вашого комп'ютера, і я просто малювання ж довільного 1 і 0.
Коли ви перетягнете файл так, щоб ваше відро для сміття або кошики,
буквально нічого не відбувається тому, що компанії Apple і Microsoft тільки що вирішили
відро для сміття і кошики насправді це просто тимчасові рамки.
Може бути, врешті-решт ОС буде очистити його для вас, але, як правило, він нічого не робить,
по крайней мере, до тих пір поки ви дійсно мало місця.
>> Тим не менше, коли ви йдете в порожні сміття або порожні кошики,
Аналогічно, нічого не відбувається в цій картині.
Все, що відбувається в іншому місці на вашому комп'ютері, є свого роду таблиці.
Це ніби як маленька шпаргалка, яка говорить, що, скажімо, resume.doc,
так що ваше резюме у файл Microsoft Word жили на місці 123 на жорсткому диску,
не в пам'яті, а не в пам'яті, а на жорсткому диску,
і вашим уривчастих життя JPEG на 456, і ваш файл Excel живе на 789 або де завгодно.
Коли ви видаляєте файли насправді спорожнення кошика чи кошика,
ця картина не змінюється. 0 і 1 на жорсткому диску нікуди не ходжу.
Але ця таблиця, ця маленька база даних сортів, змінюється.
При видаленні вашого резюме, це як якби файл видаляється, в деякому розумінні,
але комп'ютер не буде забувати, де ця штука живе на вашому жорсткому диску.
0 і 1, які складають ваше резюме або будь-який з цих інших файлів залишаються недоторканими.
>> Так що якщо ви зробили це випадково, ще є ненульова ймовірність
що ви можете відновити дані за допомогою Нортон Утиліти та деякі комерційні програми
чиї цілі в житті, щоб знайти 0 і 1, які начебто сироти,
забули тут, але залишив тут, так що ви можете отримати ваші дані назад.
Або судових слідчих поліції або ФБР буде насправді взяти жорсткий диск
а насправді шукати зразки з 0 і 1, які виглядають як JPEG, виглядають як файли Excel,
і відновити їх таким чином, навіть якщо комп'ютер забула їх там.
Тому єдиний спосіб дійсно видалити дані, як ми будемо обговорювати в майбутньому,
це, щоб вичистити або стерти файл або жорсткий диск -
Ви не можете реально позбутися від 0 і 1
тому що інакше ви б почати з гігабайтний жорсткий диск
і ви в кінцевому підсумку з мегабайта жорсткого диска, якщо ви постійно були видалення,
буквально, 0 і 1.
Отже, що б ви зробили, якби ви дійсно хотіли, щоб замести сліди
і основною проблемою є те, що ще є 0 і 1 на диску?
Я бачу, хтось жестикулюючи, що ви фізично зламати пристрій. Це буде працювати.
[Сміється] Але якщо це свого роду дороге рішення, що було б більш розумним?
Так. >> [Студент] переписати їх. >> Перезаписати їх чи що? >> [Студент] Інші дані.
Інші дані. Ви можете просто перезаписати диск з 0s і 1s або всі 0s, все 1s.
>> І це дійсно те, що деякі програми робить.
Ви можете купити програмне забезпечення або навіть отримати безкоштовне програмне забезпечення,
і навіть вбудовану в Mac OS в ці дні, в меншій мірі в Windows,
є здатність надійно стирати.
Насправді, якщо ви хочете, щоб всі біжать додому сьогодні, якщо у вас є Mac і зробити це,
якщо у вас є деякі речі у вашій відро для сміття, ви можете зробити Безпека Empty Trash,
який робить саме це.
Замість того щоб просто стерти файли тут, вона не стирає 0 і 1 тут,
скоріше, він просто змінює їх, наприклад, на 0 і точка, точка, точка.
Тому однією з ваших майбутніх psets насправді буде навмисно відновлення даних -
фотографії, які ми взяли людей, місць і речей на території кампуса
, Для якого ми будемо робити судово зображення карти пам'яті цифрової камери,
який є точно такий же ідеєю - і ви будете мати, щоб бути оскаржені насправді знайти
моделей, які являють собою зображення у форматі JPEG на жорсткий диск,
так само, як, що колишній студент, лист, який я прочитав кілька тижнів тому зробив
відновити фотографії своєї сестри.
Чому б нам не взяти 5-хвилинну перерву тут, і ми перегрупуватися більш на пам'ять.
Так ось де все стає трохи галюциногенний, але це дуже потужний крок
до розуміння цього все більше.
Ось програма під назвою pointers.c.
Він є одним із зразків коду сьогодні.
Зверніть увагу, що в перші кілька рядків, з 19 по 22, все, що ми робимо щось подібне GetString
і повернення адреси, зберігання в с.
Надалі для PSET навіть 3, якщо ви хочете, але PSET 4 і на
де ви можете почати приймати ці навчальні коліс від себе,
немає ніяких причин робити вигляд, що рядки існує.
Це, звичайно, добре, щоб просто почати говорити символ *.
>> Як осторонь, в онлайн-довідниках і книгах ви можете часто бачити на зірочку поряд із змінною.
Ви навіть можете бачити простір навколо обидві сторони від нього.
Всі ці функціонально правильно.
Зараз, однак, ми будемо стандартизувати цей підхід, щоб зробити Super Clear
, Що символ *, як кажуть покажчик на символ.
Це тип даних.
А потім ім'я змінної з в цьому випадку.
Таким чином, ми отримали рядок, і ми назвали її з.
А потім сюди, помітили, що я роблю насправді трохи хитрості.
Це називається арифметика покажчиків, яка є свого роду супер просто.
Це просто означає, складати і віднімати номери покажчиків.
Але це насправді працює.
Ця програма мабуть друкує 1 символ рядка з на лінію таким чином, що кінцевий результат -
Точно так само ми можемо зіпсувати, де це відбувається, зробити покажчики, покажчики працювати, дозвольте мені змінити масштаб зображення
Тепер дозвольте мені типу в щось на зразок привіт і тип Enter
і він друкує 1 символу в рядку.
До секунду назад, ми б зробили це з квадратними позначення кронштейна.
Ми б цикл, і ми будемо робити Printf з [я], і ми будемо робити це знову і знову і знову
з зворотною косою рисою п в кінці кожного рядка.
Але ця програма відрізняється. Ця програма використовується, в буквальному сенсі, арифметика.
Так що ж тут відбувається?
Перш за все, до цього цикл виконує навіть те, що, просто щоб бути ясно, є насправді?
S є? >> [Студент] адресу. >> Адреса.
>> І це адреса, в випадку здрастуй, перший символ в тому, що слово, яке годину.
Так що з Тобто, у даному конкретному прикладі, адреса годину.
Так що ж це значить зробити з + я?
Ну, я починається з 0 в цьому цикл. Ми робили це багато разів.
Я маю намір йти до довжини рядка, мабуть.
Таким чином, на першій ітерації цього циклу, я, очевидно, 0.
Таким чином, цей вислів говорив з + я - скоріше, з +0--це, очевидно, тільки з.
Так що ж таке * з тут?
Зараз ми використовуємо зірка в дещо інший шлях.
Дозвольте мені йти вперед і позбутися від т, тому що ми зробили говоримо про т і копії з.
Зараз ми просто хочемо, щоб розповісти історію за участю с.
І ось в цей момент, після того, як тип рядка, наш світ виглядає зовсім як це було раніше
всього із зберіганням адресу год і в більш загальному вказуючи на рядок привіт.
Якщо я зараз роблю такий рядок * (S + I), давайте спробуємо це.
Так * (S + I). Дозвольте мені спростити це, тому що це 0, так що це * (S +0).
Ну, почекай хвилинку. Спрощення далі. Це * (с).
Ну, а тепер дужках є свого роду дурним, так що тепер давайте просто робити * с.
Таким чином, у першій ітерації цього циклу, що лінія яка підкреслила, 26,
в значній мірі еквівалентно друку цьому.
Що таке тип даних * з?
У цьому контексті, бо зірка опиниться поряд з себе,
але більш конкретно, тому що ми більше не оголосивши їй,
Ми не створюємо змінну більше, немає жодної згадки символ * в рядку 26,
немає жодної згадки ключового слова рядки, ми просто за допомогою змінної с,
Виявляється тепер зірка має дещо інший і, треба визнати, плутаючи сенс.
* И тут означає перейти за адресою в с і друку все, що є.
Таким чином, з тут, * S є - ніби як жолоби і драбини, слідуйте за стрілкою - тут.
Так що це * с.
>> Так що ж отримує надрукований на першій ітерації цього циклу в рядку 26?
Я роздрукувати% C, який є прототипом для символу,
Потім \ п для нового рядка. * (S + I), де я = 0 є саме це.
Так що символ потрібно помістити в% для C? H.
У наступній ітерації циклу - можна, ймовірно, побачити, де це відбувається -
Наступна ітерація я, очевидно, 1, так що це означає з +1,
і тепер мені потрібно дужки, тому що тепер зірка повинна сказати
перейдіть за адресою пам'яті з +1.
Що таке S? Давайте повернутися в минуле і сказати, що це стрілка зараз насправді не роблять нам ніяких позичені.
Давайте більш конкретно сказати, що це зберіганні номер 123
тому що на початку цього рядка Здравствуйте, це адреса 123, це 124, і так далі.
Таким чином, на другій ітерації, коли я говорю з +1, це, як кажуть 123 +1,
інакше відома як 124, так що символ отримує надрукований на другий ітерації?
E на адресу пам'яті, 124.
Потім знову +, 125, 126, 127, і ця петля на щастя зупиняється, перш ніж ми отримаємо тут
тому що я використовую StrLen щоб переконатися, що я не вважає занадто високою.
Так що це теж його.
Знову ж таки, це як якби ми зробили тиждень тому.
Дозвольте мені написати його на рядок нижче, хоча ми не хочемо, щоб зробити обидва.
Це ідентично тепер до цього.
>> Тому, навіть якщо з собою рядок, як ми називаємо його на тижні, а насправді символ *.
Тому якщо ми хочемо, щоб бути супер анал, це дійсно правильний написати специфіка
на р-м місці за допомогою цих числових адрес і ця зірка оператора,
але, чесно кажучи, це просто так набагато чистіше. Таким чином, це не погано.
Немає причин, щоб перестати робити лінію 27 тут, але 26 є функціонально те ж саме,
і це функціонально той же рівно причин того, що ми обговорювали до сих пір.
І, нарешті, 29 просто хороша практика.
Виклик безкоштовно з означає, що тепер ви даєте задній пам'яті, яка дала вам GetString
тому що знову, як я вже говорив понеділок, GetString тижні
впроваджує помилка в коді.
Ваш код тижнів була витік пам'яті
яких ви запитували GetString для пам'яті, але ви ніколи не давав його назад.
І це була свідомо обрана нами педагогічно
тому що це просто занадто багато, щоб думати про початок.
Але тепер нам потрібно більше симетрії.
Якщо ви запитаєте комп'ютер для пам'яті, як і у випадку з GetString,
як і у випадку мабуть Танос,
Ви повинні тепер PSET 4 і в подальших також безкоштовно будь такої пам'яті.
Зауважте, що це відрізняється від того, Int N.
Вам не потрібно, щоб звільнити це тому, що ви не дзвоните GetString
і ви не дзвоните Танос.
>> І навіть якщо ви називали GetInt, як ми бачимо в остаточному підсумку,
GetInt не виділити пам'ять для вас, тому що ви можете обійти цілих чисел
і плаває і букви так, як ми робили протягом тижня.
Струни, однак, є особливими, тому що насправді вони конкатенації декількох символів.
Таким чином, вони просто відрізняються від символів і поплавці й цілими тощо.
Але ми повернемося до цього незабаром.
Будь-які питання, то на цьому початку покажчики? Так.
[Нерозбірливо запитання студента]
Ах, дуже хороше запитання.
Одна з небагатьох речей, C насправді робить для вас, що зручно,
воно з'ясовує, для вас те, що розмір типу даних
, А потім робить такий множення для вас.
Це не має ніякого значення в разі символів, тому що майже завжди символ займає 1 байт,
так що це просто працює.
Але заради обговорення, якщо б ви були насправді друкувати цілі
і ви намагалися роздрукувати деякі значення с, що вказувало на ціле число,
Вам також не потрібно буде робити + 4 * я тільки тому, що Int становить 4 байти.
Арифметика з покажчиками означає, що C і компілятор робити все, що математика для вас.
Все, що ви повинні піклуватися про те, підрахунок роду в людському сенсі. Так.
[Студент] Якщо ви оголошуєте рядки всередині циклу, ви повинні звільнити його пізніше?
Хороше питання.
>> Якщо ви оголосили рядки всередині циклу, ви повинні звільнити його пізніше?
Вам потрібно всього лише вільною пам'яттю, що ви виділяєте з GetString або з Танос.
Так що якщо ви тільки що сказали щось на кшталт - дозвольте мені фігурні дужки тепер так весь код пов'язані між собою.
Якщо ви зробили щось, хоча buggily, як ця, символ * T = S,
Вам не потрібно, щоб безкоштовно т т тому, що не пов'язане з яким-небудь згадкою Танос або GetString.
Якщо, навпаки, ви зробили це, GetString, то так, вам потрібно буде безкоштовним тонн.
І справді, ваш єдиний шанс зробити це зараз всередині цієї петлі, з того ж питання за рамки
, Які ми обговорювали в минулому.
В іншому випадку ви будете виділення пам'яті, виділення пам'яті, виділення пам'яті,
і в кінці програми, тому що ви перебуваєте за межами цього циклу,
т не існує, але ви ніколи не говорили операційної системи
що вам не потрібно, що пам'ять більше.
І незабаром, до PSET 4 або 5 ми озброїти вас з програмою під назвою Valgrind,
які близькі за духом GDB в тому, що він отримав свого роду таємне інтерфейс,
але його мета в житті, щоб допомогти вам.
І Valgrind це програма, яка в майбутньому буде шукати ваші програми
шукати витоки пам'яті, чи то від GetString або Танос,
які ми почнемо, використовуючи все більше, як ми припинити використання CS50 бібліотеці стільки ж.
Ми, нарешті, тепер є свого роду словника і свого роду ментальної моделі в теорії
з яким для вирішення цієї зламаною програмі.
>> Так що в цьому зламаною програми, своп працює всередині підкачки,
але він ніколи не працював в основному тому, що основна пройшло в х і у, нагадаємо,
і ті були прийняті в цінностями, так би мовити.
Копії з них були дані поміняти.
До кінця підкачки, і б дійсно були обмінені,
але, звичайно, х і у, як ми обговорювали в понеділок, не було.
Тому я пропоную в зеленому тут, що це насправді рішення тут.
А насправді, дозвольте мені рухати зірки просто бути послідовним
хоча, знову ж таки, функціонально це не має значення.
У майбутньому тижнів ми будемо пояснювати, коли і чому це має значення.
Таким чином, в зеленому зараз є рішенням.
Чесно кажучи, це виглядає набагато брудніше, тому що у мене є всі ці зірки.
Дозвольте мені зазначити одну річ.
Верхній рядок тут, де він говорить Int * і Int * б
принципово робить те ж саме, як це було завжди.
Він заявляє, 2 аргументи або параметри поміняти,
першим з яких є Int покажчика називається,
другий з яких є Int покажчика називається б.
Єдине, що нового на даний момент є те, що там є зірки.
>> Що це значить? Чи не INT, б не є Int.
Це адреса Int і б це адреса іншого Int.
Тут, внизу, це де я визнаю C збиває з пантелику.
Зараз ми використовуємо зіркою, але він має різне значення в цьому контексті.
Тому що ми не оголошуємо покажчики, як ми тут,
Тут ми разименованія речі.
Таким чином, технічно, зірки в цьому контексті першої, другої і третьої лінії всередині своп
є оператором разименованія, який просто означає, що йти туди.
Так само, як мій палець пішов за стрілками годинника,
* Кошти йдуть на цю адресу і знайти мене Int, що є.
* В означає, перейти за адресою і передати мені, що там.
Так що давайте перемальовувати зображення з понеділка тепер використовується стек кадрів,
нижній, один з яких буде основним,
верхня, одна з яких буде своп,
так що наш світ виглядає, як понеділка, як це.
Ось шматок пам'яті, що основною збирається використовувати.
>> Нагадаємо, з понеділка, що програма просто було 2 змінних,
одна називається х і одна називається у, і я поклав числа 1 і 2.
Тепер, коли я називаю поміняти, як я зробив у понеділок,
Раніше, коли я використовував червону версію цієї програми, яка виглядає так,
Я отримав 2 параметри, а, б, і що ж ми пишемо тут і тут?
Тільки 1 і 2, буквально копіює х і у.
Сьогодні ми це змінити.
Сьогодні замість передачі в цілих а і б ми збираємося передати в 2-адрес.
Ці адреси трапитися, щоб вказати на цілі, але ці адреси не цілими себе.
Вони адрес. Це як поштова адреса.
Так що тепер нам потрібно просто дати собі трохи більш докладно на екрані.
Це моя пам'ять комп'ютера, як це було весь день.
Тепер нам потрібно довільної схеми нумерації.
Так що давайте просто скажемо, просто випадково, що це адреса пам'яті, 123, 124.
Давайте просто скажемо, що це 125, це 126, і так далі, але це абсолютно довільними.
Нам просто потрібно деякий схеми нумерації в моїй пам'яті.
Так що тепер, коли я насправді проходять в х і у, я не збираюся переходити в х і у;
Я збираюся перейти в поштову адресу, так би мовити, х і у
так що те, що отримує зберігається тут і тут не 1 і 2,
Але якщо ви можете побачити мої дрібний текст, те, що пройшло в тут і тут?
[Нерозбірливо відповідь студента] >> Саме так. 123 отримує покласти тут, і 124 отримує покласти тут.
>> Тепер, тому що я використовував зірка в цій самій першому рядку шлях тут, на вершині,
моя програма просто знає, що 123 і 124, хоча вони, очевидно, цілі
що будь-яка людина міг помітити, вони повинні бути інтерпретовані як адреси, числові адреси.
Вони не є самі по собі цілими, вони адрес,
і це тому, що я явно поставив зірки там.
Так що тепер у моїй першій, другій і третій лінії фактичного коду, що тут відбувається?
Давайте намалюємо решті частини картини.
Tmp так само, як це було в понеділок. Нічого особливого TMP.
Це просто місцевий 32 біт змінної, так і всередині, що я мабуть зберігання значення *.
Тепер, якщо я тільки що сказав, TMP =, що б я тут? >> [Студент] 123.
123. Але це не те, що я роблю.
Я кажу TMP = *. Зірка кошти йдуть туди.
Так от, 123. Як мені туди йти? Прикиньтеся, що є стрілка.
Ну, так і є, 1. Так що ж отримує зберігається у TMP, по-видимому? Просто 1.
Отже, іншими словами, TMP є *, * кошти йдуть на адресу, який є в даний час,
по-видимому, 123.
>> Ну, ось ми і на місці 123, я бачу, № 1,
так що я збираюся поставити номер 1 там.
Тепер те, що я роблю в рядку 2, * = * б?
Це одна трохи складніше, тому що тепер це? Це 123.
Так що * це де? Там, де я був раніше. Так що йдіть туди. Добре.
Тепер, нарешті, і, нарешті, це почне мати сенс, сподіваюся,
* Б означає, що в б? 124. Так що мені потрібно піти туди, що на 2.
Так що я ставлю де?
2 йде в тут, тому що * б * переходить в. Так що я буду робити.
І ви вже можете бачити, мабуть, що ми набагато ближче
до вирішення цієї дурної, просте завдання правильно в перший раз
тому що тепер у нас ще є спогад про те, що х був,
у нас є 2-х примірниках, по загальному визнанню, у,
але лінія 3 тепер говорить, * б.
Так от б. * В означає піти туди. Так де ж розташування 124?
Це мабуть тут. Отже, що ж я тут? Очевидно, TMP.
Так що тепер я це роблю. Так що у мене є 1 і 2 тут тут.
І що тепер про все це, 123, 124 і 1?
Як тільки своп повертається, ця пам'ять так добре, як втратили
тому що як тільки своп повертається, операційна система
має право використовувати цю пам'ять в майбутньому.
Тільки основної пам'яті в нижній цього так званого стеком тиняється поблизу.
>> І ось ми, нарешті, зараз робоча версія.
Відпустіть мене в swap.c, і зверніть увагу на наступне.
У верхній частині програми я змінив мій прототип, щоб бути Int * і * б Int.
Так що єдине, що я змінилася, щоб перейти від червоного, який був поганий, на зелений, і це добре,
це я додав ці зірки сьогодні.
Але тут, в самій поміняти мені довелося скопіювати, вставити те, що було тільки на слайді.
У мене є зірка тут, зірка тут - що відповідає прототипу -
і тоді всі ці речі тепер мають зірки, за винятком TMP
тому, що використання тимчасових змінних, немає нічого нового.
Мені просто потрібно тимчасове сховище для внутр.
Таким чином, нам не потрібні зірки там.
Нам просто потрібно зірці, щоб ми могли перетнути такого роду довільні кордону
Між цими 2 кадри в пам'яті мого комп'ютера.
Але останнє, що має змінитися, і ви, можливо, побачив його вже.
Які інші лінії, очевидно, відрізняється тепер? >> [Студент] & х.
>> Так, так що 25 є останньому рядку коду мені потрібно змінити, щоб це працювало.
Тиждень тому, і навіть в понеділок лінії 25 виглядала так, поміняйте місцями х і у,
і це було просто зламана, тому що якщо ви говорите свопу (х, у)
Ви даєте копії х і у поміняти, то він робить свою справу,
але ви ніколи не міняється х і у себе.
Так що навіть якщо ви ніколи не бачили цей символ, перш ніж з амперсанд в коді,
просто взяти припущення. Що робити амперсанд, мабуть?
[Студент] приймає адресу. >> Бере адресу.
Таким чином, амперсанд говорить, дайте мені адресу х.
Хто знає, де це? Це трапляється, 123. Мені все одно. Просто дайте мені адресу х.
І у означає дати мені адресу у.
І в цей момент історія цілком узгоджується з картиною ми зробили хвилину тому.
>> Таким чином, я визнаю, покажчики, звичайно, для мене, коли я вперше почав Дізнавшись про це,
був безперечно одним з найважчих речей, щоб обернути свій розум навколо.
Але розумієте, тим більше, що ми продовжуємо грати з цими речами,
Якщо ви розбити його на ці супер простий вид інтелектуально нецікаві проблеми
всього рухомого навколо номера, відповідь на багато плутанини з покажчиками
дійсно може бути отримана з цих самих основних механіки.
Ось адреса. Піди туди із зіркою.
Або навпаки, ось амперсанд. З'ясувати, що адресу насправді.
Добре.
Так де ж все це пам'ять приходять?
Ми намалювали цю картину кілька разів, і я тримаю перспективним, ми повернемося до нього,
але от уявлення пам'яті комп'ютера
, Що трохи більше, ніж наші помічені дошці тут.
Текст у верхньому сегменті становить те, що по відношенню до вашої програми?
[Нерозбірливо відповідь студента] >> Вибачте? Скажіть ще раз.
[Студент] Фактичне програми. >> Фактичною програмою.
>> Таким чином, 0 і 1, що ви зібрали після написання коду C і потім запустити Clang
і генеруючих 0 і 1 кінцях тим, що були там ховаються в пам'яті
тому що, коли ви двічі клацніть значок на вашому Mac або PC
або виконайте команду, як Маріо на ваше запрошення, ваше 0 і 1 з диска
завантажуються в пам'ять, так що комп'ютер може керувати ними
і виконувати їх швидше.
Так початкові дані і неініціалізовані дані, ми не будемо багато говорити про тих,
але це тільки глобальні змінні.
Initialized означає глобальні змінні, які ви дали значення;
неініціалізовані означає глобальні змінні, які ви ще не дають значення.
Тоді є ці змінні оточення, які я повністю махнути рукою на,
але вони є, і що магазини речі, як ім'я користувача
та іншого роду нижній рівень подробиці.
Але найсоковитіші шматки макет вашої пам'яті є те, що називається стека і купи.
Стек знову, щоб було ясно, це пам'ять, яка використовується щоразу, коли функції викликаються,
всякий раз, коли є локальні змінні
а також за наявності параметрів, що передаються навколо.
Все, що відбувається в стеці.
Купа ми не говорили про це, але зробити припущення, хто використовує купу.
Просто інший шматок пам'яті.
Буває, який можна зробити тут, на вершині, але це довільне мальовничій конвенції.
Хто Очевидно, використання пам'яті з купи тижні?
Це технічно вас, але побічно. >> [Студент] GetString.
GetString і Танос. Так ось принципова різниця.
>> Ви знаєте, протягом останніх декількох тижнів, що якщо вам потрібна пам'ять, просто оголосити змінну.
Якщо вам потрібно багато пам'яті, оголосити масив прямо всередині вашої функції.
Але проблема ми зберегли зіткнулася, якщо ви оголосите змінні локально всередині функції,
Як тільки функція повертає значення, що відбувається з пам'яттю і ці змінні?
Тільки начебто це вже не ваш, чи не так? Він просто зникає роду концептуально.
Це все ще фізично існує, очевидно, але це вже не ваше право на використання.
Очевидно, що це проблематично, якщо ви хочете написати функції в житті
що насправді виділяє пам'ять і не дають його назад.
Справа в точку: GetString мети в житті, поняття не мають заздалегідь
як великий з рядка Я збираюся ввести на клавіатурі,
але він повинен бути в змозі виділити пам'ять для зберігання Давида або привіт
або цілу статтю про те, що користувач, можливо, ввели дюйма
Так GetString використовує Танос.
Malloc тому необхідно використовувати не стек;
Замість цього, використовуючи те, що називається купою.
Там немає нічого іншого про пам'яті. Це не швидше або повільніше або що-небудь подібне.
Це просто фізично у іншому місці.
>> Але правило, що пам'ять яка виділяється в купі
ніколи не буде відібране у вас, поки ви не зателефонуйте - зробити припущення - безкоштовно.
З іншого боку, будь-яка пам'ять ви просите в стек просто оголошенні масиву
або оголошення змінної, як ми робили протягом тижня,
, Що за замовчуванням закінчується в стеці.
І це прекрасно працює 90% часу, а на тих рідкісних випадках
де ви хочете виділити пам'ять, і тримати його навколо,
Потім ви повинні використовувати функції, як Танос.
Або ми використовували функцію, як GetString, який в свою чергу використовує Танос.
Давайте подивимося, де це може зламати, а потім поглянути на Бінки.
Ми повернемося до цього в майбутньому.
Ось це супер просту програму, яка в перші 2 рядки що робить?
В англійській мові, те, що ці перші 2 рядки коду зробити всередині основного?
[Нерозбірливо відповідь студента]
Обережно. Це не дає мені адресу х або у.
[Студент] Дає покажчиків на цілі. >> Добрий. Дайте мені 2 покажчиків на цілі числа.
Іншими словами, дайте мені 2 ділянок пам'яті, що я тримаю креслення сьогодні,
хоча я стер його зараз, як квадрати.
Дайте мені 2 ділянок пам'яті, одна називається х, одна називається у -
Раніше я називав їх з і т - а що це тип, що частина пам'яті?
Це буде зберігати адресу.
Це типу * Int.
>> Таким чином, адреса Int в кінцевому підсумку жити в х,
Адреса Int в кінцевому підсумку жити в у,
але спочатку, що всередині х і у? Хто знає? Сміття значення.
Це не має нічого спільного з покажчиками.
Якщо ми не встигли щось там, хто знає, що насправді існує?
Тепер, х. Що тут відбувається? Це законно, тому х є покажчиком. Це Int *.
Таким чином, це означає, що я можу покласти в X в адресу деяких шматок пам'яті.
Що Танос повернутися? Perfect, він повертає адресу,
адреса першого байта в цілий шматок пам'яті.
Скільки байт це, очевидно виділення, наприклад, в холодильнику?
Який розмір Int? 4.
Якщо ви згадаєте тижня 1, це не супер важливо завжди пам'ятати, що,
але в даному випадку це корисно знати, 4 байт.
Отже, це виділення в купі 4 байти
і він повертався на адресу першого до мене довільно.
Тепер, що х робите?
* Х = 42, що робить?
Якщо в цей момент в історії ми маємо х, який виглядає, як це з деякими сміття значення,
це зараз у деяких сміття значення, тепер в рядку 3 Я виділив 4 байт.
Ця картина істотно виглядає наступним чином.
Або, більш точно, якщо це довільний адресу 123, це те, що наша історія виглядає тепер.
* Х = 42 означає тепер, що? Це означає, що перехід на адресу 123 і поклав число 42 там.
Мені не потрібно, щоб зробити ці рядки, тому що ми не робимо рядків.
>> Я тільки що написав це так, і тільки заради демонстрації, в
42, внутр вигляд займає багато місця, 4 байт.
Так от що там сталося, але є проблема.
* У = 13. Що станеться тут?
Проблема в тому, * у в нашому спрощеному світі означає лише перейти за адресою у.
Що в Y? Це якась фігня значення.
Отже, давайте припустимо, що сміття значення 5551212, щось божевільний, як це.
* У кошти йдуть на рішення 5551212.
Це все одно тут. Він не існує, наприклад.
Таким чином, у * отримує 13 означає, що я намагаюся зробити тут 13. Вона не існує.
Я перевищили сегмент дошці. Що я отримаю?
Це загадкове вини сегментації повідомлення, тому що я намагаюся поставити в пам'яті
значення, як 13 в місці, яке не існує.
Інша частина програми може працювати добре, але до цього моменту він не робить.
Так давайте спробуємо розповісти цю історію.
Ми повернемося до цього, коли ми говорили про шестігр.
Давайте повернемося до цього і укласти з цією річчю, званої Бінки,
Нагадаємо якої є професор Стенфордського сидячи у себе вдома, граючи з Claymation,
щоб розповісти історію саме тієї ж програми.
Це всього лише близько 3 хвилин. Тут ми маємо Бінки.
[Чоловік динаміка на відео] Гей, Бінки, прокинься. Це час для покажчика весело.
[Бінки] Що це? Дізнатися про покажчиків? О, сентиментальний!
[Чоловік динамік] Ну, для початку, я думаю, ми будемо мати потребу в кількох покажчиків.
>> [Бінки] Добре. Цей код виділяє 2 покажчики, які можуть указувати на цілі числа.
[Чоловік динамік] Добре. Ну, я бачу 2 покажчиків, але вони, схоже, не вказуючи ні до чого.
[Бінки] Це вірно. Спочатку, покажчики не вказують ні до чого.
Те, що вони вказують називають pointees, а їх створення є окремим кроком.
[Чоловік динамік] Ах, так, так. Я знав, що. Pointees окремо.
Е-е, так як ви виділити pointee?
[Бінки] Добре. Цей код створює новий ціле pointee, і ця частина безлічі Х, щоб вказати на це.
[Чоловік динамік] Гей, це виглядає краще.
Так що це щось робити. >> [Бінки] Добре.
Я буду разименовать х, щоб зберегти номер 42 у своєму pointee.
Для цього трюку мені потрібна моя чарівна паличка разименованія.
[Чоловік динамік] Ваша чарівна паличка разименованія? Це здорово.
[Бінки] Це те, що код виглядає наступним чином. Я просто налаштувати кількість і ... [Уривчасті звуки]
[Чоловік динамік] Гей, подивіться, там вона йде.
Так роблять разименованія на х слід стрілку, щоб відкрити її pointee,
У цьому випадку для зберігання 42 в там.
Гей, спробуйте використовувати його, щоб зберегти номер 13 через інший покажчик, у.
[Бінки] Добре. Я піду сюди, щоб у і отримаємо число 13 створений
, А потім взяти паличку разименованія і просто ... [Звук, що дзижчить] Ух ти!
[Чоловік динамік] О, агов, це не працює.
>> Скажімо, Бінки, я не думаю, що у разименованія це гарна ідея
тому що створення pointee окремий крок
і я не думаю, що ми коли-небудь робили це.
[Бінки] Хм, гарне питання.
[Чоловік динамік] Так. Ми виділили покажчик у, але ми ніколи не встановите його, щоб вказати на pointee.
[Бінки] Хм, дуже спостережливі.
[Чоловік динамік] Гей, ви шукаєте там добре, Бінки.
Ви можете це виправити, так що у вказує на той же pointee як х? >> [Бінки] Звичайно.
Я буду використовувати мою чарівну паличку покажчика призначення.
[Чоловік динамік], що буде проблема, як раніше?
[Бінки] Ні, це не стосується pointees.
Це просто змінює один покажчик, щоб вказати на те ж саме іншим. [Уривчасті звуки]
[Чоловік динамік] О, я бачу. Тепер у вказує на те ж місце, х.
Так що чекайте. Тепер у фіксовано. Він має pointee.
Таким чином, ви можете спробувати паличку разименованія знову відправити на 13 старше.
[Бінки] Ну, гаразд. Тут йде. [Уривчасті звуки]
[Чоловік динамік] Гей, подивися на це. Тепер разименованія робіт по в.
І тому, що покажчики обміну, що одна pointee, вони обидва бачать 13.
[Бінки] Так, обмін. Неважливо.
>> Таким чином, ми збираємося, щоб помінятися місцями зараз?
[Чоловік динамік] О, дивіться, ми поза часом. >> [Бінки] Але -
[Чоловік динамік] Тільки пам'ятайте, 3 положення покажчика.
Номер 1, базова структура є те, що у вас є покажчик і він вказує до pointee.
Але покажчик і pointee окремо, а поширена помилка полягає в створенні покажчика
але забути дати йому pointee.
Номер 2, разименованія покажчика починається з покажчика і слід його стрілки над
Для доступу до pointee.
Як ми всі знаємо, це працює тільки, якщо є pointee,
який вид повертається в Правило № 1.
Номер 3, покажчик призначення приймає один покажчик і змінює його
вказують на той же pointee як ще один покажчик.
Таким чином, після призначення, 2 покажчики будуть вказувати на той же pointee.
Іноді це називається обмін.
>> І це все, що є насправді. Прощай зараз.
Це Бінки. Це CS50. Побачимося наступного тижня. [Оплески]
>> [CS50.TV]