Что такое массив как расположены элементы массива в оперативной памяти

Обновлено: 07.07.2024

Работая на таких высокоуровневых языках как 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 * размер элемента конкретного типа = начальный адрес.

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

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

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

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

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

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

Массив - это набор элементов (компонентов), которые имеют одинаковый тип данных. Причём этот тип данных может быть как простым, так и сложным.

Элементы массива в памяти компьютера расположены друг за другом. Получить доступ к отдельному элементу массива можно по индексу этого элемента.

Любой массив имеет фиксированный размер. Таким образом, размерность массива - это количество индексов, необходимое для однозначного доступа к элементу массива.

Массив может быть как одномерным, так и многомерным. Например, таблица - это двухмерный массив (строки таблицы - это одна размерность массива, столбцы таблицы - вторая). Разумеется, таблицу можно представить как два одномерных массива. Но легче работать с одним массивом, нежели с двумя.

Наиболее часто используются одномерные и двухмерные массивы. Реже - трёхмерные. Массивы с большей размерностью я использовать не рекомендую (особенно новичкам), так как это чревато большим количеством труднонаходимых ошибок.

В качестве индекса массива может использоваться переменная. Эта переменная должна обязательно иметь порядковый тип.

Некоторые языки программирования и средства разработки имеют в своём арсенале динамические массивы, то есть массивы не с фиксированной, а с неопределённой размерностью.

Зачем нужны массивы? Ответ простой - для удобства (как, впрочем, и все языковые конструкции). Во многих случаях работать с массивом данных более удобно, чем с отдельными переменными.

Синтаксис массива в Паскале:

var ИмяМассива : array[0..15] of ТипДанных;

Здесь ИмяМассива - это имя переменной, связанной с этим массивом. ТипДанных - это тип данных элементов массива. Пример:

var M1 : array[0..15] of byte;

Здесь мы объявили массив с именем М1, который содержит 16 элементов типа byte с индексами от 0 до 15. первый элемент массива имеет индекс 0, второй - индекс 1 и так далее.

Работать с отдельным элементом массива можно так:

var m : byte;
M1[0] := 100;
m := M1[0];

Здесь мы сначала в первый элемент массива записываем значение 100, а потом в переменную m записываем значение первого элемента массива. Догадайтесь, какое значение будет в переменной m после этого))).

Но понять всю прелесть использования массивов вы сможете только тогда, когда попробуете обработать все элементы массива в цикле. Например, так:

for i := 0 to 15 do M1[i] := i;
for i := 0 to 15 do Write(M1[i], ' ');

Надеюсь, не надо объяснять, что делает этот код. А теперь представьте, сколько бы строк кода вам пришлось написать, если бы то же самое вы делали с помощью обычных переменных.

Двухмерный массив объявляется так:

M2 : array[1..4, 1..2] of byte;

Это будет матрица (или таблица) 4х2. То есть такой массив имеет некоторое количество строк (в нашем примере 4) и некоторое количество столбцов (в нашем примере 2). Того же результата можно достичь, если объявить массив массивов:

M2e : array[1..4] of array[1..2] of byte;

Здесь новичкам обычно трудно сообразить, что со всем этим “многомерьем” делать. Ну ничего, привыкайте. Первый массив - это строки таблицы. Второй - это столбцы. То есть каждый элемент первого массива содержит массив array[0..1]. Таблица (матрица), представленная нашим примером, выглядит так:

Строка 1, Столбец 1 Строка 1, Столбец 2
Строка 2, Столбец 1 Строка 2, Столбец 2
Строка 3, Столбец 1 Строка 3, Столбец 2
Строка 4, Столбец 1 Строка 4, Столбец 2

М2[1, 1] - это ячейка 1.1 (первая строка, первый столбец)
М2[1, 2] - это ячейка 1.2 (первая строка, второй столбец)
М2[2, 1] - это ячейка 2.1 (вторая строка, первый столбец)

Если вы попробуете использовать, например, М2[1, 3], то компилятор выдаст предупреждение, так как столбца 3 в нашем массиве не существует. Однако будьте осторожны! В некоторых средствах разработки программа при этом будет создана (зависит от настроек среды)! И вы можете получить ошибку, которую в последствии будет трудно обнаружить.

А теперь пример использования нашего двухмерного массива:

Как видите, здесь мы используем ДВЕ индексных переменных (i и j) и вложенные циклы. Как работают вложенные циклы - попробуйте догадаться сами. Если не получится - задайте вопрос в разделе ВОПРОСЫ. Этот раздел я стараюсь проверять хотя бы раз в день.

Надеюсь, с этим кодом вы разобрались. Или хотя бы запустили его и посмотрели, что он делает. А он выводит двухмерный массив на экран. Но вывод выполняется в одну строку. И это не очень удобно для двухмерного массива. Ведь обычно в таких массивах представлены матрицы (таблицы). То есть удобнее воспринимать информацию, если она будет выводиться в виде таблицы. В нашем случае хотелось бы получить 4 строки и 2 столбца.

Попробуйте решить эту задачу самостоятельно. А если у вас не получится, то вот один из вариантов решения:

Это решение не является универсальным, так как его сложно применить к массивам с другой размерностью (с другим количеством столбцов). Но зато оно простое. И во многих случаях его можно использовать.

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

Ну и напоследок добавлю, что для определения индексов массива можно использовать уже известные нам по первым урокам стандартные функции Low и High. Например, так:

WriteLn('Индекс первого элемента М1 : ', Low(M1));
WriteLn('Индекс последнего элемента М1 : ', High(M1));

Статья получилась больше, чем я ожидал. Но надеюсь, у вас хватило терпения дочитать её до конца.

Для того чтобы разобраться в возможностях и особенностях обработки массивов в программах на ассемблере, нужно ответить на следующие вопросы:

· Как описать массивв программе?

· Как инициализировать массив, то есть как задать начальные значения его элементов?

· Как организовать доступк элементам массива?

· Как организовать массивыс размерностью более одной?

· Как организовать выполнениетиповых операций с массивами?

Описание и инициализация массива в программе

Специальных средств описания массивов в программах ассемблера, конечно, нет. При необходимости использовать массив в программе его нужно моделировать одним из следующих способов:

1. Перечислением элементов массива в поле операндов одной из директив описания данных. При перечислении элементы разделяются запятыми. К примеру:

;массив из 5 элементов.Размер каждого элемента 4 байта:

2. Используя оператор повторения dup. К примеру:

;массив из 5 нулевых элементов.

;Размер каждого элемента 2 байта:

Такой способ определения используется для резервирования памяти с целью размещения и инициализации элементов массива.

3. Используя директивы labelиrept. Пара этих директив может облегчить описание больших массивов в памяти и повысить наглядность такого описания. Директиваreptотносится к макросредствам языка ассемблера и вызывает повторение указанное число раз строк, заключенных между директивой и строкой endm. К примеру, определим массив байт в области памяти, обозначенной идентификаторомmas_b. В данном случае директиваlabelопределяет символическое имяmas_b, аналогично тому, как это делают директивы резервирования и инициализации памяти. Достоинство директивыlabelв том, что она не резервирует память, а лишь определяет характеристики объекта. В данном случае объект — это ячейка памяти. Используя несколько директивlabel, записанных одна за другой, можно присвоить одной и той же области памяти разные имена и разный тип, что и сделано в следующем фрагменте:

mas_b label byte

mas_w label word

В результате в памяти будет создана последовательность из четырех слов f1f0. Эту последовательность можно трактовать как массив байт или слов в зависимости от того, какое имя области мы будем использовать в программе —mas_bилиmas_w.

4. Использование цикла для инициализации значениями области памяти, которую можно будет впоследствии трактовать как массив.

5. Посмотрим на примере листинга 2, каким образом это делается.

Листинг 2 Инициализация массива в цикле

mes db 0ah,0dh,'Массив- ','$'

mas db 10 dup (?) ;исходный массив

xor ax,ax ;обнуление ax

mov cx,10 ;значение счетчика цикла в cx

mov si,0 ;индекс начального элемента в cx

go: ;цикл инициализации

mov mas[si],bh ;запись в массив i

inc i ;инкремент i

inc si ;продвижение к следующему элементу массива

loop go ;повторить цикл

;вывод на экран получившегося массива

mov ah,02h ;функция вывода значения из al на экран

add dl,30h ;преобразование числа в символ

mov ax,4c00h ;стандартный выход

end main ;конец программы

При работе с массивами необходимо четко представлять себе, что все элементы массива располагаются в памяти компьютера последовательно.

Само по себе такое расположение ничего не говорит о назначении и порядке использования этих элементов. И только лишь программист с помощью составленного им алгоритма обработки определяет, как нужно трактовать эту последовательность байт, составляющих массив. Так, одну и ту же область памяти можно трактовать как одномерный массив, и одновременно те же самые данные могут трактоваться как двухмерный массив. Все зависит только от алгоритма обработки этих данных в конкретной программе. Сами по себе данные не несут никакой информации о своем “смысловом”, или логическом, типе. Помните об этом принципиальном моменте.

Эти же соображения можно распространить и на индексы элементов массива. Ассемблер не подозревает об их существовании и ему абсолютно все равно, каковы их численные смысловые значения.

Для того чтобы локализовать определенный элемент массива, к его имени нужно добавить индекс. Так как мы моделируем массив, то должны позаботиться и о моделировании индекса. В языке ассемблера индексы массивов — это обычные адреса, но с ними работают особым образом. Другими словами, когда при программировании на ассемблере мы говорим об индексе, то скорее подразумеваем под этим не номер элемента в массиве, а некоторый адрес.

Давайте еще раз обратимся к описанию массива. К примеру, в программе статически определена последовательность данных:

Пусть эта последовательность чисел трактуется как одномерный массив. Размерность каждого элемента определяется директивой dw, то есть она равна2байта. Чтобы получить доступ к третьему элементу, нужно к адресу массива прибавить6. Нумерация элементов массива в ассемблере начинается с нуля.

То есть в нашем случае речь, фактически, идет о 4-м элементе массива — 3, но об этом знает только программист; микропроцессору в данном случае все равно — ему нужен только адрес.

В общем случае для получения адреса элемента в массиве необходимо начальный (базовый) адрес массива сложить с произведением индекса (номер элемента минус единица) этого элемента на размер элемента массива:

база + (индекс*размер элемента)

Архитектура микропроцессора предоставляет достаточно удобные программно-аппаратные средства для работы с массивами. К ним относятся базовые и индексные регистры, позволяющие реализовать несколько режимов адресации данных. Используя данные режимы адресации, можно организовать эффективную работу с массивами в памяти. Вспомним эти режимы:

· индексная адресация со смещением — режим адресации, при котором эффективный адрес формируется из двух компонентов:

o постоянного (базового)— указанием прямого адреса массива в виде имени идентификатора, обозначающего начало массива;

o переменного (индексного)— указанием имени индексного регистра.

;поместить 3-й элемент массива mas в регистр ax:

· базовая индексная адресация со смещением — режим адресации, при котором эффективный адрес формируется максимум из трех компонентов:

o постоянного(необязательный компонент), в качестве которой может выступать прямой адрес массива в виде имени идентификатора, обозначающего начало массива, или непосредственное значение;

o переменного (базового)— указанием имени базового регистра;

o переменного (индексного)— указанием имени индексного регистра.

Этот вид адресации удобно использовать при обработке двухмерных массивов. Пример использования этой адресации мы рассмотрим далее при изучении особенностей работы с двухмерными массивами.

Напомним, что в качестве базового регистра может использоваться любой из восьми регистров общего назначения. В качестве индексного регистра также можно использовать любой регистр общего назначения, за исключением esp/sp.

Микропроцессор позволяет масштабировать индекс. Это означает, что если указать после имени индексного регистра знак умножения “*” с последующей цифрой 2, 4 или 8, то содержимое индексного регистра будет умножаться на 2, 4 или 8, то есть масштабироваться.

Применение масштабирования облегчает работу с массивами, которые имеют размер элементов, равный 2, 4 или 8 байт, так как микропроцессор сам производит коррекцию индекса для получения адреса очередного элемента массива. Нам нужно лишь загрузить в индексный регистр значение требуемого индекса (считая от 0). Кстати сказать, возможность масштабирования появилась в микропроцессорах Intel, начиная с модели i486. По этой причине в рассматриваемом здесь примере программы стоит директива .486. Ее назначение, как и ранее использовавшейся директивы.386, в том, чтобы указать ассемблеру при формировании машинных команд на необходимость учета и использования дополнительных возможностей системы команд новых моделей микропроцессоров.

Листинг 3. Просмотр массива слов с использованием

.data ;начало сегмента данных

mes1 db 'не равен 0!$',0ah,0dh

mes2 db 'равен 0!$',0ah,0dh

mes3 db 0ah,0dh,'Элемент $'

mas dw 2,7,0,0,1,9,3,6,0,8 ;исходный массив

.486 ;это обязательно

mov ds,ax ;связка ds с сегментом данных

xor ax,ax ;обнуление ax

mov cx,10 ;значение счетчика цикла в cx

mov esi,0 ;индекс в esi

mov dx,mas[esi*2] ;первый элемент массива в dx

cmp dx,0 ;сравнение dx c 0

je equal ;переход, если равно

not_equal: ;не равно

mov ah,02h ;вывод номера элемента массива на экран

inc esi ;на следующий элемент

dec cx ;условие для выхода из цикла

jcxz exit ;cx=0? Если да — на выход

jmp compare ;нет — повторить цикл

inc esi ;на следующий элемент

dec cx ;все элементы обработаны?

mov ax,4c00h ;стандартный выход

end main ;конец программы

Еще несколько слов о соглашениях:

· Если для описания адреса используется только один регистр, то речь идет о базовой адресациии этот регистр рассматривается какбазовый:

;переслать байт из области данных, адрес

которой находится в регистре ebx:

· Если для задания адреса в команде используется прямая адресация(в виде идентификатора) в сочетании с одним регистром, то речь идет обиндексной адресации. Регистр считаетсяиндексным, и поэтому можно использовать масштабирование для получения адреса нужного элемента массива:

;сложить содержимое eax с двойным словом в памяти

;по адресу mas + (ebx)*4

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

· Помните, что применение регистров ebp/bpиesp/spпо умолчанию подразумевает, что сегментная составляющая адреса находится в регистреss.

Заметим, что базово-индексную адресацию не возбраняется сочетать с прямой адресацией или указанием непосредственного значения. Адрес тогда будет формироваться как сумма всех компонентов.

;адрес операнда равен [mas+(ebx)+(ecx)*2]

;адрес операнда равен [(ebx)+8+(ecx)*4]

Но имейте в виду, что масштабирование эффективно лишь тогда, когда размерность элементов массива равна 2, 4 или 8 байт. Если же размерность элементов другая, то организовывать обращение к элементам массива нужно обычным способом, как описано ранее.

Рассмотрим пример работы с массивом из пяти трехбайтовых элементов (листинг 4). Младший байт в каждом из этих элементов представляет собой некий счетчик, а старшие два байта — что-то еще, для нас не имеющее никакого значения. Необходимо последовательно обработать элементы данного массива, увеличив значения счетчиков на единицу.

Массив располагается в памяти последовательно, элемент за элементом. Сначала лежит нулевой, потом первый и т.д. Элементы располагаются по возрастанию адреса: Один элемент массива отстоит от другого на количество байт, равное базовому типу массива. Формула, по которой производится позиционирование по массиву:

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

Каждый элемента массива имеет свою собственную размерность, которая напрямую зависит от типа всего массива. Например, если массив имеет тип данных int - размер каждого элемента в нем - 4 байта. Таким образом, общий размер всего массива вычисляется по формуле:

Для начала, нам необходимо научиться создавать массив. А, для этого - во-первых, определить общий синтаксис. Во-вторых, выяснить, каким правилам и ограничениям этот синтаксис подчиняется.

тип_данных - любой из существующих, известных вам типов данных. Именно этим типом будет обладать каждый элемент массива. имя_массива - любое имя, которое подчиняется "правилам имен переменных" (эти правила мы рассматривали с Вами в первом уроке). количество_элементов - число элементов в массиве. На данном месте должно находиться - целочисленное константное значение. Таким значением может быть - либо целочисленный литерал, либо константная целочисленная переменная. Обратите внимания, что количество элементов массива должно быть определенно на этапе создания программы. Другими словами, задать размерность такого массива в зависимости от какого-то условия или по решению пользователя невозможно. Это приведет к ошибке на этапе компиляции. Вариант первый: Объявлен массив ar, состоящий из 5 элементов, каждый из которых имеет тип данных int. Вариант второй: Объявлена константа size, значение которой равно 3, а затем, массив br, состоящий из 3 элементов, каждый из которых имеет тип данных double. Мы рекомендуем вам использовать вторую форму записи, так как она является более корректной и удобной.

Рассмотрим, как обратиться к конкретному элементу массива. Запись значения:

Здесь, на место индекса_элемента может быть подставлено ЛЮБОЕ целочисленное значение, в том числе выражение, результатом которого является целое число.

Еще раз напоминаем - нумерация элементов в массиве начинается с нуля. Таким образом в массиве из 5 элементов - последний элемент имеет индекс 4. Выходить за пределы массива нельзя, это приведет к ошибке на этапе выполнения.

Заполнить массив данными можно двумя способами:

При такой форме инициализации есть некоторые особенности:

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

Одномерный массив - массив данных, где каждое значение обладает только одной характеристикой - порядковым номером (индексом). Именно по этому индексу мы и обращаемся к конкретному элементу.

Сегодня мы поговорим о многомерных массивах, т. е. о массивах, где каждый элемент описывается несколькими характеристиками.

Двумерный массив представляет собой совокупность строк и столбцов, на пересечении которых находится конкретное значение. Объявить двумерный массив несложно, необходимо указать количество строк и столбцов. При этом, здесь действуют все теже правила, что и при объявлении одномерного массива. Т. е. нельзя в качестве количества строк и столбцов указывать неконстантные и нецелочисленные значения.

Первый элемент имеет порядковый номер 0. Важно понимать, почему. В дальнейшем будем представлять память компьютера в виде ленты. Имя массива - это указатель на адрес памяти, где располагаются элементы массива.

Массив хранит адрес первого элемента. Индекс i элемента - это сдвиг на i*sizeof(тип) байт от начала

Рис. 1 Массив хранит адрес первого элемента. Индекс i элемента - это сдвиг на i*sizeof(тип) байт от начала

Индекс массива указывает, на сколько байт необходимо сместиться относительно начала массива, чтобы получить доступ до нужно элемента. Например, если массив A имеет тип int, то A[10] означает, что мы сместились на 10*sizeof(int) байт относительно начала. Первый элемент находится в самом начале и у него смещение 0*sizeof(int) .
В си массив не хранит своего размера и не проверяет индекс массива на корректность. Это значит, что можно выйти за пределы массива и обратиться к памяти, находящейся дальше последнего элемента массива (или ближе).

Начальная инициализация массива.

Н апишем простую программу. Создадим массив, после чего найдём его максимальный элемент.

Разберём пример. Сначала мы создаём массив и инициализируем его при создании. После этого присваиваем максимальному найденному элементу значение первого элемента массива.

После чего проходим по массиву. Так как мы уже просмотрели первый элемент (у него индекс 1), то нет смысла снова его просматривать.
Тот же пример, только теперь пользователь вводит значения

В том случае, если при инициализации указано меньше значений, чем размер массива, остальные элементы заполняются нулями.

Если необходимо заполнить весь массив нулями, тогда пишем

Можно не задавать размер массива явно, например

массив будет иметь размер 3

Размер массива

М ассив в си должен иметь константный размер. Это значит, что невозможно, например, запросить у пользователя размер, а потом задать этот размер массиву.

Создание динамических массивов будет рассмотрено дальше, при работе с указателями и памятью
В некоторых случаях можно узнать размер массива с помощью функции sizeof.

Но это вряд ли будет полезным. При передаче массива в качестве аргумента функции будет передаваться указатель, поэтому размер массива будет невозможно узнать.
Статические массивы удобны, когда заранее известно число элементов. Они предоставляют быстрый, но небезопасный доступ до элементов.

Переполнение массива

П ускай у вас есть такой код

  • 1. Используйте тип size_t для индексирования. Он обезопасит вас от отрицательных значений и его всегда хватит для массива любого размера.
  • 2. Помните, что массив начинается с нуля.
  • 3. Последний элемент массива имеет индекс (размер массива - 1)

Примеры

Т еперь несколько типичных примеров работы с массивами
1. Переворачиваем массив.

Здесь незнакомая для вас конструкция

макрос. Во всём коде препроцессор автоматически заменит все вхождения SIZE на 10u.
2. Удаление элемента, выбранного пользователем.

Удаление элемента в данном случае, конечно, не происходит. Массив остаётся того же размера, что и раньше. Мы просто затираем удаляемый элемент следующим за ним и выводим SIZE-1 элементов.
3. Пользователь вводит значения в массив. После этого вывести все разные значения, которые он ввёл.
Пусть пользователь вводит конечное число элементов, допустим 10. Тогда заранее известно, что всего различных значений будет не более 10. Каждый раз, когда пользователь вводит число будем проходить по массиву и проверять, было ли такое число введено.

4. Пользователь вводит число - количество измерений (от 2 до 10). После этого вводит все измерения. Программа выдаёт среднее значение, дисперсию, погрешность.

5. Сортировка массива пузырьком

6. Перемешаем массив. Воспользуемся для этого алгоритмом Fisher-Yates:
Для i от N-1 до 1 выбираем случайное число j в пределах от 0 до i и меняем местами i-й и j-й элементы.

email

Всё ещё не понятно? – пиши вопросы на ящик

Читайте также: