[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]