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