- Массивы
- Массивы
- Начальная инициализация массива.
- Размер массива
- Переполнение массива
- Примеры
- Pascal: Занятие № 5. Одномерные массивы в Паскале
- Одномерные массивы в Паскале
- Объявление массива
- Инициализация массива
- Вывод элементов массива
- Функция Random в Pascal
- Числа Фибоначчи в Паскале
- Максимальный (минимальный) элемент массива
- Поиск в массиве
- Циклический сдвиг
- Перестановка элементов в массиве
- Выбор элементов и сохранение в другой массив
- Сортировка элементов массива
- admin
- Bronislav
- Владимир
- Aurangzeb
Массивы
Массивы
П усть нам необходимо работать с большим количеством однотипных данных. Например, у нас есть тысяча измерений координаты маятника с каким-то шагом по времени. Создавать 1000 переменных для хранения всех значений очень. обременительно. Вместо этого множество однотипных данных можно объединить под одним именем и обращаться к каждому конкретному элементу по его порядковому номеру.
Массив в си определяется следующим образом
[ ];
Например,
int a[100];
Мы получим массив с именем a, который содержит сто элементов типа int. Как и в случае с переменными, массив содержит мусор.
Для получения доступа до первого элемента, в квадратных скобках пишем его номер (индекс). Например
Первый элемент имеет порядковый номер 0. Важно понимать, почему. В дальнейшем будем представлять память компьютера в виде ленты. Имя массива — это указатель на адрес памяти, где располагаются элементы массива.
Рис. 1 Массив хранит адрес первого элемента. Индекс i элемента — это сдвиг на i*sizeof(тип) байт от начала
Индекс массива указывает, на сколько байт необходимо сместиться относительно начала массива, чтобы получить доступ до нужно элемента. Например, если массив A имеет тип int, то A[10] означает, что мы сместились на 10*sizeof(int) байт относительно начала. Первый элемент находится в самом начале и у него смещение 0*sizeof(int) .
В си массив не хранит своего размера и не проверяет индекс массива на корректность. Это значит, что можно выйти за пределы массива и обратиться к памяти, находящейся дальше последнего элемента массива (или ближе).
Начальная инициализация массива.
Н апишем простую программу. Создадим массив, после чего найдём его максимальный элемент.
Разберём пример. Сначала мы создаём массив и инициализируем его при создании. После этого присваиваем максимальному найденному элементу значение первого элемента массива.
После чего проходим по массиву. Так как мы уже просмотрели первый элемент (у него индекс 1), то нет смысла снова его просматривать.
Тот же пример, только теперь пользователь вводит значения
В том случае, если при инициализации указано меньше значений, чем размер массива, остальные элементы заполняются нулями.
Если необходимо заполнить весь массив нулями, тогда пишем
Можно не задавать размер массива явно, например
массив будет иметь размер 3
Размер массива
М ассив в си должен иметь константный размер. Это значит, что невозможно, например, запросить у пользователя размер, а потом задать этот размер массиву.
Создание динамических массивов будет рассмотрено дальше, при работе с указателями и памятью
В некоторых случаях можно узнать размер массива с помощью функции sizeof.
Но это вряд ли будет полезным. При передаче массива в качестве аргумента функции будет передаваться указатель, поэтому размер массива будет невозможно узнать.
Статические массивы удобны, когда заранее известно число элементов. Они предоставляют быстрый, но небезопасный доступ до элементов.
Переполнение массива
П ускай у вас есть такой код
Здесь цикл for задан с ошибкой. В некоторых старых версиях компиляторов этот код зацикливался. Дело в том, что переменная i располагалась при компиляции сразу за массивом A. При выходе за границы массива счётчик переводился в 1.
Массивы небезопасны, так как неправильная работа с индексом может приводить к доступу к произвольному участку памяти (Теоретически. Современные компиляторы сами заботятся о том, чтобы вы не копались в чужой памяти).
Если вы работаете с массивами, то необходимо следить за тем, чтобы счётчик не превышал размер массива и не был отрицательным. Для этого, как минимум,
- 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-й элементы.
Источник
Pascal: Занятие № 5. Одномерные массивы в Паскале
Одномерные массивы в Паскале
Объявление массива
Массивы в Паскале используются двух типов: одномерные и двумерные.
Определение одномерного массива в Паскале звучит так: одномерный массив — это определенное количество элементов, относящихся к одному и тому же типу данных, которые имеют одно имя, и каждый элемент имеет свой индекс — порядковый номер.
Описание массива в Паскале (объявление) и обращение к его элементам происходит следующим образом:
var dlina: array [1..3] of integer; begin dlina[1]:=500; dlina[2]:=400; dlina[3]:=150; .
Объявить размер можно через константу:
Инициализация массива
Кроме того, массив может быть сам константным, т.е. все его элементы в программе заранее определены. Описание такого массива выглядит следующим образом:
const a:array[1..4] of integer = (1, 3, 2, 5);
Заполнение последовательными числами:
var a: array of integer; var n:=readInteger; a:=new integer[n];
var a: array of integer; var n:=readInteger; SetLength(a,n); // устанавливаем размер
begin var a: array of integer; a := new integer[3]; a[0] := 5; a[1] := 2; a[2] := 3; end.
или в одну строку:
begin var a: array of integer; a := new integer[3](5,2,3); print(a) end.
Ввод с клавиатуры:
writeln (‘введите кол-во элементов: ‘); readln(n); <если кол-во заранее не известно, - запрашиваем его>for i := 1 to n do begin write(‘a[‘, i, ‘]=’); read(a[i]); . end; .
✍ Пример результата:
var a:=ReadArrInteger(5); // целые var a:=ReadArrReal(5); // вещественные
Вывод элементов массива
var a: array[1..5] of integer; <массив из пяти элементов>i: integer; begin a[1]:=2; a[2]:=4; a[3]:=8; a[4]:=6; a[5]:=3; writeln(‘Массив A:’); for i := 1 to 5 do write(a[i]:2); <вывод элементов массива>end.
Для работы с массивами чаще всего используется в Паскале цикл for с параметром, так как обычно известно, сколько элементов в массиве, и можно использовать счетчик цикла в качестве индексов элементов.
[Название файла: taskArray0.pas ]
В данном примере работы с одномерным массивом есть явное неудобство: присваивание значений элементам.
for var i:=0 to a.Length-1 do a[i] += 1;
Проход по элементам (только для чтения):
Пример:
foreach var x in a do Print(x)
Функция Random в Pascal
Для того чтобы постоянно не запрашивать значения элементов массива используется генератор случайных чисел в Паскаль, который реализуется функцией Random . На самом деле генерируются псевдослучайные числа, но суть не в этом.
Диапазон в Паскале тех самых случайных чисел от a до b задается формулой:
var f: array[1..10] of integer; i:integer; begin randomize; for i:=1 to 10 do begin f[i]:=random(10); < интервал [0,9] >write(f[i],’ ‘); end; end.
Для вещественных чисел в интервале [0,1]:
var x: real; . x := random(0.0,1.0);;
или с дополнительными параметрами (диапазон [5;15]):
[Название файла: taskArray1.pas ]
Числа Фибоначчи в Паскале
Наиболее распространенным примером работы с массивом является вывод ряда чисел Фибоначчи в Паскаль. Рассмотрим его.
Получили формулу элементов ряда.
var i:integer; f:array[0..19]of integer; begin f[0]:=1; f[1]:=1; for i:=2 to 19 do begin f[i]:=f[i-1]+f[i-2]; writeln(f[i]) end; end.
На данном примере, становится понятен принцип работы с числовыми рядами. Обычно, для вывода числового ряда находится формула определения каждого элемента данного ряда. Так, в случае с числами Фибоначчи, эта формула-правило выглядит как f[i]:=f[i-1]+f[i-2] . Поэтому ее необходимо использовать в цикле for при формировании элементов массива.
[Название файла: taskArray2.pas ]
Максимальный (минимальный) элемент массива
Псевдокод:
Поиск максимального элемента по его индексу:
// … var (min, minind) := (a[0], 0); for var i:=1 to a.Length-1 do if a[i]
[Название файла: taskArray_min.pas ]
[Название файла: taskArray4.pas ]
[Название файла: taskArray5.pas ]
[Название файла: taskArray6.pas ]
Пример:
[Название файла: taskArray7.pas ]
Поиск в массиве
Рассмотрим сложный пример работы с одномерными массивами:
Для решения поставленной задачи понадобится оператор break — выход из цикла.
Решение Вариант 1. Цикл for:
var f: array[1..10] of integer; flag:boolean; i,c:integer; begin randomize; for i:=1 to 10 do begin f[i]:=random(10); write(f[i],’ ‘); end; flag:=false; writeln(‘введите образец’); readln(c); for i:=1 to 10 do if f[i]=c then begin writeln(‘найден’); flag:=true; break; end; if flag=false then writeln(‘не найден’); end.
begin var a := new integer[10]; a := arrRandomInteger(5,0,5); //[1,3,5,4,5] print(a.IndexOf(3)) // 1 end.
или метод a.Contains(x) наравне с x in a :
begin var a := new integer[10]; a := arrRandomInteger(5,0,5); //[1,3,5,4,5] print(a.Contains(3)); // True print(3 in a)// True end.
Рассмотрим эффективное решение:
Задача: найти в массиве элемент, равный X , или установить, что его нет.
Алгоритм:
- начать с 1-го элемента ( i:=1 );
- если очередной элемент ( A[i] ) равен X , то закончить поиск иначе перейти к следующему элементу.
решение на Паскале Вариант 2. Цикл While:
Поиск элемента в массиве
Предлагаем посмотреть подробный видео разбор поиска элемента в массиве (эффективный алгоритм):
Пример:
[Название файла: taskArray8.pas ]
Циклический сдвиг
Решение:
Программа:
// … var v := a[0]; for var i:=0 to a.Length-2 do a[i] := a[i+1]; a[a.Length-1] := v;
// … var v := a[a.Length-1]; for var i:=a.Length-1 downto 1 do a[i] := a[i-1]; a[0] := v;
[Название файла: taskArray9.pas ]
Перестановка элементов в массиве
Рассмотрим, как происходит перестановка или реверс массива.
Решение:
Псевдокод:
Программа:
begin var a: array of integer := (1,3,5,7); var n := a.Length; for var i:=0 to n div 2 — 1 do Swap(a[i],a[n-i-1]); End.
Решение 2 (стандартная процедура Reverse() ):
begin var a:=new integer[10]; a:=arrRandomInteger(10); print(a);// [41,81,84,63,12,26,88,25,36,72] Reverse(a); print(a) //[72,36,25,88,26,12,63,84,81,41] end.
[Название файла: taskArray10.pas ]
Выбор элементов и сохранение в другой массив
Решение:
Вывод массива B:
writeln(‘Выбранные элементы’); for i:=1 to count-1 do write(B[i], ‘ ‘)
// . for var i := 0 to a.length — 1 do if a[i]
[Название файла: taskArray11.pas ]
Сортировка элементов массива
- В таком типе сортировок массив представляется в виде воды, маленькие элементы — пузырьки в воде, которые всплывают наверх (самые легкие).
- При первой итерации цикла элементы массива попарно сравниваются между собой:предпоследний с последним, пред предпоследний с предпоследним и т.д. Если предшествующий элемент оказывается больше последующего, то производится их обмен.
- При второй итерации цикла нет надобности сравнивать последний элемент с предпоследним. Последний элемент уже стоит на своем месте, он самый большой. Значит, число сравнений будет на одно меньше. То же самое касается каждой последующей итерации.
Pascal | PascalABC.NET |
Pascal | PascalABC.NET |