Лабораторная работа №6
Одномерный массив
Массив – это линейная, однородная структура данных, состоящая из конечного числа элементов. Доступ к элементу массива прямой по индексу.
Статический массив
Статический массив – это структура данных, которая создается во время компиляции (т.е. массиву выделяется память). Размер массива нельзя изменять во время работы программы.
Формат определения одномерного статического массива
[КП] спецификатор базового типа массива Имя массива [количество элементов]
Где:
Количество элементов – константа или макроопределение
Примеры объявления массива
#define Len 100
float z[len];
int main()
{
int x[100];
double y[Len];
}
Спецификатор базового типа массива – это любой простой тип языка Си, включая указатель.
Представление в памяти массива из Len элементов
∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙ | ||||
Len-1 |
Для всех элементов массива общим является имя, но у каждого элемента массива уникальным является индекс.
|
|
Имя массива это константный указатель. Он хранит адрес первого байта области памяти, выделенной под элементы массива. Это можно представить так:
Y
∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙ | |||||
Len-1 |
Объем памяти выделенной переменной можно рассчитать по формуле Len*объем одного элемента.
Доступ к элементу массива осуществляется по имени. Имя элемента массива формируется по следующему правилу:
имя массива [индекс элемента]
Каждый элемент занимает в памяти отдельную ячейку памяти. Ячейка памяти выделяется переменной, т.о. элемент массива – это отдельная переменная в составе массива.
Операции можно выполнять только над элементом массива, допустимые базовым типом массива.
Пример заполнения массива с переменной верхней границей при инициализации и с клавиатуры
int main()
{ int i,y[4]={5, 6, 7,8}; //инициализация массива
// вывод массива
for(i=0;i<4;i++)
{
printf(“%d ”, x[i]);
}
int x[Len], n;
printf(“ Введите количество обрабатываемых элементов массива”);
scanf(“%d”,&n);
if(n>0 && n<Len)
{ printf(“Введите %d чисел”);
for(i=0;i<n;i++)
{
scanf(“%d”, x[i]);
}
}
else
printf(“ n должно быть больше нуля”);
}
Пример заполнения статического массива датчиком случайных чисел из диапазона от 100 до 300.
Примечание.
1)Функция rand() генерирует числа в диапазоне от 0 до RAND_MAX. RAND_MAX— это константа, определённая в библиотеке cstdlib.h. Для MVS RAND_MAX= 32767,но оно может быть и больше, в зависимости от компилятора.
2) Формула генерации случайных чисел по заданному диапазону
random_number = firs_value + rand() % last_value;
где firs_value - минимальное число из желаемого диапазона
|
|
last_value - ширина выборки
3) Чтобы при различных запусках программы датчик формировал новое значение, необходимо настроить функцию rand(), передав ей новое начальное значение для алгоритма формирования случайного числа. Для этого надо в программу включить вызов функции srand(time(0)); из time.h. до вызова функции rand().
#include “stdio.h”
#include "stdlib.h"
#include "time.h"
int main()
{
int x[Len], n;
printf(“ Введите количество обрабатываемых элементов массива”);
scanf(“%d”,&n);
if(n>0 && n<Len)
{ srand(time(0));
for(i=0;i<n;i++)
{x[i]=100+rand()%300;
}
}
else
printf(“ n должно быть больше нуля”);
}
}
Динамический массив
Динамический массив – это структура данных, которая создается во время выполнения программы. В процессе работы программы размер массива может быть изменен.
Примечание. Как же писать код программы и обращаться к ячейкам массива, если он еще не создан, т.е. не переменной и соответственно память не выделена? Для этого в программе разработан тип данных – указатель. Это переменная, значением которой может быть адрес.
Динамический массив в языке Си определяется через указатель. Количество элементов в массиве может быть определено перед созданием массива.
Индексация элементов динамического массива начинается с нуля.
Функции языка Си по управлению динамическим массивом из модуля malloc.h:
1) Выделение памяти под переменную в динамической памяти (создание динамической переменной)
void* malloc(выражение);
Выражение определяет объем памяти в байтах.
Функция запрашивает у диспетчера динамической памяти (ДП) необходимое количество последовательно расположенных байтов, заданное выражением, если такой участок есть, то результат функции – адрес первого байта выделенной области, если такого свободного объема нет, то результат функции NULL.
Так как результат функции не типизированный указатель, то результат нужно привести к базовому типу массива (или типу переменной, под которую выделяется память).
Пример создания динамического массива
int mai()
{
int n;
cout<<”Введите количество элементов массива”;
int *x=(int *)malloc(n);
double *y=(double *)malloc(n);
}
2) Удаление динамического массива
После того, как необходимость в динамическом массиве в приложении отпала, его надо из ДП удалить, так как она автоматически не освобождается от использованных переменных, иначе эта память считается занятой и новым переменным может не хватить свободной памяти.
void free(указатель на динамическую память);
Пример удаления динамического массива после использования
int mai()
{
int n;
cout<<”Введите количество элементов массива”;
int *x=(int *)malloc(n);
double *y=(double *)malloc(n);
for(i=0;i<n;i++)
cin>>x[i];
for(i=0;i<n;i++)
cout<<x[i];
free(x);
}
3) Изменение размера динамического массива
void* realloc(указатель, выражение);
где
указатель – это указатель на массив, размер которого надо изменить;
выражение – определяет новый размер массива в байтах.
Функция изменяет размер массива, добавляя новые байты в конец массива или удаляя последнее байты, сохраняя при этом значения остальных элементов массива.
Пример применения realloc для величения и уменьшения размера массива
int main()
{
int n=5;
int *x=(int *) malloc(n);
x[0]=1; x[1]=2;x[2]=3; x[3]=4; x[4]=5;
//увеличить массив на один элемент
realloc(x,sizeof(int)*(n+1)); n++;
x[5]=6;
//увеличить массив на два элемента
realloc(x,sizeof(int)*(n+2));
x[6]=7; x[7]=8;
//уменьшить массив на один элемент
n--;
realloc(x,sizeof(int)*n);
free(x);
}