1 00:00:07,360 --> 00:00:09,360 [Powered by Google Translate] Давайте поговорим о массивах. 2 00:00:09,360 --> 00:00:12,780 Так почему же мы все хотим использовать массивы? 3 00:00:12,780 --> 00:00:17,210 Ну, скажем, у вас есть программа, которую необходимо хранить 5 идентификаторов студентов. 4 00:00:17,210 --> 00:00:21,270 Казалось бы разумно иметь 5 отдельных переменных. 5 00:00:21,270 --> 00:00:24,240 По причинам, которые мы увидим в немного, мы начнем отсчет с 0. 6 00:00:24,240 --> 00:00:30,700 Переменных мы будем иметь будет id0 Int, Int id1, и так далее. 7 00:00:30,700 --> 00:00:34,870 Любая логика, которую мы хотим выполнить на студенческий билет нужно будет скопировать и вставить 8 00:00:34,870 --> 00:00:36,870 Для каждого из этих студентов идентификаторов. 9 00:00:36,870 --> 00:00:39,710 Если мы хотим, чтобы проверить, какие студенты оказались в CS50, 10 00:00:39,710 --> 00:00:43,910 мы сначала нужно проверить, если id0 представляет студентом на курсе. 11 00:00:43,910 --> 00:00:48,070 Затем сделать то же самое на следующий студент, нам нужно скопировать и вставить код для id0 12 00:00:48,070 --> 00:00:54,430 и заменить все вхождения id0 с id1 и так далее для id2, 3, и 4. 13 00:00:54,430 --> 00:00:57,560 >> Как только вы услышите, что нам нужно скопировать и вставить, 14 00:00:57,560 --> 00:01:00,440 Вы должны начать думать, что есть лучшее решение. 15 00:01:00,440 --> 00:01:05,360 А что, если вы понимаете, что вы не нуждаетесь в 5 идентификаторы студентов, а 7? 16 00:01:05,360 --> 00:01:09,570 Вам нужно вернуться в исходный код и добавить в ID5, ID6, 17 00:01:09,570 --> 00:01:14,260 и скопировать и вставить логику для проверки, если идентификаторы относятся к классу для этих 2 новых идентификаторов. 18 00:01:14,260 --> 00:01:19,600 Существует ничего подключения всех этих идентификаторов вместе, и поэтому нет способа просить 19 00:01:19,600 --> 00:01:22,040 Программа сделать это для идентификаторов 0 до 6. 20 00:01:22,040 --> 00:01:26,120 Ну теперь вы понимаете, у вас есть 100 идентификаторов студентов. 21 00:01:26,120 --> 00:01:30,770 Это начинает казаться меньше, чем идеально нужно отдельно объявить каждую из этих идентификаторов, 22 00:01:30,770 --> 00:01:33,760 и скопировать и вставить любой логики для этих новых идентификаторов. 23 00:01:33,760 --> 00:01:38,380 Но, возможно, мы полны решимости, и мы делаем это для всех 100 студентов. 24 00:01:38,380 --> 00:01:42,240 Но что, если вы не знаете, сколько студентов есть на самом деле? 25 00:01:42,240 --> 00:01:47,320 Есть только некоторые российских студентов и ваша программа должна спросить пользователя, что это п. 26 00:01:47,320 --> 00:01:50,250 Ой-ой. Это не будет работать очень хорошо. 27 00:01:50,250 --> 00:01:53,820 Ваша программа работает только для некоторых постоянных числа студентов. 28 00:01:53,820 --> 00:01:57,520 >> Решение всех этих проблем есть красота массивов. 29 00:01:57,520 --> 00:01:59,930 Так что же такое массив? 30 00:01:59,930 --> 00:02:04,480 В некоторых языках программирования типа массива могли бы сделать немного больше, 31 00:02:04,480 --> 00:02:09,960 но здесь мы сосредоточимся на основной структуры массива данных так же, как вы увидите его в C. 32 00:02:09,960 --> 00:02:14,030 Массив это просто большой блок памяти. Вот и все. 33 00:02:14,030 --> 00:02:17,770 Когда мы говорим, у нас есть массив из 10 целых чисел, что просто означает, что у нас есть блок 34 00:02:17,770 --> 00:02:20,740 памяти, достаточно большой, чтобы провести 10 отдельных чисел. 35 00:02:29,930 --> 00:02:33,410 Предполагая, что целое 4 байта, это означает, что массив из 10 целых чисел 36 00:02:33,410 --> 00:02:37,180 непрерывный блок из 40 байт в памяти. 37 00:02:42,660 --> 00:02:46,280 Даже если вы используете многомерные массивы, которые мы не будем вдаваться в сюда, 38 00:02:46,280 --> 00:02:49,200 это еще только большой блок памяти. 39 00:02:49,200 --> 00:02:51,840 Многомерных обозначений просто для удобства. 40 00:02:51,840 --> 00:02:55,640 Если у вас есть 3 на 3 многомерный массив целых чисел, 41 00:02:55,640 --> 00:03:00,650 Затем ваша программа будет действительно только рассматривать это как большой блок из 36 байт. 42 00:03:00,650 --> 00:03:05,460 Общее количество целых чисел в 3 раза 3, и каждое целое число занимает 4 байта. 43 00:03:05,460 --> 00:03:07,750 >> Давайте взглянем на простой пример. 44 00:03:07,750 --> 00:03:10,660 Мы видим здесь 2 различных способов объявления массивов. 45 00:03:15,660 --> 00:03:18,580 Мы должны будем комментировать 1 из них за программа для компиляции 46 00:03:18,580 --> 00:03:20,900 так как мы заявляем х в два раза. 47 00:03:20,900 --> 00:03:25,140 Мы взглянем на некоторые различия между этими 2 типами заявлений в немного. 48 00:03:25,140 --> 00:03:28,560 Обе эти линии объявить массив размера N, 49 00:03:28,560 --> 00:03:30,740 где мы определим N # как 10. 50 00:03:30,740 --> 00:03:34,460 Мы могли бы так же легко, попросил у пользователя натуральное 51 00:03:34,460 --> 00:03:37,250 и использовал его как целое число элементов в массиве. 52 00:03:37,250 --> 00:03:41,960 Нравится наш студенческий билет, например, перед, это вроде как объявить 10 полностью отдельный 53 00:03:41,960 --> 00:03:49,000 мнимых переменных x0, x1, x2, и так далее до Xn-1. 54 00:03:57,270 --> 00:04:00,840 Не обращая внимания на линиях, где мы объявляем массив, обратите внимание на квадратные скобки нетронутыми 55 00:04:00,840 --> 00:04:02,090 внутри циклов. 56 00:04:02,090 --> 00:04:09,660 Когда мы пишем что-то вроде X [3], который я только что прочитал, как х кронштейн 3, 57 00:04:09,660 --> 00:04:13,090 Вы можете думать о нем, как просить мнимой x3. 58 00:04:13,090 --> 00:04:17,519 Обратите внимание, чем массив размера N, это значит, что номер внутри скобок 59 00:04:17,519 --> 00:04:22,630 который мы будем называть индексом, может быть что угодно от 0 до N-1, 60 00:04:22,630 --> 00:04:25,660 которая является общей индексов N. 61 00:04:25,660 --> 00:04:28,260 >> Думать о том, как это на самом деле работает 62 00:04:28,260 --> 00:04:31,260 помните, что массив представляет собой большой блок памяти. 63 00:04:31,260 --> 00:04:37,460 Предполагая, что целое 4 байта, весь массив х 40 байт блока памяти. 64 00:04:37,460 --> 00:04:41,360 Так x0 относится к самым первым 4 байта блока. 65 00:04:45,810 --> 00:04:49,230 X [1] ссылается на следующие 4 байта и так далее. 66 00:04:49,230 --> 00:04:53,760 Это означает, что в начале х все программы никогда не должны отслеживать. 67 00:04:55,660 --> 00:04:59,840 Если вы хотите использовать х [400], то программа знает, что это эквивалентно 68 00:04:59,840 --> 00:05:03,460 только 1600 байт после начала х. 69 00:05:03,460 --> 00:05:08,780 Откуда мы получаем 1600 байт из? Это всего лишь в 400 раз 4 байта на целое число. 70 00:05:08,780 --> 00:05:13,170 >> Прежде чем двигаться дальше, это очень важно понимать, что в C 71 00:05:13,170 --> 00:05:17,080 нет органов индекс, который мы используем в массиве. 72 00:05:17,080 --> 00:05:23,180 Наш большой блок находится всего в 10 целых долго, но ничего не будет кричать на нас, если мы пишем х [20] 73 00:05:23,180 --> 00:05:26,060 или даже х [-5]. 74 00:05:26,060 --> 00:05:28,240 Индекс не должны даже быть рядом. 75 00:05:28,240 --> 00:05:30,630 Это может быть любое произвольное выражение. 76 00:05:30,630 --> 00:05:34,800 В программе мы используем переменную я из цикла в качестве индекса в массиве. 77 00:05:34,800 --> 00:05:40,340 Это очень распространенная картина, цикл от I = 0 до длины массива, 78 00:05:40,340 --> 00:05:43,350 а затем с помощью я как индекс для массива. 79 00:05:43,350 --> 00:05:46,160 Таким образом, вы эффективно цикл по всему массиву, 80 00:05:46,160 --> 00:05:50,600 и вы можете присвоить каждому место в массиве, или использовать его для некоторых расчетов. 81 00:05:50,600 --> 00:05:53,920 >> В первый цикл, я начинается с 0, 82 00:05:53,920 --> 00:05:58,680 и так будет назначить на 0 месте в массиве, значение 0 раз 2. 83 00:05:58,680 --> 00:06:04,370 Тогда я шагом, и мы присвоить первое место в массиве значение 1 раз 2. 84 00:06:04,370 --> 00:06:10,170 Тогда я вновь увеличивается на единицу и так далее, пока мы не назначить в положение N-1 в массиве 85 00:06:10,170 --> 00:06:13,370 Значение N-1 раз 2. 86 00:06:13,370 --> 00:06:17,810 Таким образом, мы создали массив с первых 10 четных чисел. 87 00:06:17,810 --> 00:06:21,970 Может быть, выравнивает было бы немного лучше, имя переменной, чем х, 88 00:06:21,970 --> 00:06:24,760 но это дало бы вещи. 89 00:06:24,760 --> 00:06:30,210 Второй цикл, то просто печатает значения, что мы уже хранится внутри массива. 90 00:06:30,210 --> 00:06:33,600 >> Давайте попробуем запустить программу с обоими типами массива деклараций 91 00:06:33,600 --> 00:06:36,330 и посмотрите на результат работы программы. 92 00:06:51,450 --> 00:06:57,020 Насколько мы можем видеть, программа ведет себя так же для обоих типов деклараций. 93 00:06:57,020 --> 00:07:02,230 Давайте же взглянем на то, что произойдет, если мы изменим первую петлю, чтобы не останавливаться на N 94 00:07:02,230 --> 00:07:05,040 а сказать 10.000. 95 00:07:05,040 --> 00:07:07,430 Пути за пределы массива. 96 00:07:14,700 --> 00:07:17,210 Ой. Может быть, вы видели это раньше. 97 00:07:17,210 --> 00:07:20,440 Ошибки сегментации означает, что ваши программы произошел сбой. 98 00:07:20,440 --> 00:07:24,430 Вы начинаете видеть это, когда вы касаетесь области памяти, вы не должны касаться. 99 00:07:24,430 --> 00:07:27,870 Здесь соприкасаются 10000 мест за начало х, 100 00:07:27,870 --> 00:07:31,920 которая, очевидно, является местом в памяти, мы не должны соприкасаться. 101 00:07:31,920 --> 00:07:37,690 Поэтому большинство из нас, вероятно, не случайно поставил 10000 вместо N, 102 00:07:37,690 --> 00:07:42,930 Но что, если мы делаем что-то более тонкое, как говорят записи меньше или равно N 103 00:07:42,930 --> 00:07:46,830 в цикле условие, а не меньше, чем N. 104 00:07:46,830 --> 00:07:50,100 Помните, что массив имеет только индексами от 0 до N-1, 105 00:07:50,100 --> 00:07:54,510 Это означает, что индекс N находится за пределами конца массива. 106 00:07:54,510 --> 00:07:58,050 Программа не может привести к сбою в данном случае, но это все равно ошибка. 107 00:07:58,050 --> 00:08:01,950 На самом деле, эта ошибка является настолько распространенным, что оно имеет свое собственное имя, 108 00:08:01,950 --> 00:08:03,970 выключения на 1 ошибка. 109 00:08:03,970 --> 00:08:05,970 >> Вот именно для основы. 110 00:08:05,970 --> 00:08:09,960 Итак, какие же основные различия между 2 типами массива деклараций? 111 00:08:09,960 --> 00:08:13,960 Одно из отличий является, где большой блок памяти идет. 112 00:08:13,960 --> 00:08:17,660 В первую декларацию, в которой я буду называть брекет-тип массива, 113 00:08:17,660 --> 00:08:20,300 хотя это отнюдь не условное наименование, 114 00:08:20,300 --> 00:08:22,480 он будет идти в стеке. 115 00:08:22,480 --> 00:08:27,450 В то время как во втором, который я буду называть указатель типа массива, он будет идти в кучу. 116 00:08:27,450 --> 00:08:32,480 Это означает, что когда функция возвращает, кронштейн массив будет автоматически освобождается, 117 00:08:32,480 --> 00:08:36,419 в то время как вы должны explicitily позвонить бесплатно на массив указателей 118 00:08:36,419 --> 00:08:38,010 или же у вас есть утечка памяти. 119 00:08:38,010 --> 00:08:42,750 Кроме того, кронштейн массива фактически не является переменной. 120 00:08:42,750 --> 00:08:45,490 Это очень важно. Это просто символ. 121 00:08:45,490 --> 00:08:49,160 Вы можете думать об этом как константа, компилятор выбирает для вас. 122 00:08:49,160 --> 00:08:52,970 Это означает, что мы не можем сделать что-то вроде х + + с кронштейном типа, 123 00:08:52,970 --> 00:08:56,240 хотя это вполне допустимо с указателем. 124 00:08:56,240 --> 00:08:58,270 >> Указатель типа переменной. 125 00:08:58,270 --> 00:09:01,510 Для указателей типа, у нас есть 2 отдельных блоков памяти. 126 00:09:01,510 --> 00:09:06,060 Переменная х сам хранятся в стеке и только один указатель, 127 00:09:06,060 --> 00:09:08,620 но большой блок памяти хранятся в куче. 128 00:09:08,620 --> 00:09:11,010 Переменная х в стек только хранит адрес 129 00:09:11,010 --> 00:09:14,010 большой блок памяти в куче. 130 00:09:14,010 --> 00:09:17,370 Одним из следствий этого является с размером оператора. 131 00:09:17,370 --> 00:09:22,480 Если вы попросите размер кронштейна массив, это даст вам размер большой блок памяти, 132 00:09:22,480 --> 00:09:24,620 что-то вроде 40 байт, 133 00:09:24,620 --> 00:09:26,920 Но если вы попросите размер указателя типа массива, 134 00:09:26,920 --> 00:09:32,740 это даст вам размер переменной х себя, что на прибор, скорее всего, только 4 байт. 135 00:09:32,740 --> 00:09:36,530 Использование указателей типа массива, нельзя напрямую обратиться за 136 00:09:36,530 --> 00:09:38,530 Размер большой блок памяти. 137 00:09:38,530 --> 00:09:42,530 Это обычно не много ограничений, так как мы очень редко хотят размера 138 00:09:42,530 --> 00:09:46,980 большой блок памяти, и мы, как правило, вычислить его, если нам это нужно. 139 00:09:46,980 --> 00:09:51,490 >> Наконец, кронштейн массива происходит, чтобы предоставить нам ярлык для инициализации массива. 140 00:09:51,490 --> 00:09:56,130 Давайте посмотрим, как мы могли бы написать первые 10 четных чисел с помощью контекстного initilization. 141 00:10:11,220 --> 00:10:14,470 С массива указателей, не существует способа сделать ярлык, как это. 142 00:10:14,470 --> 00:10:18,120 Это всего лишь введение к тому, что вы можете сделать с массивами. 143 00:10:18,120 --> 00:10:20,990 Они появляются почти в каждой программе вы пишете. 144 00:10:20,990 --> 00:10:24,390 Надеюсь, теперь вы можете видеть лучший способ это сделать на примере студентов идентификаторы 145 00:10:24,390 --> 00:10:26,710 С начала видео. 146 00:10:26,710 --> 00:10:29,960 >> Меня зовут Боб Боуден, и это CS50.