Массивы
Содержание
- Массив как структура данных
- Массив в Python
- Создание массива
- Литерал массива
- Создание массива заданной длины, склеивание массивов
- Элементы массива: доступ и изменение
- Доступ по индексу
- Изменение элементов
- Доступ в цикле while
- Доступ в цикле for
- Печать массива
- Ремарка о строках
- Работа с двумерными массивами
- Контест №5
- Массивы в Python, часть 2
- Создание массива
- Списковые включения
- Функция list
- Изменение массива
- Добавление элемента в конец list.append
- Удаление элемента с конца list.pop
- Вставка элемента в список
- Удаление элемента из списка
- Асимптотики методов
- Соединение и копирование массивов
- Питонизмы
Массив (англ. array) — структура данных, хранящая набор значений.
Простейший массив имеет следующий интерфейс
создать(A, N) -> массив A длины N
— создание массиваA
размераN
.записать(A, i, x)
— записывает значениеx
вi
-ый элемент массиваA
.считать(A, i) -> элемент массива A с индексом i
— взятие элемента по индексу (чтение).удалить(A)
— удаление массиваА
.
Обычно индексами массива являются целые положительные числа, причём в непрерывном диапазоне. Например, 0, 1, 2,... N-2, N-1
, где N — размер массива. В таком случае массив упорядочен по индексу и можно говорить, что массив также является последовательностью.
Для массива операции чтения и записи выполняются за O(1)
, т.е. время этих операций не зависит от количества элементов в массиве.
Массив в Python
- упорядоченная изменяемая последовательность…
- массив хранит множество элементов, которые образуют последовательность. При этом можно изменять как сами элементы массива, так и сам массив: пополнять массив новыми элементами или удалять их.
- …объектов произвольных типов
- элементами массива являются Python-объекты. При этом допускается, чтобы в одном массиве хранились объекты разных типов.
Массивы в Python также называют списками или листами (англ. list). Терминология в других языках программирования, а также в теории алгоритмов может быть другая.
Список Python является гибким в использовании объектом. Как инструмент, программист может использовать списки, например, для создания элементов линейной алгебры: точек, векторов, матриц, тензоров. Или, например, для таблицы с некоторыми данными.
Важно заметить, что <class 'list'>
, питоновский список, является универсальной структурой данных. В том числе, ей можно пользоваться как массивом (что мы и будем делать)! То есть, у этого объекта есть интерфейс, описанный в предыдущем разделе, причём с теми же асимптотиками, хотя возможности выходят гораздо за пределы простейшего массива.
Литерал массива
Массив можно создать при помощи литералов. Литерал — это код, который используется для создания объекта «вручную» (задания константы). Например, некоторые литералы уже изученных ранее объектов:
int
:5
,-23
float
:5.
,5.0
,-10.81
,-1.081e1
str
:'ABCdef'
,"ABCdef"
В случае массива литералом являются квадратные скобки []
, внутри которых через запятую ,
перечисляются элементы массива:
>>> [] [] >>> [0, 1, 2, 3, 4] [0, 1, 2, 3, 4] >>> ['sapere', 'aude'] ['sapere', 'aude'] >>> ['Gravitational acceleration', 9. -2'] >>> type([0, 1, 2, 3, 4]) <class 'list'>
Создание массива заданной длины, склеивание массивов
Чтобы создать массив наперёд заданной длины, нужно задать инициализируещее значение и длину. Ниже создаётся массив, содержащий 10 нулей.
>>> A = [0] * 10 >>> A [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] >>> type(A) <class 'list'>
С похожим синтаксисом мы сталкивались при работе со строками. Массивы в Python можно «склеивать» с помощью знака сложения:
>>> A = [0] * 3 # [0, 0, 0] >>> B = [1] * 3 # [1, 1, 1] >>> C = [2] * 3 # [2, 2, 2] >>> D = A + B + C >>> D [0, 0, 0, 1, 1, 1, 2, 2, 2]
На самом деле, умножение массива на целое число M
это создание нового массива путём M
«склеиваний» исходного массива с самим собой:
>>> [0, 1] * 3 [0, 1, 0, 1, 0, 1] >>> [0, 1] + [0, 1] + [0, 1] [0, 1, 0, 1, 0, 1]
Выше мы убедились, что массив это множество объектов различных типов, теперь убедимся, что это упорядоченная последовательность изменяемых объектов. -2′ >>> l = [10, 20, 30] >>> l[0] 10 >>> l[1] 20 >>> l[2] 30
Нумерация элементов массива начинается с нуля.
При запросе элемента по несуществующему индексу, Python вызовет ошибку IndexError:
>>> l [10, 20, 30] >>> l[3] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
Поэтому всегда нужно быть уверенным, что индексация не выходит за пределы длины массива.
Получить её можно с помощью функции len()
:
>>> l [10, 20, 30] >>> len(l) 3 >>> l[len(l) - 1] 30
Последняя конструкция встречается нередко, поэтому в Python существует возможность взять элемент по отрицательному индексу:
>>> l [10, 20, 30] >>> l[-1] 30 >>> l[-2] 20 >>> l[-3] 10 >>> l[-4] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
Таким образом для индекса n ≥ 0, l[-n]
эвивалентно l[len(l) - n]
.
Изменение элементов
>>> l = [10, 20, 30] >>> l [10, 20, 30] >>> l[0] = 0 >>> l [0, 20, 30] >>> l[2] = 55 >>> l [0, 20, 55]
Доступ в цикле while
>>> l [0, 20, 55] >>> i = 0 >>> while i < len(l): ... print(i, l[i]) ... i += 1 ... 0 0 1 20 2 55 >>>
Доступ в цикле for
Наиболее универсальный способ это использование генератора range:
>>> l [0, 20, 55] >>> for i in range(len(l)): ... print(i, l[i]) ... 0 0 1 20 2 55
Чтобы распечатать элементы массива в столбец, воспользуйтесь циклом for
, как в разделе выше.
Если нужно распечатать массив в строку, то воспользуйтесь функцией print
:
>>> A = [0, 1, 2, 3] >>> print(*A) 0 1 2 3
Здесь знак *
это операция развёртывания коллекции по аргументам функции.
print
принимает на вход сколько угодно аргументов и действие выше эквиваленто следующему:>>> print(A[0], A[1], A[2], A[3]) 0 1 2 3
На самом деле, мы уже ранее сталкивались с массивами в предудыщих лабораторных, когда использовали строковый метод str.split
:
>>> s = "ab cd ef1 2 301" >>> s.split() ['ab', 'cd', 'ef1', '2', '301']
Т.е. str.split
, по умолчанию, разбивает строку по символам пустого пространства (пробел, табуляция) и создаёт массив из получившихся «слов».
Загляните в help(str.split)
, чтобы узнать, как изменить такое поведение, и разбивать строку, например, по запятым, что является стандартом для представления таблиц в файлах csv
(comma separated values).
Методом, являющимся обратным к операции str.split
является str.join
>>> s 'ab cd ef1 2 301' >>> l = s. split() >>> l ['ab', 'cd', 'ef1', '2', '301'] >>> l[-1] = '430' >>> l ['ab', 'cd', 'ef1', '2', '430'] >>> ','.join(l) 'ab,cd,ef1,2,430' >>> ' -- '.join(l) 'ab -- cd -- ef1 -- 2 -- 430'
Как вам рассказали, в массиве мы можем хранить различные данные.
В том числе в ячейке массива можем хранить другой массив. Давайте предположим, что
в каждой ячейке массива размера N
у нас будет храниться другой массив размера M
.
Таким образом мы можем построить таблицу или матрицу размера N x M
.
Создание двумерного массива (матрицы) размера N x M
в питоне:
a = [] for _ in range(n): a.append([0] * m)
или
a = [[0] * m for _ in range(n)]
Обращение к элементами двумерного массива:
a[i][j] = 5
Ссылки на контесты
- Начинающие (участвовать)
- Основные (участвовать)
- Продвинутые (участвовать)
Списковые включения
Зачастую требуется создать массив, хранящий значения некоторой функции, например, квадратов чисел или арифметическую последовательность. В Python есть возможность сделать это «на лету».
Для этого можно воспользоваться синтаксическим сахаром Python — списковое включение (list comprehension):
>>> arithm = [ x for x in range(10) ] >>> squares = [ x**2 for x in range(10) ] >>> arithm [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> squares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Списковое включение может содержать и более одного цикла, а также фильтрующее условие
>>> A = [ i * j for i in range(1, 5) for j in range(1, 5)] >>> A [1, 2, 3, 4, 2, 4, 6, 8, 3, 6, 9, 12, 4, 8, 12, 16] >>> odd_squares = [ i**2 for i in range(10) if i % 2 == 1 ] # массив из квадратов нечётных чисел >>> odd_squares [1, 9, 25, 49, 81]
На первом месте во включении должно стоять выражение, возвращающее некоторое значение. Например, это может быть функция
>>> A = [int(input()) for i in range(5)] # считывание массива размера 5 с клавиатуры 9 0 -100 2 74 >>> A [9, 0, -100, 2, 74]
Однако злоупотреблять списковыми включениями не стоит — если заполнение происходит по сложным правилам, лучше избежать использования включения в пользу читаемости кода.
Функция list
Аналогично функциям преобразования типов int()
, float()
, str()
существует функция list()
, создающая список из итерируемого объекта.
Её можно использовать, например, для создания массива символов из строки:
>>> list("sapere aude") ['s', 'a', 'p', 'e', 'r', 'e', ' ', 'a', 'u', 'd', 'e'] >>> list(range(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Типичный пример использования — при чтении массива чисел из строки
>>> s = input() 1 2 -1 93 100 >>> s '1 2 -1 93 100' >>> A = list(map(int, s.split())) >>> A [1, 2, -1, 93, 100]
Как было сказано, можно менять не только значение, записанные в массиве, но и сам массив: можно изменять его размер, добавляя и удаляя элементы.
Добавление элемента в конец list.append
В примере ниже инициализируется пустой массив fibs, а затем заполняется элементами:
>>> fibs = [] >>> fibs. append(1) >>> fibs [1] >>> fibs.append(1) >>> fibs [1, 1] >>> fibs.append(2) >>> fibs [1, 1, 2] >>> fibs.append(3) >>> fibs [1, 1, 2, 3]
Удаление элемента с конца list.pop
>>> fibs = [1, 1, 2, 3] >>> fibs [1, 1, 2, 3] >>> fibs.pop() 3 >>> fibs [1, 1, 2] >>> fibs.pop() 2 >>> fibs [1, 1]
Вставка элемента в список
Метод list.insert(i, x) вставляет элемент x на позицию i в списке
>>> A = [1, 9, 10, 3, -1] >>> A [1, 9, 10, 3, -1] >>> A.insert(0, 'i') >>> A ['i', 1, 9, 10, 3, -1] >>> A.insert(5, 'i2') >>> A ['i', 1, 9, 10, 3, 'i2', -1]
Удаление элемента из списка
Метод list.pop(i) удаляет из списка элемент с индексом i.
>>> B = ['popme', 1, 0, 'popme2', 3, -100] >>> B.pop(0) 'popme' >>> B [1, 0, 'popme2', 3, -100] >>> B.pop(2) 'popme2' >>> B [1, 0, 3, -100]
Асимптотики методов
Здесь A — некоторый список.
Метод списков | Асимптотика метода |
---|---|
A.append(x) | O(1) |
A.pop() | O(1) |
A.insert(i, x) | O(len(A)) |
A.pop(i) | O(len(A)) |
Массивы можно соединять in place, т.е. перезаписывая, с помощью метода list.extend:
>>> A = [0, 1, 2] >>> B = [3, 4, 5] >>> id(A) 4337064576 >>> A.extend(B) >>> id(A) 4337064576 >>> A [0, 1, 2, 3, 4, 5] >>> B [3, 4, 5]
Заметим, что оператор + для списков создаёт новый список.
С копированием массивов нужно быть осторожным. Python никогда не осуществляет копирование явно:
>>> A = [0, 1, 2] >>> B = A >>> B[1] = 'take_care!' >>> A [0, 'take_care!', 2] >>> B [0, 'take_care!', 2] >>> A is B True
В строчке B = A лишь создаётся ещё одна ссылка на объект [0, 1, 2], которая присваивается переменной B. В итоге A и B будут указывать на один и тот же объект.
Чтобы создать копию, необходимо поэлементно создать новый массив из исходного. Например, с помощью функции list() или метода list.copy:
>>> A = [0, 1, 2] >>> B = list(A) >>> C = A.copy() >>> A is B False >>> A is C False >>> B is C False >>> A [0, 1, 2] >>> B [0, 1, 2] >>> C [0, 1, 2]
Приведённые способы копирования работают для списков, содержащих неизменяемые объекты. Если же вы работаете с двумерным массивом или чем-то более сложным, то функцию явного копирования стоит написать самому, либо воспользоваться функцией copy.deepcopy из библиотеки copy.
Конструкции с использованием while и for, изложенные в первой части лабораторной, имеют аналоги практически во всех языках программирования. Они универсальны, стандартны, переносимы из языка в язык.
Этот раздел относится только к особенностям языка Python.
Не злоупотребляйте питонизмами, наша цель — освоить алгоритмы и структуры данных, а не Python.
В языке Python цикл for на самом деле является синтаксическим сахаром, поддерживающим концепцию итерируемого объекта. Его обобщённый синтаксис выглядит примерно так:
for item in any_iterable: # тело цикла
Здесь item это выбранное программистом имя переменной итерирования, которая доступна в теле цикла. В начале каждой итерации в эту переменную помещается значение из any_iterable. Под any_iterable может стоять любой итерируемый объект.
Знакомые нам примеры итерируемых объектов:
- range — генератор арифметической последовательности, for «просит» новые значения у генератора, пока те не закончатся
- str — строковый тип, итерирование происходит по символам
- list — список, итерирование происходит по элементам
Таким образом, pythonic way пробега по списку может выглядеть так:
>>> l [0, 20, 55] >>> for elem in l: . .. print(elem) ... 0 20 55
Отсюда видно, что программист в таком случае теряет удобный способ получить индекс элемента, если он ему нужен.
Под подобные мелкие задачи существует множество «питонизмов» — специфических для языка Python инструментов.
Один из примеров — enumerate — позволяет программисту получить в цикле индекс итерации (!) (а не индекс элемента) и сам элемент.
При таком использовании номер итерации совпадает с индексом элемента:
>>> l [0, 20, 55] >>> for i, elem in enumerate(l): ... print(i, elem) ... 0 0 1 20 2 55
Код приведённый для enumerate выше, аналогичен универсальным:
>>> l [0, 20, 55] >>> for i in range(len(l)): ... elem = l[i] ... print(i, elem) ... 0 0 1 20 2 55
>>> l [0, 20, 55] >>> i = 0 >>> while i < len(l): ... elem = l[i] ... print(i, elem) ... i += 1 ... 0 0 1 20 2 55
Примеры использования массивов в VBA
Массивы используются в большинстве языков программирования и VBA, как язык высокого уровня, тоже не мог обойтись без них. Данный материал расскажет о создании массивов, их применении, а так же вы здесь найдете примеры использования массивов. Для начала разберем синтаксис определения массивов.
Объявление массивов
Пример 1. Создание (объявление) одномерного массива выполняется, так:
Dim Arr1(10) As Integer Dim Arr2(5 To 10) As String Dim Arr3() As Long
В данном примере объявляются: одномерный массив Arr1, содержащий ячейки с 0-й до 10-й типа Integer, массив Arr2, содержащий ячейки с 5-й до 10-й типа String и динамический массив Arr3.
Прежде чем использовать динамический массив, его необходимо «инициализировать», т.е. выделить для него необходимую память. Менять размер динамического массива можно много раз в программе, даже в цикле, если хотите. Правда учитывайте, что выделение памяти для массива — ресурсно-затратная операция, поэтому не стоит менять размер массива очень часто, это сильно замедлит программу.
Пример 2. Инициализация динамического массива и изменение его размеров
Dim Arr3() As Long ReDim Preserve Arr3(10) ReDim Preserve Arr3(20)
В данном примере мы сначала с помощью ReDim задали размер динамического массива в 11 элементов (c 0-го по 10-й), а затем снова увеличили размер до 21-го элемента. Кроме того, использовали ключевое слово Preserve — означающее, что нужно сохранить уже имеющиеся элементы с их значениями (без этого ключевого слова массив обнуляется).
Примечание: изменение размеров функцией ReDim возможно только для динамических массивов. Если размер массива был изначально задан, то его размер уже не будет меняться функцией.
Пример 3. Объявление многомерного массива
Dim Arr4(10, 10) As Integer Dim Arr5(5 To 10, 15 To 20, 30) As String
Arr4 — двумерных массив 11х11 элементов, а массив Arr5 — трехмерный.
Пример 4. Создание массива массивов
В следующем примере массив Arr2 будет содержать элементы другого массива Arr1
Dim Arr1 As Variant Dim Arr2(10) As Variant Arr1 = Array(10, 20, 30) Arr2(0) = Arr1 For i = LBound(Arr2(0)) To UBound(Arr2(0)) MsgBox Arr2(0)(i) ' Выведет последовательно 10, 20 и 30 Next i
Определение нижней и верхней границы массива
Чтобы узнать какой самый наименьший индекс у массива и какой самый максимальный индекс массива, нужно использовать функции LBound для определения нижней границы и UBound для определения верхней границы.
Пример 5. Определение границ массива
Dim Arr1(2 To 15) As Integer MsgBox LBound(Arr1) ' Выведет: 2 MsgBox UBound(Arr1) ' Выведет: 15 Dim Arr2() As Integer ReDim Arr2(8) MsgBox LBound(Arr2) ' Выведет: 0 MsgBox UBound(Arr2) ' Выведет: 8
Чтобы определить границы многомерных массивов, нужно просто использовать второй параметр функций UBound и LBound.
Dim Arr(1 To 10, 5 To 20) As Integer MsgBox LBound(Arr, 2) ' Выведет: 5 MsgBox UBound(Arr, 2) ' Выведет: 20
Задание нижней границы по-умолчанию
Иногда бывает очень не удобно, что VBA начинает нумерацию элементов массивов с нуля (0), это часто может привести к путанице и усложнению кода программы. Для решения этой проблемы есть специальный оператор Option Base, аргумент которого может быть 0 или 1. Указав значение 1, индексация массивов будет начинаться с 1, а не с 0.
Пример 6. Указание нижней границы по-умолчанию.
Option Base 1 Sub Test() Dim Arr1(10) As Integer MsgBox LBound(Arr1) End Sub
В данном примере я намеренно использовал процедуру, чтобы показать, что Option Base нужно применять не внутри процедур и функций, а в разделе «Declarations». В результате выполнения процедуры Test будет отображено сообщение с индексом нижней границы массива, т. е. «1».
Примечание: Оператор Option Base так же влияет на функцию Array и не влияет на функцию Split (будут рассмотрены ниже), что означает, что при задании «Option Base 1», функция Array вернет массив с индексацией с 1-цы, а функция Split вернет массив с индексацией с 0.
Запись данных в массивы
Для сохранения каких-либо значений в массив, можно воспользоваться несколькими способами. С помощью примеров, покажу эти способы.
Пример 7. Запись данных в массив в цикле.
Dim Arr(10) As Integer For i = 0 To 10 Arr(i) = i * 2 Next i
Пример 8. Запись заранее известных данных с помощью Array
Dim Arr() Arr = Array("красный", "зеленый", "синий") MsgBox Arr(2)
Функция Array возвращает массив из перечисленных данных типа Variant. При этом, массив, который будет содержать значения, должен быть динамическим, т. е. без указания его размеров и границ.
Пример 9. Получение массива из строки с разделителями
Dim Arr() As String Arr = Split("красный;зеленый;синий", ";") MsgBox Arr(2)
Обход элементов массива
Обычно, массивы используются для хранения большого кол-ва данных, а не 1-2 значений, поэтому чтобы получить все эелементы и использовать их для чего-то, обычно используют циклы. Наиболее удобны в этом плане циклы For и For Each.
Пример 10. Обход элементов массива циклом For.
Dim Sum As Integer Dim Arr() Arr = Array(10, 20, 30) For i = 0 To 2 Sum = Sum + Arr(i) Next i MsgBox Sum
Пример 11. Обход элементов массива циклом For Each.
Dim Sum As Integer Dim Val As Variant Dim Arr() Arr = Array(10, 20, 30) For Each Val In Arr Sum = Sum + Val Next MsgBox Sum
Иногда, бывает необходимость работы с массивом внутри других типов циклов, но получение значение элемента, всё-равно в них будет таким же, как и в цикле For, т. е. через индекс элемента.
Одномерный массив C++
В этом посте вы узнаете об одномерных массивах в C++. Итак, без лишних слов, приступим.
Группа элементов, имеющих одинаковый тип данных и имя, образует одномерный массив. Общее название каждого элемента, а также собственное Отдельный индекс используется для идентификации каждого отдельного элемента.
Объявление одномерного массива в C++
Простейшей формой массива является одномерный массив. Самому массиву дается имя, а на его элементы ссылаются их индексы. В С++, одномерный массив обозначается следующим образом:
имя типа[размер];
, где «тип» — это тип данных, «имя» — это имя одномерного массива, а «размер» — это количество элементов, которые может содержать массив. Например:
int arr[5];
объявляет массив «arr», который может хранить до 5 элементов типа «int».
Инициализация одномерного массива в C++
Вот общая форма для инициализации значений в одномерном массиве в C++.
тип_данных имя_массива[размер_массива] = {список_элементов, разделенных запятыми};
Вот пример объявления и инициализации значений для имени массива arr типа int , который содержит 10 элементов.
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Если вас интересует просмотр программ, созданных на одномерном массиве, рекомендуется прочитать статью под названием «Программы одномерных массивов». С другой стороны, после того, как я закончу объяснять этот момент, я дать вам несколько примеров, чтобы помочь вам лучше понять концепцию и для вашего собственного удобства.
Вот несколько примеров программ на C++, демонстрирующих одномерные массивы. Ниже приведен первый пример программы:
#includeиспользование пространства имен std; основной () { интервал [5] = {1, 2, 3, 4, 5}; для (целое я = 0; я <5; я ++) { cout< Вывод этой программы на C++ выглядит следующим образом:
1 2 3 4 5То есть первый элемент (1) хранится в "arr[0]", аналогично, второй элемент (2) хранится в "arr[1]" и так далее. Поэтому, используя только цикл for с его переменной, работающей от 0 до 4, я напечатал элементы каждого массива на консоли вывода.
Теперь позвольте мне изменить приведенную выше программу, чтобы она печатала значение каждого элемента вместе с его индексами.
#includeиспользование пространства имен std; основной () { int i, arr[5] = {10, 20, 23, 43, 50}; для (я = 0; я <5; я ++) cout<<"arr["< Теперь вывод должен быть:
обр[0] = 10 обр[1] = 20 обр[2] = 23 обр[3] = 43 arr[4] = 50Теперь пришло время снова изменить приведенную выше программу, чтобы пользователь мог вводить элементы массива:
#includeиспользование пространства имен std; основной () { интервал я, обр[5]; cout<<"Введите 5 элементов для массива: "; для (я = 0; я <5; я ++) cin>>arr[i]; cout<<"\nМассив:\n"; для (я = 0; я <5; я ++) cout< На следующем снимке показан начальный вывод, созданный вышеприведенной программой:
Теперь введите ввод. То есть введите первое число и нажмите ENTER, затем второе число и снова нажмите ENTER. Предоставьте пять входных данных в виде элементов массива и нажмите клавишу ENTER, чтобы увидеть следующий вывод:
Позвольте мне внести еще одно изменение в программу. Следующая программа позволяет пользователю указать размер массива, а также его элементы, а затем печатает элементы в консоль вывода.
#includeиспользование пространства имен std; основной () { инт я, тот; cout<<"Введите размер массива: "; цин>>общ; инт обр[общий]; cout<<"\nВведите элементы "< >arr[i]; } cout<<"\nМассив:\n"; for(i=0; i На приведенном ниже снимке экрана показан пример запуска вышеуказанной программы со следующими пользовательскими входными данными: 8 в качестве размера и 10, 20, 30, 40, 50, 60, 70 и 80 в качестве элементов массива.
Другие примеры одномерного массива
- Линейный поиск в C++
- Двоичный поиск в C++
- Найти самый большой элемент в массиве в C++
- Реверс массива в C++
- Программа пузырьковой сортировки на C++
- Программа сортировки выбором на C++
- Программа сортировки вставками на C++
Викторина по C++
« Предыдущий учебникСледующий учебник »
Двумерные массивы в C — проектирование встроенных систем с использованием конечного автомата UML
В этой статье давайте узнаем о двумерных массивах в «C».
Рисунок 1 , Пример одномерного массива
Например, если вы считаете баллов uint8_t[3] = {10, 20, 30}; Здесь scores[3] — это одномерный массив из 3 элементов типа uint8, один байт данных. Итак, scores[3] — это массив из трех элементов, каждый из которых имеет размер 1 байт. И баллы указывают имя массива; его тип является типом указателя. Но здесь scores — это имя массива, а 10, 20, 30 — инициализация. И мы называем это одномерным массивом, потому что вы не можете индексировать этот массив только в одном измерении; вы называете это x измерением.
Здесь 10 — 0-й элемент, 20 — первый элемент, 30 — второй элемент. Если вы наберете 0 баллов, вы получите значение 10. Если вы наберете 1 балл, вы получите значение 20. Мы называем это индексированием. Индексация может быть выполнена только в одном измерении. Вот почему он называется одномерным массивом. Речь идет об одномерном массиве.
Двумерный массив:
Двумерный массив — это структура данных в C, которая используется или полезна при представлении набора данных в виде таблицы.
Таблица: Таблица имеет несколько строк и несколько столбцов.
Рисунок 2. Пример двумерного массива
Рассмотрим этот пример, как показано на рисунке 2. Здесь scores — это имя двумерного массива, [2] → указывает количество строк в таблице, а [ 3] → указывает количество столбцов таблицы. Таблица — это не что иное, как некоторое расположение данных.
С помощью поля [2] вы можете переключаться между разными строками, а с помощью поля [3] вы можете переключаться между разными столбцами. Следовательно, он называется двумерным массивом, потому что есть две точки переключения. Вы можете переключаться в направлении y или переключаться в направлении x. И двумерные массивы инициализируются так. Сначала инициализируйте первую строку, поставьте запятую и инициализируйте вторую строку. 10, 20, 30 эти значения данных первой строки должны быть заключены в фигурные скобки.
Рисунок 3. Пример 2-мерного массива
Предположим, если я пишу типа scores[0][1], то данные 0-й строки, первого столбца, я получаю 20, как показано на рисунке 3.
Рисунок 4. Пример двумерного массива
Если я делаю баллы[1][2], это означает строку 1, столбец 2. Значение, которое он предоставляет, равно 45 (рисунок 4). Вы можете сделать индексацию следующим образом.
Почему это полезно?
Рисунок 5. Маркировочный лист Испытания-1 по номерам валков
Рассмотрим этот пример: оценочный лист теста-1 вашего класса в виде номеров бросков, как показано на рис. 5. Есть четыре ученика; Номера рулонов от 0 до 3 и 4 предмета. Код предмета по математике — 0. Код по физике — 1. Код по химии — 2. Код по экономике — 3. А остальное — это оценки, выставленные учащимся.
Как вы это делаете?
uint8_t marksheet_of_test[16] = {34, 56, 77, 99, 67, 34, 89 …… 21,43};
Можно сохранить 16 данных. Вот почему вы создаете один массив из 16 байт и начинаете хранить значения. Во-первых, вы сохраняете 34,56, 77, вот так, вплоть до последних чисел.
Недостатком этого метода является то, что вы хотите получить некоторые значения, например, какую оценку набрал Бросок номер 1 по химии? Теперь, как узнать, используете ли вы одномерный массив? Это возможно, но это немного сложно. Вот как вы собираетесь это вычислить. Итак, вы должны отработать это.
Рисунок 6. Оценочный лист Теста-1 согласно номерам бросков
Прежде всего, оценка, выставленная по броску номер 1, означает, что вы должны сначала получить 67. Как вы получаете 67? Вы можете прийти сюда по указанному ряду.
uint8_t mark = marksheet_of_test1[1*4+2];
Номер рулона 1, умноженный на общее количество столбцов. Вы должны умножить это. 1 умножается на общее количество столбцов 4 и затем добавляется код темы. Вы хотите химии; химия равна 2. Вы добавляете к ней 2. Затем вы достигаете точки 89, вот так.
Например, какая оценка выставляется за бросок номер 3 по физике?
Рис. 7. Пример двумерного массива
Во-первых, вы должны прибыть на 98. Как вы сюда попали? Строка в вопросе 3, умноженная на общее количество столбцов 4, равна 12. Это массив из 12.
Массив из 12 равен 98, а затем добавьте код темы. Код темы 1. Итак, добавляем 1. 45 (рисунок 7).
Это означает, что таблицу также можно представить в виде одномерного массива, без проблем. Но вам придется немного потрудиться, чтобы узнать нужную координату. Для этой цели язык программирования C предоставил вам двумерную структуру данных массива.
Рисунок 8. Пример двумерного массива
В приведенном выше примере двумерный массив определяется как четыре строки и четыре столбца и инициализируются значения.
Предположим, я хочу получить отметку по химическому тесту за второй бросок. Здесь это очень просто; укажите номер строки и номер столбца. Строка номер 2 и номер столбца тоже 2, что дает мне 30. Это очень просто, если вы используете двумерный массив. Это помогло бы, если бы вы не боролись с получением этих координат.
Давайте разберемся, как двумерный массив сохраняется в памяти.
Рис. 9. Хранение двумерного массива в памяти
Память, выделенная для одномерного массива, по своей природе непрерывна. Например, посмотрите на рисунок 9. В этом массиве 3 элемента данных, и 3 байта памяти будут выделены рядом друг с другом. И здесь имя массива содержит адрес первого элемента массива.
Распределение памяти точно такое же, если рассматривать двумерный массив.
Например, uint8_t items[2][2] — это двумерный массив с двумя строками и двумя столбцами; это означает, что имеется 4 элемента данных, как вы можете видеть на рис. 9. В памяти данные хранятся построчно. Здесь выкладывается первый ряд, примыкающий ко второму ряду. А память носит непрерывный характер. Память размещается построчно. Это очень просто понять.
По этой причине всякий раз, когда вы инициализируете двумерный массив, вам не нужно упоминать информацию о строке. Это может быть необязательно. Но информация столбца является обязательной.
Видите ли, здесь я даже могу написать элементов [][2] , оставить строку пустой и даже написать столбец равным 2, это и приравнять к тому, что я хочу инициализировать. Всякий раз, когда компилятор видит этот оператор, компилятор понимает, что есть две строки. Вот почему вам не нужно упоминать эту информацию строки.
Рисунок 10. Инициализация двумерного массива
Первая строка {1, 2} и инициализация второй строки {2,3}.
uint8_t элементов[2][2] → Когда компилятор увидит это определение на первом шаге, он должен понять, что оно состоит из двух строк и двух столбцов.
uint8_t items[][] → Когда вы упомянете это определение, оно выдаст ошибку, если вы его скомпилируете. И что говорит об ошибке, вы должны предоставить информацию о столбце. Информация о столбце, внешняя граница, которую вы можете увидеть здесь, границы, которые вы должны указать.
uint8_t items[][2] → Вы указываете 2 в информации столбца и компилируете. Хорошо. Это не приводит к ошибкам. Почему? Когда компилятор это видит, он понимает, что строк две. Поэтому он сам заполнит эту информацию. Но вы должны указать информацию о столбце. Поскольку в строке две записи, это не означает, что в ней два столбца.