Опубликован: 14.12.2010 | Доступ: свободный | Студентов: 3137 / 738 | Оценка: 4.53 / 4.12 | Длительность: 26:28:00
Лекция 6:

Числовые массивы в языке программирования С

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >
Аннотация: В лекции надлежит изучить определение и инициализацию числовых массивов в языке программирования С. Освоить программные решения типовых примеров с многомерными числовыми массивами.

Теоретическая часть

В языке программирования С заложены средства для задания последовательностей упорядоченных данных [5.1]. Такие последовательности называются массивами. В массивах должны быть упорядочены данные одного и того же типа. В данной лабораторной работе будут рассматриваться массивы с целыми и вещественными типами данных, т.е. типы int, float или double.

Массивы данных могут быть одномерными (векторами размера 1 \times n или n \times 1), двухмерными (матрицами размера n \times m) или многомерными (размера n \times m \times p...). В частности, для векторов и матриц в приведенной записи первый индекс означает количество строк, а второй (число или буква) – это количество столбцов. Для названия массива может быть использована переменная, состоящая из букв (буквы), букв с цифрами, букв с цифрами и знаком подчеркивания и т.д. в соответствии с правилами объявления переменных, принятых в языке С. Если размерность массива меньше, чем требуется, то компилятор не выдаст сообщения об ошибке. Выход за границы массивов должен следить только сам программист.

5.1. Одномерные массивы

Одномерный массив – это список связанных однотипных переменных.

Общая форма записи одномерного массива [5.2]:

тип  имя_массива[размер];

В приведенной записи элемент тип объявляет базовый тип массива. Количество элементов, которые будут храниться в массиве с именем имя_массива, определяется элементом размер.

В языке С индексация массива начинается с нуля. Например, если размер массива определен величиной 9, то в массиве можно хранить 10 элементов с индексацией 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

Доступ к отдельному элементу массива осуществляется с помощью индекса. Индекс описывает позицию элемента внутри массива.

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

Для одномерных массивов общий размер массива в байтах вычисляется по формуле:

всего байт = размер типа в байтах * количество элементов

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

5.2. Двухмерные массивы, матрицы

Двухмерный массив представляет собой список одномерных массивов.

Общая форма записи двухмерного массива:

тип  имя_массива[размер1] [размер2];

В приведенной записи размер1 означает количество строк двухмерного массива, а размер2 – количество столбцов.

В двухмерном массиве позиция любого элемента определяется двумя индексами. Индексы каждого из размеров массива начинаются с 0 (с нуля).

Место хранения для всех элементов массива определяется во время компиляции. Память, выделенная для хранения массива, используется в течение всего времени существования массива.

Для двухмерных массивов общий размер массива в байтах вычисляется по формуле:

всего байт = число строк * число столбцов * размер типа в байтах

5.3. Многомерные массивы

Общая форма записи многомерного массива:

тип  имя_массива[размер1] [размер2]... [размерN];

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

При обращении к многомерным массивам компьютер много времени затрачивает на вычисление адреса, так как при этом приходится учитывать значение каждого индекса [5.2]. Следовательно, доступ к элементам многомерного массива происходит значительно медленнее, чем к элементам одномерного. В этой связи использование многомерных массивов встречается значительно реже, чем одномерных или двухмерных массивов.

Для многомерных массивов общий размер многомерного массива в байтах вычисляется по формуле:

всего байт = размер1* размер2*...* размерN *размер типа в байтах

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

Для определения размера типа в байтах применяется функция sizeof(), которая возвращает целое число. Например, sizeof(float).

5.4. Инициализация массивов

В языке С массивы при объявлении можно инициализировать [5.2].

Общая форма инициализации массива:

тип  имя_массива[размер1] * [размерN] = {список_значений};

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

Пример инициализации одномерного массива:

int A[5] = {1, 2, 3, 4, 5};

При этом A[0] = 1, A[1] = 2 и т.д.

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

Пример инициализации двухмерного массива:

int  MN[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

Массив MN[3][4] – это матрица, у которой 3 строки и 4 столбца.

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

Пример инициализации трехмерного массива:

int  XYZ[2][3][4] = {
{ {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} },
{ {13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24} }
};

Как видно, массив XYZ содержит два блока, каждый из которых есть матрица размера 3 \times 4, т.е. 3 строки и 4 столбца.

В языке С возможна инициализация безразмерных массивов. Например, для одномерного массива:

int A[ ] = {1, 2, 3, 4, 5};

В многомерном массиве размер самого левого измерения также можно не указывать. В частности, для инициализации массива MN[3][4] допустима следующая запись:

int  MN[][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

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

int  XYZ[][3][4] = {
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
},
{
{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24}
}
};

Вывод трехмерного массива на консоль (дисплей) можно выполнить по следующей программе:

#include <stdio.h>
#include <conio.h>

int main (void) {
	int i, j, k;
	int  XYZ[][3][4] = {
{ {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }, // 1-й 
{ {13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24} } }; // 2-й 
	for (i = 0; i < 2; ++i) { printf("\n");
		for (j = 0; j < 3; ++j) { printf("\n");
			for (k = 0; k < 4; ++k)
				printf(" %3d", XYZ[i][j][k]);
		}
	}
	printf("\n\n Press any key: ");
	_getch();
	return 0;
 }

Практическая часть

Пример 1. Напишите программу заполнения одномерного массива случайными числами из интервала от 1 до 15 по случайному равномерному закону. Отсортировать массив случайных чисел по возрастанию.

Для решения поставленной задачи применим сортировку методом прямого выбора [5.3]. Алгоритм сортировки заключается в следующем:

  1. В исходной последовательности из N элементов отыскивается элемент с наименьшим ключом.
  2. Он меняется местами с первым элементом.
  3. В оставшейся последовательности из ( N –1) элементов отыскивается минимальный элемент и меняется местами со вторым элементом и т.д., пока не останется один, самый большой элемент.

Программный код решения примера:

#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#define Left 1
#define Right 15
#define N 10

int main (void) {
float R, r, min;
float A[N];

int i, j, k;	
unsigned int some;
long int L;

L = (long) time(NULL); // Системное время
some = (unsigned) L; // Приведение типов
srand(some); // Задание исходного случайного числа для rand()
printf("\n\t The initial array of random numbers in the interval [%d, %2d]\n", Left, Right);

for (i = 0; i < N; ++i)
{// Случайное число из интервала [0,1]
r = (float) rand()/RAND_MAX;
// Формирование случайного числа из заданного интервала
R = Left + (Right - Left) * r;
// Заполнение массива случайными числами
A[i] = R; }

// Печать элементов исходного массива
for (i = 0; i < N; ++i)
printf("\n\t %5d) %10.4f", i + 1, A[i]);

// Сортировка методом выбора
for (i = 0; i < (N - 1); ++i)
 {
 min = A[i]; k = i;
for (j = i + 1; j < N; ++j)
if (A[j] < min) { k = j; min = A[k]; }
A[k] = A[i]; A[i] = min;
}

// Печать отсортированного массива по возрастанию
printf("\n\n\t Sort an array:\n");
for (i = 0; i < N; ++i)
printf("\n\t %5d) %10.4f", i + 1, A[i]);

	printf("\n\n Press any key: ");
	_getch();
	return 0;
}

Возможный результат выполнения программы показан на рис. 5.1.

Сортировка одномерного массива по возрастанию

Рис. 5.1. Сортировка одномерного массива по возрастанию

В программе использованы директивы препроцессора для задания левой границы ( #define Left 1 ), правой границы ( #define Right 15 ) и размера одномерного массива ( #define N 10 ). Включены дополнительные библиотеки time.h – для обращения к функциям системного времени, stdlib.h – для обращения к функциям генерации псевдослучайных чисел.

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >
Мухаммадюсуф Курбонов
Мухаммадюсуф Курбонов