Как декларируются и формируются массивы
Перейти к содержимому

Как декларируются и формируются массивы

Тема: Как передать массив в функциональный блок если зарание не известно сколько элемнтов

Serhioromano вне форума

По умолчаниюКак передать массив в функциональный блок если зарание не известно сколько элемнтов

myArray1 := ARRAY[0..2] OF STRING; myArray2 := ARRAY[0..10] OF STRING; myArray3 := ARRAY[0..4] OF STRING;

Конечно же все сложней. Это не строки а структура с многотиповым хранением данных.

Есть так же универсальный функциональный блок который может их обработать. Он просто в цикле походит по каждому элементу и делает свое дело.

Когда я поределяю входную переменную мне надо написать

In := ARRAY[0..2] OF STRING;

И вот тут проблема. я ведь могу туда опустить любой массив а у меня разное количество элементов.

Как мне сделать так что бы можно было передать массив с любым колличеством элементов?

26.03.2017, 21:52 #2

capzap на форуме

Пользователь Регистрация 25.02.2011 Адрес Киров Сообщений 10,113

По умолчанию

добавляйте а свою структуру некий id, в фб передайте указатель, если у очередного элемента индекс равен нулю, значит массив закончился

Bad programmers worry about the code. Good programmers worry about data structures and their relationships

среди успешных людей я не встречала нытиков
Барбара Коркоран
27.03.2017, 07:54 #3

  • Просмотр профиля
  • Сообщения форума
  • Личное сообщение
  • Просмотр статей

Serhioromano вне форума

Пользователь Регистрация 15.09.2015 Адрес Бишкек Сообщений 265

По умолчанию

Нет это понятно. Я могу пройти в цикле неопределенное количество элементов. Это не проблема. Как этот массив передать в FB? Ведь мне нужно декларировать переменную входную или локальную и там указвать зарание количество элементов в массиве, так что как я не передавай, входная переменная должна иметь тоже колличество.

27.03.2017, 08:26 #4

capzap на форуме

Пользователь Регистрация 25.02.2011 Адрес Киров Сообщений 10,113

По умолчанию

массив, это уложенные последовательно в памяти однородные данные, ни какой массив передавать в ФБ я не предлагаю, а рекомендую передавать указатель на тип данных из которых сформирован массив, начиная с начального элемента массива, а далее как угодно, в цикле определяете когда данные закончились или с этим указателем передавайте количество элементов массива. В оскат библиотеке много таких примеров

Bad programmers worry about the code. Good programmers worry about data structures and their relationships

среди успешных людей я не встречала нытиков
Барбара Коркоран
29.03.2017, 09:48 #5

slonegd вне форума

Пользователь Регистрация 08.08.2014 Сообщений 79

По умолчанию

Когда работал с файлами, там тоже заранее неизвестно сколько и чего записывать надо обычно. Как советует capzap, то просто дать указатель и работать с ним. Также можно передавать и разнородную структуру. Мне было удобно указатель на байт и sizeof структуры, чтобы определить её границы.

30.03.2017, 03:36 #6

  • Просмотр профиля
  • Сообщения форума
  • Личное сообщение
  • Просмотр статей

Serhioromano вне форума

Пользователь Регистрация 15.09.2015 Адрес Бишкек Сообщений 265

По умолчанию

Можно примерчик указателя?

30.03.2017, 07:15 #7

petera на форуме

Пользователь Регистрация 06.05.2011 Адрес Минск Сообщений 3,759

По умолчанию

ЦитатаСообщение от Serhioromano Посмотреть сообщение

Можно примерчик указателя?
Кусочно-линейная аппроксимация http://www.owen.ru/forum/showthread. l=1#post220263

FUNCTION MyGraf_p : REAL VAR_INPUT IN: REAL; (*Входной сигнал*) pt : POINTER TO ARRAY[0..99] OF Point_GR; (*Массив точек графика, не более 100 пар точек X,Y*) size : UINT; END_VAR VAR a: INT; (*Начало интервала поиска*) b: INT; (*Конец интервала поиска*) N: INT; (*Число точек в графике*) i: INT; END_VAR N:= SHR(size,3)-1; (*Число точек в графике*) (*Начальные значения интнрвала поиска*) a:=0; b:=N-1; (*Обрезание графика для крайних точек*) IF IN=pt^[N-1].X THEN MyGraf_p:=pt^[N-1].Y; (*Теперь можно начать поиск*) ELSE WHILE (b-a) <> 1 DO (*В конце концов, входной сигнал ТОЧНО попадет между двумя соседними точками X(a) и Х(а+1)*) i:=(a+b)/2; (*Делим интервал поиска пополам*) IF IN=pt^[i+1].X THEN (*Может нам повезло, и мы сразу нашли точку? *) a:=i; b:=i+1; (*Бинго! прекращаем итераций, нечего в пустую молотить :) *) (*мимо :( ,тогда посмотрим в какую половину интервала попали*) ELSIF IN>pt^[i].X THEN (*Если входной сигнал больше середины интервала поиска,*) a:=i; (*то следующий поиск будем делать начиная от середины и до конца массива*) ELSE (*А если входной сигнал меньше середины интервала поиска,*) b:=i; (*то следующий поиск будем делать начиная от начала и до середины массива*) END_IF (*Таким образом на каждой итерации отбрасываем из поиска заведомо ненужную половину значений две соседние координаты X(a) и Х(а+1), меду которыми попадает входной сигнал найдем очень быстро для 8 точек графика нужно не более 3 итераций при 9..16 точек в графике нужно не более 4 итераций при 17..32 точек в графике нужно не более 5 итераций при 33..64 точек в графике нужно не более 6 итераций при 65..128 точек в графике нужно не более 7 итераций инфа точная - 100% ;) *) END_WHILE (*Теперь самое простое - сделать линейную аппроксимацию по двум точкам ;) *) MyGraf_p:=pt^[b].Y-(pt^[b].X-IN)*(pt^[b].Y-pt^[a].Y)/(pt^[b].X-pt^[a].X); END_IF

Сам массив структур передается в функцию через указатель, по этому вызывать ее нужно так
MyGraf_p(IN, ADR(Имя_Массива), SIZEOF(Имя_Массива))

PROGRAM PLC_PRG VAR GR: ARRAY [0..49] OF Point_GR:= (X:=0, Y:=15),(X:=3, Y:=25),(X:=4, Y:=45),(X:=8, Y:=75),(X:=15, Y:=45), (X:=16, Y:=45),(X:=20, Y:=65),(X:=22, Y:=75),(X:=40, Y:=95),(X:=50, Y:=105), (X:=110, Y:=15),(X:=120, Y:=25),(X:=130, Y:=45),(X:=140, Y:=75),(X:=150, Y:=45), (X:=160, Y:=45),(X:=200, Y:=65),(X:=220, Y:=75),(X:=240, Y:=95),(X:=250, Y:=305), (X:=301, Y:=15),(X:=305, Y:=25),(X:=324, Y:=45),(X:=380, Y:=75),(X:=415, Y:=45), (X:=416, Y:=45),(X:=420, Y:=65),(X:=422, Y:=75),(X:=440, Y:=495),(X:=450, Y:=505), (X:=511, Y:=15),(X:=515, Y:=25),(X:=524, Y:=45),(X:=580, Y:=75),(X:=615, Y:=45), (X:=416, Y:=45),(X:=420, Y:=65),(X:=422, Y:=75),(X:=440, Y:=495),(X:=450, Y:=505), (X:=621, Y:=15),(X:=625, Y:=25),(X:=634, Y:=45),(X:=680, Y:=75),(X:=695, Y:=45), (X:=676, Y:=45),(X:=680, Y:=65),(X:=692, Y:=75),(X:=740, Y:=495),(X:=750, Y:=505); IN: REAL; OUT: REAL; END_VAR (*ВАЖНО! Таблица должна быть обязательно отсортирована по X в порядке возрастания значений.*) OUT:=MyGraf_p(IN, ADR(GR), SIZEOF(GR));

Контрольные вопросы:

1. Что такое проект, и какие элементы он может содержать? 2. Какие типы модулей может включать проект? 3. Каково различие между переменной и константой? 4. Какие символы допускается применять в именах переменных? 5. Какие базовые типы данных поддерживает Visual Basic for Application? 6. Как определяются процедуры и функции? Встроенные функции в VBA. 7. Каково различие между линейным и блочным оператором if? 8. Как определяются различные виды циклов в VBA? Чем они различаются? 9. Как декларируются и формируются массивы? 10. Какие возможности для отладки программ есть в VBA?

3. Объектно-ориентированное программирование на vba

3.1 Разработка программы создания приложения с помощью Форм

Пример 1. Постановка задачи. Требуется разработать программу вычисления значения выражения при заданных числах, вводимых пользователем с клавиатуры в два (три) поля с именами «Число1», «Число2» («Число3»), с отображением результата в поле «Результат». Результат должен отображаться после нажатия кнопки . Программа должна заканчивать работу после нажатия кнопки . Окно программы должно иметь вид, показанный на рисунке 22. , при a=0.126, b=0.842, x=0.34 Технология выполнения задания: Процесс программирования приложения Вычисление предусмотрен тремя этапами, представленными в таблице 26. Таблица 26 — Этапы программирования

Этапы программирования Число объектов
1 Создание пользовательского интерфейса 11 объектов
2 Установка свойств объектов 11 объектов
3 Составление программного кода 2 объекта

Iэтап. Разработка пользовательского интерфейса 1. Запустить среду программирования VBA. Рисунок 22 – Окно программы «Вычисление» 2. Выполнить команду Insert→UserForm. В центре экрана появляется чистая форма, как показано на рисунке 23, которая будет использоваться для создания пользовательского интерфейса. 3. Поместить указатель мыши в правый нижний угол окна формы так, чтобы он принял вид двунаправленной стрелки. Переместить указатель, увеличивая размеры формы так, чтобы на ней могли разместиться все объекты программы. Рисунок 23 – Пользовательская форма 4. Создать на форме объект Командная кнопка. — щелкнуть по кнопке (Командная кнопка) на панели инструментов (ToolBox); — переместить указатель мыши на форму в левый нижний угол; — удерживая левую кнопку мыши нажатой, вычертить указателем мыши прямоугольный объект. Он приобретает определенные очертания и «привязывается» к сетке формы. — отпустить кнопку мыши. Экран будет выглядеть, как показано на рисунке 24. Рисунок 24 – Вид формы с объектом «Командная кнопка» По умолчанию первая командная кнопка, имеющая набор команд управления, называется . Ее можно перемещать и изменять ее размеры. При желании можно изменить шаг сетки (меню Tools (Настройки), команда Options (параметры), вкладка General (Общие)). Например, Grid Units: Points Width: 6, Height: 6. 5. Аналогично создать вторую командную кнопку, поместив ее ниже первой. Кнопка получит имя . 6. Числовые и текстовые данные могут вводиться в программах VBA в текстовые поля (окна). Для того чтобы создать на форме текстовое поле, необходимо: — щелкнуть по кнопке (Текстовое окно) панели инструментов; — переместить указатель мыши в левый верхний угол формы и, удерживая нажатой левую кнопку, очертить указателем мыши прямоугольный объект. По умолчанию объект получает имя Text1. 7. Аналогично создать объекты Text2, Text3, поместив их над объектом Text1. 8. Для показа текста, чисел и символов при работе программы и формирования надписей используется специальный элемент пользовательского интерфейса, называемый этикеткой. Добавим в форму этикетку для отображения результата. Для этого нужно: — щелкнуть мышью по кнопке (Этикетка) на панели инструментов; — поместить указатель мыши в верхний правый угол формы и, удерживая нажатой левую клавишу мыши, очертить прямоугольное окно. Созданный объект получает имя Label1. После этого экран будет выглядеть, как показано на рисунке 25. Рисунок 25 – Вид формы с объектами «Командные кнопки», «Текстовые поля», «Этикетки» 9. Добавить этикетки для надписей над окнами ввода чисел, результата и названия программы. Для этого нужно повторить пять раз операцию построения этикеток: — щелкнуть по кнопке панели инструментов; — переместить указатель мыши на форму и, удерживая левую клавишу мыши, построить прямоугольные окна для надписей). Полученный на экране результат приведен на рисунке 26. Рисунок 26 – Окончательный вид формы IIэтап. Установка свойств объектов Изменим надпись формы с UserForm1 на значимую в соответствии с решаемой задачей. Для этого необходимо выполнить: — щелкнуть мышью на форме; — в окне «Properties» (Свойства) появятся свойства формы; — дважды щелкнуть на свойстве Caption (Название) в левой колонке окна свойств для выделения установленного по умолчанию названия «UserForm1»; — ввести название «Вычисление». Алгоритм действий: 1) щелкнуть по первой командной кнопке (). Кнопка будет выделена маркерами; 2) в окне свойств, показанном на рисунке 27, будут перечислены установки для командной кнопки (цвет фона, название, размер шрифта, ширина кнопки и др.); Рисунок 27 – Вид окна «Свойств» 3) дважды щелкнуть на свойстве Caption в левой колонке окна свойств для выделения установленного по умолчанию названия (CommandButton1); 4) набрать новое название для кнопки и нажать клавишу Enter (можно щелкнуть мышью по форме). Название командной кнопки в окне свойств и в форме изменится на . 5) аналогично надо изменить название второй командной кнопки. Это можно сделать другим способом. Для этого нужно: — открыть ниспадающее окно «Object List» (Список объектов) щелчком мыши по кнопке в верхней части окна свойств. В списке будут перечислены все объекты программы, как показано на рисунке 28. Рисунок 28 – Вид окна «Список объектов» — щелкнуть на строке в окне списка. В окне свойств появятся установки для второй командной кнопки; — дважды щелкнуть на свойстве названия (), набрать и нажать клавишу Enter. Название второй кнопки изменится на . 6) свойства текстовых полей 1, 2, 3 должны быть одинаковыми (они выполняют одинаковые функции – ввод чисел). Поэтому установим их как группу. Для этого необходимо выполнить: — щелкнуть мышью по первому объекту (Text1); — удерживая нажатой клавишу Ctrl, щелкнуть мышью по второму объекту (Text2) и третьему (Text3). В результате текстовые поля будут выделены, а устанавливаемые значения свойств в окне «Properties» будут общими (одними и теми же) для полей «Text1», «Text2», «Text3». 7) установить свойство Text для текстовых полей в значение Empty (Пусто). Это означает, что нужно удалить текущую установку и оставить свойство пустым. В этом случае в поля «Text1»- «Text3» можно вводить произвольную информацию с клавиатуры. 8) перейти к установке свойств для этикетки Label1, предназначенной для отображения результата. Для этого необходимо выполнить: — щелкнуть мышью по объекту Label1 для его выделения; — щелкнуть на свойстве TextAlign (Выравнивание текста), а затем справа на стрелке окна ниспадающего списка; — щелкнуть на цифре 2 — (Выравнивание по центру). Отображаемый результат будет выравниваться по центру поля. 9) изменить стиль рамки. Для этого: — щелкнуть мышью на свойстве Border Style (Стиль рамки), а затем – на стрелке окна ниспадающего списка, который появится справа; — щелкнуть на значение 1 — , чтобы добавить тонкую рамку вокруг этикетки; 10) установить шрифт, которым будут выводиться цифры в окне результата: — дважды щелкнуть по свойству Font (Шрифт); — появится диалоговое окно, приведенное на рисунке 29. — в нем выбрать желаемый шрифт (например, Times New Roman), начертание (полужирный), кегль (14); — щелкнуть по кнопке . 11) удалить название объекта Label1, так как в поле объекта будет выводиться числовой результат: — дважды щелкнуть мышью на свойстве Caption и нажать клавишу Delete. 12) аналогично установить общие для этикеток Label2-Label5 свойства: выравнивание, стиль рамки и шрифт. Для этого необходимо: — выделить эти объекты как группу, используя клавишу Ctrl; — поочередно щелкая мышью по объектам; — установить общие свойства TextAlign, Border Style, Font, как это делалось для объекта Label1. 13) установить свойство Caption для объектов Label2-Label5, используя значения Результат, Число 1, Число 2, Число 3 соответственно. Рисунок 29 – Вид диалогового окна Шрифт 14) щелкнуть по объекту Label6 для его выделения. Эта этикетка должна иметь название программы Вычисление, поэтому значение свойства Caption заменить на Вычисление. 15) установить свойства объекта Label6: — выравнивание по центру; — отсутствие рамки (значение Border Style равно нулю); — шрифт Arial; — полужирный; — кегль – 20. 16) изменить цвет текста. Для этого необходимо выполнить: — дважды щелкнуть мышью на свойстве ForeColor в окне свойств; — в поле списка появятся вкладки System (Система) и Palette (Палитра), позволяющие изменять цвет объекта. Вкладка System показывает цвета пользовательского интерфейса Windows. Вкладка Palette содержит все доступные цвета. — щелкнуть на вкладке Palette, а затем – на квадратике красного (или другого) цвета. Название Вычисление приобрело этот цвет, в окне свойств он представляется шестнадцатеричным числом. IIIэтап. Составление программного кода Большинство объектов, которые созданы, уже «знают», как работать после запуска программы, и готовы к приему данных от пользователя. Внутренняя функциональность создаваемых объектов – одна из мощнейших особенностей VBA. В разрабатываемой программе необходим код, который будет вычислять значение выражения по определенной формуле с помощью вводимых пользователем чисел и отображать результат вычислений. Вычислительная логика может быть встроена в приложение только с помощью программного кода, который точно определяет, что именно должна делать программа на каждом этапе работы. Программа управляется кнопками и (Конец), поэтому программный код будет связан с информацией, поступающей от этих кнопок. Для работы с программным кодом командной кнопки нужно дважды по ней щелкнуть мышью. Например, щелкнем по кнопке на форме. После этого появляется окно «Cod» (Код), изображенное на рисунке 30. Рисунок 30 – Вид окна «Код» Блок кода, связанный с частным объектом интерфейса, называется процедурой события VBA. Тело процедуры заключено между операторами, указывающими на начало и конец подпрограммы. Private Sub CommandButton2_Click() End Sub Операторы тела и процедуры выполняются каждый раз, когда пользователь активизирует элемент интерфейса, ассоциированный с процедурой. В данном случае событием является щелчок мыши (Click), но могут быть и события другого типа. (Их можно увидеть в ниспадающем списке, щелкнув по стрелке правее надписи Click). Разработаем программный код для кнопок и . 1. Открыть список объектов в окне «Code». Все объекты интерфейса Вычислить появятся в списке, как показано на рисунке 31. Рисунок 31 – Вид списка объектов 2. Щелкнуть по строке CommandButton1 в списке. Появится «пустая» процедура, связанная с кнопкой . Несмотря на то, что название кнопки было изменено на , в программе ее имя осталось прежним. Следует иметь в виду, что у каждого объекта интерфейса может быть несколько ассоциированных с ним процедур – по одной для каждого связанного с этим объектом события. В данном случае для кнопки задано только одно событие – щелчок мышью. 3. Набрать следующие программные строки: Private Sub CommandButton1_Click() Dim A, B, X, z1, z2, z3 As Single A = Val(TextBox1.Text) B = Val(TextBox2.Text) X = Val(TextBox3.Text) z1 = Abs(Log(X) / Log(10)) — Sqr(Abs(Cos(X) — Exp(X))) z2 = Abs(Tan(Abs(A * X — B)) / Sin(Abs(X)) + B) z3 = Atn(z2 / Sqr(Abs(1 — z2 ^ 2))) Label1.Caption = Log(Abs(z1 * z3)) End Sub Примечание. Функция Val преобразует текстовый аргумент в числовое значение (по умолчанию данные, введенные в текстовое поле, представляются как обычный текст). 4. Дважды щелкнуть мышью по командной кнопке на форме (или выбрать строку Command2 в окне «Code». 5. Набрать программную строку процедуры, связанной с кнопкой . В данном случае это один оператор End. Он используется для останова программы и удаления ее с экрана (рисунок 32). Рисунок 32 – Программный код, связанный с командной кнопкой 1 и 2 IVэтап – Запуск программы Запуск программы может быть осуществлен следующим образом: 1. Выбрать команду из меню Run→Run Sub/UserForm. Программа Вычисление запустится в среде программирования VBA. На экране появится разработанный программный интерфейс. 2. В поле ввода числа 1, где мигающий курсор, ввести произвольное число (целое или с дробной частью). 3. Нажать клавишу Tab или щелкнуть мышью на поле ввода числа 2. Мигающий курсор появится в поле числа 2. 4. Ввести второе произвольное число в поле 2. 5. Аналогично ввести третье число в поле 3. 6. Щелкнуть на кнопке . В поле результата будет показан окончательный результат вычисления выражения. 7. Для продолжения работы программы, то есть для вычисления выражения при других входных данных, надо щелкнуть мышью на поле ввода числа 1 и ввести его. 8. Выполнить действия п.3-7 и т.д. Работа программы в подобном режиме диалога будет продолжаться до тех пор, пока не будет произведен щелчок мыши по кнопке . В этом случае программа завершит работу, и среда программирования VBA вновь появится на экране. Vэтап Сохранить созданную программу создания приложения Пример экономической задачи. Расчет стоимости с учетом НДС. Постановка задачи. Создать диалоговое окно, в котором производится расчет стоимости товара с учетом НДС по его стоимости без НДС и значению ставки НДС. Технология выполнения задания: 1. В редакторе Visual Basic в проект добавьте форму. На ней расположить три надписи, три поля ввода и две командные кнопки, как показано на рисунке 33. Рисунок 33 – Диалоговое окно «Расчет стоимости» 2. При помощи окна Properties задать элементам управления значения следующим образом, как показано в таблице 27. Таблица 27

Элемент управления Свойство Значение
Форма Caption Расчет стоимости
Надпись Caption Стоимость без учета НДС
Поле ввода Name TextBox1
Надпись Caption НДС

Продолжение таблицы 27

Поле ввода Name TextBox2
Надпись Caption Стоимость с учетом НДС
Поле ввода Name TextBox3
Кнопка Name Caption CommandButton1 ОК
Кнопка Name Caption CommandButton2 Отмена
  1. В модуле проекта набрать следующий код, изображенный

Рисунок 34 – Программный код

4. Запустить проект.

— в поле Стоимость без учета НДС ввести 1000;

— в поле НДС ввести 25;

— нажать кнопку ОК.

В поле Стоимость с учетом НДС будет выведена искомая стоимость. Для закрытия окна нажать кнопку Отмена.

Как декларировать массив массивов произвольной вложенности?

pav5000

Что имеете ввиду под «произвольной вложенностью»?
Чтобы количество уровней вложенности можно было задавать в рантайме?

uvelichitel

uvelichitel @uvelichitel Автор вопроса, куратор тега Go
Решения вопроса 1

pav5000

Если объявить type s1 []s1, то заполнять так:

s1 := s1< < <>, < <>, <>, <>, <>, <>, >, <>, >, >

Пользы это этого никакой, правда, ибо там негде хранить значения.
Если вам надо просто хранить n-мерный массив, я бы предложил лучше хранить одномерный массив, просто написать функцию обращения к нужному элементу с учетом n-мерности.
Если нужна именно мультивложенность и у вложенных соседних элементов может быть разная размерность, то придется сделать структуру, чтобы можно было хранить значения.

type s1 struct < Value int // тут любой тип можно, в принципе, лучше указателем Children []s1 >func main() < s1 := s1< Children: []s1< , , , >>, , , >>, >, > fmt.Println(s1) >

Массивы в памяти компьютера — PHP: Массивы

Работая на таких высокоуровневых языках как PHP, позволительно не знать устройство массивов для решения повседневных задач. С другой стороны, подобное понимание делает код менее магическим и даёт возможность заглядывать чуть дальше.

Массивы в языке C

Реальные массивы лучше всего рассматривать на языке , который, с одной стороны, достаточно простой и понятный, с другой — очень близок к железу и не скрывает от нас практически ничего. Когда мы говорим про примитивные типы данных, такие как «строка» или «число», то на интуитивном уровне все довольно понятно. Под каждое значение выделяется некоторый объем памяти в соответствии с типом, в которой и хранится само значение. А как должна выделиться память под хранение массива? И что такое массив в памяти? На уровне хранения, понятия массив не существует. Массив представляется цельным куском памяти, размер которого вычисляется по следующей формуле: количество элементов * количество памяти под каждый элемент. Из этого утверждения есть два интересных вывода:

  • Размер массива — фиксированная величина. Те динамические массивы, с которыми мы имеем дело во многих языках, реализованы уже внутри языка, а не на уровне железа
  • Все элементы массива имеют один тип и занимают одно и то же количество памяти. Благодаря этому появляется возможность простым умножением (по формуле, описанной выше) получить адрес той ячейки, в которой лежит нужный нам элемент. Именно это происходит под капотом, при обращении к элементу массива под определённым индексом

Фактически, индекс в массиве — смещение относительно начала куска памяти, содержащего данные массива. Адрес, по которому расположен элемент под конкретным индексом, рассчитывается так: начальный адрес + индекс * количество памяти, занимаемое одним элементом (для данного типа данных). Начальный адрес, это адрес ячейки памяти, начиная с которой размещается массив. Он формируется во время выделения памяти под массив.

// Инициализация массива из пяти элементов типа int // В этом месте резервируется память под него // Непрерывный кусок памяти размером _количество элементов * количество байт под int_ int mark[] = 19, 10, 8, 17, 9>; // _Начальный адрес + 3 * количество байт под int_ // Так рассчитывается фактический адрес, по которому располагаются данные mark[3]; // 17 

Если предположить, что тип int занимает в памяти 2 байта (зависит от архитектуры), то адрес элемента, соответствующего индексу 3 , вычисляется так: начальный адрес + 3 * 2. Для индекса 1 – начальный адрес + 1 * 2.

В такой формуле расчета адреса, есть ровно один способ физически разместить данные в начале доступной памяти – использовать нулевой индекс: начальный адрес + 0 * размер элемента конкретного типа = начальный адрес.

// Первый элемент // Начальный адрес + 2 * 0 = начальный адрес mark[0]; // 19 // Начальный адрес + 2 * 1 = начальный адрес + 2 // То есть сместились на 2 байта mark[1]; // 10 // Начальный адрес + 2 * 2 = начальный адрес + 4 // То есть сместились на 4 байта mark[2]; // 8 // Последний элемент // Начальный адрес + 2 * 4 = начальный адрес + 8 // То есть сместились на 8 байт // И сам элемент занимает 2 байта. В сумме как раз 10 mark[4]; // 9 

Теперь должно быть понятно, почему индексы в массиве начинаются с нуля. 0 — означает отсутствие смещения.

Но не все данные имеют одинаковый размер. Как будет храниться массив строк? Строки ведь имеют разную длину, а значит требуют разное количество памяти для своего хранения. Один из способов сохранить строки в массиве на языке Си – создать массив массивов (тут нужно понимать, что любая строка в Си это массив символов). Вложенные массивы обязательно должны быть одного размера, невозможно обойти физические ограничения массивов. Хитрость в том, что этот размер должен быть достаточно большой, чтобы туда поместились необходимые строки.

// Массив из трех элементов, внутри которого массивы по 10 элементов // Это значит, что здесь можно хранить 3 строки длиной не больше 10 символов char strings[3][10] =  "spike", "tom", "jerry" >; strings[0]; // spike 

Безопасность

В отличие от высокоуровневых языков, в которых код защищён от выхода за границу массива, в таком языке как Си, выход за границу не приводит к ошибкам. Обращение к элементу, индекс которого находится за пределами массива, вернёт данные, которые лежат в той самой области памяти, куда его попросили обратиться в соответствии с формулой выше. Чем они окажутся — никому не известно (но они будут проинтерпретированы в соответствии с типом массива. Если массив имеет тип int , то вернётся число). Благодаря отсутствию какой-либо защиты, выход за границу массива активно эксплуатируется хакерами для взлома программ.

Массивы в динамических языках

В динамических языках, таких как PHP или JS, устройство массивов значительно сложнее, чем в C. Так как типы данных вычисляются автоматически во время выполнения кода. Массив в такой среде не может работать как в си. Неизвестно, данные каких типов окажутся внутри в процессе работы.

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *