В языке программирования С заложены средства для задания последовательностей упорядоченных данных [5.1]. Такие последовательности называются массивами. В массивах должны быть упорядочены данные одного и того же типа. В данной лабораторной работе будут рассматриваться массивы с целыми и вещественными типами данных, т.е. типы int, float или double.
Массивы данных могут быть одномерными (векторами размера 1 $$\times$$ n или n $$\times$$ 1), двухмерными (матрицами размера n $$\times$$ m) или многомерными (размера n $$\times$$ m $$\times$$ p...). В частности, для векторов и матриц в приведенной записи первый индекс означает количество строк, а второй (число или буква) – это количество столбцов. Для названия массива может быть использована переменная, состоящая из букв (буквы), букв с цифрами, букв с цифрами и знаком подчеркивания и т.д. в соответствии с правилами объявления переменных, принятых в языке С. Если размерность массива меньше, чем требуется, то компилятор не выдаст сообщения об ошибке. Выход за границы массивов должен следить только сам программист.
Одномерный массив – это список связанных однотипных переменных.
Общая форма записи одномерного массива [5.2]:
тип имя_массива[размер];
В приведенной записи элемент тип объявляет базовый тип массива. Количество элементов, которые будут храниться в массиве с именем имя_массива, определяется элементом размер.
В языке С
Доступ к отдельному элементу массива осуществляется с помощью индекса. Индекс описывает позицию элемента внутри массива.
Все массивы занимают смежные ячейки памяти, т.е. элементы массива в памяти расположены последовательно друг за другом. Ячейка памяти с наименьшим адресом относится к первому элементу массива, а с наибольшим – к последнему.
Для одномерных массивов общий размер массива в байтах вычисляется по формуле:
всего байт = размер типа в байтах * количество элементов
В языке С нельзя присвоить один массив другому. Для передачи элементов одного массива другому необходимо выполнить присвоение поэлементно.
Двухмерный массив представляет собой список одномерных массивов.
Общая форма записи двухмерного массива:
тип имя_массива[размер1] [размер2];
В приведенной записи размер1 означает количество строк двухмерного массива, а размер2 – количество столбцов.
В двухмерном массиве позиция любого элемента определяется двумя индексами. Индексы каждого из размеров массива начинаются с 0 (с нуля).
Место хранения для всех элементов массива определяется во время компиляции. Память, выделенная для хранения массива, используется в течение всего времени существования массива.
Для двухмерных массивов общий размер массива в байтах вычисляется по формуле:
всего байт = число строк * число столбцов * размер типа в байтах
Общая форма записи многомерного массива:
тип имя_массива[размер1] [размер2]... [размерN];
Индексация каждого размера начинается с нуля. Элементы многомерного массива располагаются в памяти в порядке возрастания самого правого индекса. Поэтому правый индекс будет изменяться быстрее, чем левый (левые).
При обращении к многомерным массивам компьютер много времени затрачивает на вычисление адреса, так как при этом приходится учитывать значение каждого индекса [5.2]. Следовательно, доступ к элементам многомерного массива происходит значительно медленнее, чем к элементам одномерного. В этой связи использование многомерных массивов встречается значительно реже, чем одномерных или двухмерных массивов.
Для многомерных массивов общий размер многомерного массива в байтах вычисляется по формуле:
всего байт = размер1* размер2*...* размерN *размер типа в байтах
Очевидно, многомерные массивы способны занять большой объем памяти, а программа, которая их использует, может очень быстро столкнуться с проблемой нехватки памяти.
Для определения размера типа в байтах применяется функция sizeof(), которая возвращает целое число. Например, sizeof(float).
В языке С массивы при объявлении можно инициализировать [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]. Алгоритм сортировки заключается в следующем:
Программный код решения примера:
#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 – для обращения к функциям генерации псевдослучайных чисел.
Задание 1
Пример 2. Напишите программу поиска максимального элемента в заданном одномерном массиве. Элементы массива являются целыми числами. Программный код решения примера:
#include <stdio.h>
#include <conio.h>
int main (void){
int i, size, max;
int A[ ] = {3, 5, 2, 8, 12, 0, -7, -3, -21};
size = sizeof(A)/sizeof(A[0]);
printf("\n\t The dimention of the array A is equal to: %d\n", size);
max = A[0]; // Предполагаемый максимум
for (i = 0; i < size; ++i)
if (A[i] > max) max = A[i];
printf("\n\t Maximum array element: %d\n", max);
printf("\n\n Press any key: ");
_getch();
return 0; }
В программе использована инициализация безразмерного массива и определения его размерности с помощью функции sizeof().
Результат выполнения программы показан на рис 5.2.
(рис 5.2) Определение максимального элемента массиваЗадание 2
Пример 3. Напишите программу циклической перестановки чисел заданного массива так, чтобы i -e число стало ( i +1)-м, а последнее число – первым. Выведите на дисплей исходный массив и преобразованный.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#define N 55
int main (void) {
int i, j, k;
double D[ ] = {1.23, 2.34, 3.45, 4.56, 5.67, 6.78};
double B[N]; // Заведомо больший размер, чем у массива D
// Обнуление массива и выделение памяти для него
for (i = 0; i < N; ++i)
B[i] = 0.0;
k = sizeof(D)/sizeof(D[0]);
B[0] = D[k-1];
for (i = 0; i < (k - 1); ++i)
B[i+1] = D[i];
printf("\n\t The original array:\n");
for (i = 0; i < k; ++i)
printf("%8.2f", D[i]);
printf("\n\n\t The reconfigured array:\n");
for (j = 0; j < k; ++j)
printf("%8.2f", B[j]);
printf("\n\n Press any key: ");
_getch();
return 0;
}
Результат выполнения программы показан на рис 5.3.
(рис 5.3) Пример циклической перестановки элементов числового массиваЗадание 3
Пример 4. В данном одномерном массиве вещественных чисел поменяйте местами элементы, стоящие на нечетных местах, с элементами, стоящими на четных местах. Предусмотрите четность и нечетность размерности массива.
Для определения четности места в заданном массиве можно использовать операцию деления по модулю, т.е. %.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
// Размер массива
#define n 7
int main (void) {
int i, k;
// Пример массива
float A[n] = {1.23F, 2.34F, 3.45F, 4.56F, 5.67F, 6.78F, 7.89F};
float B[n];// Вспомогательный массив
// Обнуление массива
for (i = 0; i < n; ++i)
B[i] = 0;
// Распечатка заданного массива
printf("\n\t\t The original array of dimention n = %d:\n", n);
printf("\t");
for (i = 0; i < n; ++i)
printf("%6.2f", A[i]);
// Распечатка преобразованного массива
printf("\n\n\t\t The reconfigured array:\n");
for (i = 0; i < n; ++i) {
k = i % 2; // Для определения четности индекса массива
if (k == 0 i < n - 1 )
B[i] = A[i + 1];
else if (k != 0 i > 0 )
B[i] = A[i-1];
else if (k == 0 i < n)
B[i] = A[i]; } printf("\t");
for (i = 0; i < n; ++i)
printf("%6.2f", B[i]);
printf("\n\n Press any key: ");
_getch();
return 0; }
При инициализации массива каждый его элемент снабжен суффиксом F.
Результат выполнения программы показан на рис 5.4.
(рис 5.4) Смена четных и нечетных мест чисел массиваЗадание 4
Указание: Можно предусмотреть определение остатка от деления, как индекса строки, так и индекса столбца и суммы индексов строки и столбца.
Пример 5. Напишите программу заполнения квадратной матрицы (заданного размера n > 2) по спирали натуральными числами начиная с левого верхнего угла (принимая его за номер 1) и двигаясь по часовой стрелке.
Образец заполнения:

Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#define n 13
int main(void) {
int i = 1, j, k;
int p = n/2;
int A[n][n];
// Обнуление матрицы
for (j = 0; j < n; ++j)
for (k = 0; k < n; ++k)
A[j][k] = 0;
printf("\n\t Spiral matrix of dimention (%d x %d):\n", n, n);
for (k = 1; k <= p; k++) // Число спиралей
{
// Верхний горизонтальный столбец
for (j = (k-1); j < (n-k+1); j++)
A[(k-1)][j] = i++;
// Правый верхний столбец
for (j = k; j < (n-k+1); j++)
A[j][n-k] = i++;
// Нижний горизонтальный столбец
for (j = (n-k-1); j >= (k-1); --j)
A[n-k][j] = i++;
// Левый верхний столбец
for (j = (n-k-1); j >= k; j--)
A[j][(k-1)] = i++;
}
if ( n % 2 )
A[p][p] = n*n;
// Распечатка матрицы
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
{
printf("%5d", A[i][j]);
if (j == (n-1))
printf("\n");
}
printf("\n Press any key: ");
_getch();
return 0;
}
Результат выполнения программы показан на рис 5.5.
(рис 5.5) Заполнение матрицы по спиралиЗадание 5
Пример 6. Каждый день производятся замеры некоторых величин (вещественных значений), причем значения этих величин сводятся в прямоугольную таблицу размера n $$\times$$ m. Составьте
Этот пример относится к определению трехмерного массива данных. Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#define n 6
#define m 7
#define N 30
const int Left = -12; // Левая граница
const int Right = 21; // Правая граница
int main (void)
{
float R, r;
float A[N][n][m];
int i, j, k;
// Инициализация генератора случайных чисел
srand((unsigned) time(NULL));
printf("\n\t The values of every 10 days from 30 days:");
// Формирование данных за 30 дней
for (k = 0; k < N; ++k)
for (i = 0; i < n; ++i)
for (j = 0; j < m; ++j)
{ r = (float) rand()/RAND_MAX;
R = Left + (Right - Left)*r;
A[k][i][j] = R;
}
// Печать данных за каждый 10-й день
for (k = 0; k < N; k += 10) { printf("\n");
for (i = 0; i < n; ++i) { printf("\n");
for (j = 0; j < m; ++j)
printf("%10.4f", A[k][i][j]);
}
}
printf("\n Press any key: ");
_getch();
return 0;
}
В программе используется трехмерный массив размера 30 $$\times$$ 6 $$\times$$ 7. Это означает, что прямоугольная таблица (массив) данных размера 6 $$\times$$ 7 как бы скрепляется 30 раз – по заданному числу дней. Границы случайных чисел определены с помощью спецификатора const.
Возможный результат выполнения программы показан на рис 5.6.
(рис 5.6) Вывод данных за каждый 10-й деньЗадание 6
float на тип double. Проверьте работу программы.Пример 7. Напишите программу по перемножению двух матриц А и В с размерностями ( m $$\times$$ r ) и ( r $$\times$$ n ) соответственно. Матрицу А примите размером 4 $$\times$$ 5, матрицу В – размером 5 $$\times$$ 3 (обе целочисленные).
Условием перемножения двух матриц А и В является равенство числа столбцов матрицы А и числа строк матрицы В. Если первая матрица А имеет размер m $$\times$$ r, то вторая матрица В должна иметь размер r $$\times$$ n. В результате перемножения получим матрицу С размера m $$\times$$ n. Приведем следующую схему по размерностям:

Поэлементное перемножение двух матриц в стандартной математической форме имеет следующий вид:
$$C_{ij}=\sum^{n}_{k=1}a_{il}*b_{kj}, i=1,2,\cdots,n, j=1,2,\cdots,m.$$С учетом синтаксиса формирования массивов в языке С индексация должна начинаться с нуля, поэтому формулу перепишем в следующем виде:
$$C_{ij}=\sum^{n-1}_{k=1}a_{il}*b_{kj}, i=1,2,\cdots,n-1, j=0,1,2,\cdots,m-1.$$Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#define m 4
#define r 5
#define n 3
int main (void) {
int i, j, k; // переменные циклов
const int A[m][r] = {{1,2,3,4,5},
{2,3,4,5,6},
{2,2,2,2,2},
{3,3,3,3,3}};
const int B[r][n] = {{9,8,7},
{1,2,3},
{4,5,6},
{7,8,9},
{1,1,1}};
// Массив под результат произведения двух матриц
int C[m][n];
// Обнуление результирующей матрицы
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
C[i][j] = 0;
// Формирование результата произведения двух матриц
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
for (k = 0; k < r; k++)
C[i][j] = C[i][j] + A[i][k]*B[k][j];
// Распечатка результата произведения двух матриц
printf("\n 1) Index: \"ijk\". Matrix (%dx%d):\n", m, n);
for (i = 0; i < m; i++) {
printf("\n");
for (j = 0; j < n; j++)
printf(" %4d", C[i][j]);
}
printf("\n\n ... Press any key: ");
_getch();
return 0;
}
В программе используются три цикла по формированию произведения двух матриц. Первый цикл (переменная i ) связан с количеством строк первой матрицы (матрицы А ), второй цикл (переменная j ) связан с количеством столбцов второй матрицы (матрица В ), третий цикл (переменная k ) связан со смежной размерностью матриц, которая исчезает в результирующей матрице С. Матрицы А и В определены как неизменяемы типы ( const int ). Приведенный программный метод можно назвать как первый метод, метод "ijk".
Результат выполнения программы показан на рис 5.7.
(рис 5.7) Результат произведения двух матрицЗадание 7
"jki". Это можно назвать вторым методом программного перемножения двух матриц."kji". Это можно назвать третьим методом программного перемножения двух матриц.float для заданных матриц. Предусмотрите форматированный вывод результата на консоль.В языке программирования С заложены средства для задания последовательностей упорядоченных данных [5.1]. Такие последовательности называются массивами. В массивах должны быть упорядочены данные одного и того же типа. В данной лабораторной работе будут рассматриваться массивы с целыми и вещественными типами данных, т.е. типы int, float или double.
Массивы данных могут быть одномерными (векторами размера 1 $$\times$$ n или n $$\times$$ 1), двухмерными (матрицами размера n $$\times$$ m) или многомерными (размера n $$\times$$ m $$\times$$ p...). В частности, для векторов и матриц в приведенной записи первый индекс означает количество строк, а второй (число или буква) – это количество столбцов. Для названия массива может быть использована переменная, состоящая из букв (буквы), букв с цифрами, букв с цифрами и знаком подчеркивания и т.д. в соответствии с правилами объявления переменных, принятых в языке С. Если размерность массива меньше, чем требуется, то компилятор не выдаст сообщения об ошибке. Выход за границы массивов должен следить только сам программист.
Одномерный массив – это список связанных однотипных переменных.
Общая форма записи одномерного массива [5.2]:
тип имя_массива[размер];
В приведенной записи элемент тип объявляет базовый тип массива. Количество элементов, которые будут храниться в массиве с именем имя_массива, определяется элементом размер.
В языке С
Доступ к отдельному элементу массива осуществляется с помощью индекса. Индекс описывает позицию элемента внутри массива.
Все массивы занимают смежные ячейки памяти, т.е. элементы массива в памяти расположены последовательно друг за другом. Ячейка памяти с наименьшим адресом относится к первому элементу массива, а с наибольшим – к последнему.
Для одномерных массивов общий размер массива в байтах вычисляется по формуле:
всего байт = размер типа в байтах * количество элементов
В языке С нельзя присвоить один массив другому. Для передачи элементов одного массива другому необходимо выполнить присвоение поэлементно.
Двухмерный массив представляет собой список одномерных массивов.
Общая форма записи двухмерного массива:
тип имя_массива[размер1] [размер2];
В приведенной записи размер1 означает количество строк двухмерного массива, а размер2 – количество столбцов.
В двухмерном массиве позиция любого элемента определяется двумя индексами. Индексы каждого из размеров массива начинаются с 0 (с нуля).
Место хранения для всех элементов массива определяется во время компиляции. Память, выделенная для хранения массива, используется в течение всего времени существования массива.
Для двухмерных массивов общий размер массива в байтах вычисляется по формуле:
всего байт = число строк * число столбцов * размер типа в байтах
Общая форма записи многомерного массива:
тип имя_массива[размер1] [размер2]... [размерN];
Индексация каждого размера начинается с нуля. Элементы многомерного массива располагаются в памяти в порядке возрастания самого правого индекса. Поэтому правый индекс будет изменяться быстрее, чем левый (левые).
При обращении к многомерным массивам компьютер много времени затрачивает на вычисление адреса, так как при этом приходится учитывать значение каждого индекса [5.2]. Следовательно, доступ к элементам многомерного массива происходит значительно медленнее, чем к элементам одномерного. В этой связи использование многомерных массивов встречается значительно реже, чем одномерных или двухмерных массивов.
Для многомерных массивов общий размер многомерного массива в байтах вычисляется по формуле:
всего байт = размер1* размер2*...* размерN *размер типа в байтах
Очевидно, многомерные массивы способны занять большой объем памяти, а программа, которая их использует, может очень быстро столкнуться с проблемой нехватки памяти.
Для определения размера типа в байтах применяется функция sizeof(), которая возвращает целое число. Например, sizeof(float).
В языке С массивы при объявлении можно инициализировать [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]. Алгоритм сортировки заключается в следующем:
Программный код решения примера:
#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 – для обращения к функциям генерации псевдослучайных чисел.
Задание 1
Пример 2. Напишите программу поиска максимального элемента в заданном одномерном массиве. Элементы массива являются целыми числами. Программный код решения примера:
#include <stdio.h>
#include <conio.h>
int main (void){
int i, size, max;
int A[ ] = {3, 5, 2, 8, 12, 0, -7, -3, -21};
size = sizeof(A)/sizeof(A[0]);
printf("\n\t The dimention of the array A is equal to: %d\n", size);
max = A[0]; // Предполагаемый максимум
for (i = 0; i < size; ++i)
if (A[i] > max) max = A[i];
printf("\n\t Maximum array element: %d\n", max);
printf("\n\n Press any key: ");
_getch();
return 0; }
В программе использована инициализация безразмерного массива и определения его размерности с помощью функции sizeof().
Результат выполнения программы показан на рис 5.2.
(рис 5.2) Определение максимального элемента массиваЗадание 2
Пример 3. Напишите программу циклической перестановки чисел заданного массива так, чтобы i -e число стало ( i +1)-м, а последнее число – первым. Выведите на дисплей исходный массив и преобразованный.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#define N 55
int main (void) {
int i, j, k;
double D[ ] = {1.23, 2.34, 3.45, 4.56, 5.67, 6.78};
double B[N]; // Заведомо больший размер, чем у массива D
// Обнуление массива и выделение памяти для него
for (i = 0; i < N; ++i)
B[i] = 0.0;
k = sizeof(D)/sizeof(D[0]);
B[0] = D[k-1];
for (i = 0; i < (k - 1); ++i)
B[i+1] = D[i];
printf("\n\t The original array:\n");
for (i = 0; i < k; ++i)
printf("%8.2f", D[i]);
printf("\n\n\t The reconfigured array:\n");
for (j = 0; j < k; ++j)
printf("%8.2f", B[j]);
printf("\n\n Press any key: ");
_getch();
return 0;
}
Результат выполнения программы показан на рис 5.3.
(рис 5.3) Пример циклической перестановки элементов числового массиваЗадание 3
Пример 4. В данном одномерном массиве вещественных чисел поменяйте местами элементы, стоящие на нечетных местах, с элементами, стоящими на четных местах. Предусмотрите четность и нечетность размерности массива.
Для определения четности места в заданном массиве можно использовать операцию деления по модулю, т.е. %.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
// Размер массива
#define n 7
int main (void) {
int i, k;
// Пример массива
float A[n] = {1.23F, 2.34F, 3.45F, 4.56F, 5.67F, 6.78F, 7.89F};
float B[n];// Вспомогательный массив
// Обнуление массива
for (i = 0; i < n; ++i)
B[i] = 0;
// Распечатка заданного массива
printf("\n\t\t The original array of dimention n = %d:\n", n);
printf("\t");
for (i = 0; i < n; ++i)
printf("%6.2f", A[i]);
// Распечатка преобразованного массива
printf("\n\n\t\t The reconfigured array:\n");
for (i = 0; i < n; ++i) {
k = i % 2; // Для определения четности индекса массива
if (k == 0 i < n - 1 )
B[i] = A[i + 1];
else if (k != 0 i > 0 )
B[i] = A[i-1];
else if (k == 0 i < n)
B[i] = A[i]; } printf("\t");
for (i = 0; i < n; ++i)
printf("%6.2f", B[i]);
printf("\n\n Press any key: ");
_getch();
return 0; }
При инициализации массива каждый его элемент снабжен суффиксом F.
Результат выполнения программы показан на рис 5.4.
(рис 5.4) Смена четных и нечетных мест чисел массиваЗадание 4
Указание: Можно предусмотреть определение остатка от деления, как индекса строки, так и индекса столбца и суммы индексов строки и столбца.
Пример 5. Напишите программу заполнения квадратной матрицы (заданного размера n > 2) по спирали натуральными числами начиная с левого верхнего угла (принимая его за номер 1) и двигаясь по часовой стрелке.
Образец заполнения:

Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#define n 13
int main(void) {
int i = 1, j, k;
int p = n/2;
int A[n][n];
// Обнуление матрицы
for (j = 0; j < n; ++j)
for (k = 0; k < n; ++k)
A[j][k] = 0;
printf("\n\t Spiral matrix of dimention (%d x %d):\n", n, n);
for (k = 1; k <= p; k++) // Число спиралей
{
// Верхний горизонтальный столбец
for (j = (k-1); j < (n-k+1); j++)
A[(k-1)][j] = i++;
// Правый верхний столбец
for (j = k; j < (n-k+1); j++)
A[j][n-k] = i++;
// Нижний горизонтальный столбец
for (j = (n-k-1); j >= (k-1); --j)
A[n-k][j] = i++;
// Левый верхний столбец
for (j = (n-k-1); j >= k; j--)
A[j][(k-1)] = i++;
}
if ( n % 2 )
A[p][p] = n*n;
// Распечатка матрицы
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
{
printf("%5d", A[i][j]);
if (j == (n-1))
printf("\n");
}
printf("\n Press any key: ");
_getch();
return 0;
}
Результат выполнения программы показан на рис 5.5.
(рис 5.5) Заполнение матрицы по спиралиЗадание 5
Пример 6. Каждый день производятся замеры некоторых величин (вещественных значений), причем значения этих величин сводятся в прямоугольную таблицу размера n $$\times$$ m. Составьте
Этот пример относится к определению трехмерного массива данных. Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#define n 6
#define m 7
#define N 30
const int Left = -12; // Левая граница
const int Right = 21; // Правая граница
int main (void)
{
float R, r;
float A[N][n][m];
int i, j, k;
// Инициализация генератора случайных чисел
srand((unsigned) time(NULL));
printf("\n\t The values of every 10 days from 30 days:");
// Формирование данных за 30 дней
for (k = 0; k < N; ++k)
for (i = 0; i < n; ++i)
for (j = 0; j < m; ++j)
{ r = (float) rand()/RAND_MAX;
R = Left + (Right - Left)*r;
A[k][i][j] = R;
}
// Печать данных за каждый 10-й день
for (k = 0; k < N; k += 10) { printf("\n");
for (i = 0; i < n; ++i) { printf("\n");
for (j = 0; j < m; ++j)
printf("%10.4f", A[k][i][j]);
}
}
printf("\n Press any key: ");
_getch();
return 0;
}
В программе используется трехмерный массив размера 30 $$\times$$ 6 $$\times$$ 7. Это означает, что прямоугольная таблица (массив) данных размера 6 $$\times$$ 7 как бы скрепляется 30 раз – по заданному числу дней. Границы случайных чисел определены с помощью спецификатора const.
Возможный результат выполнения программы показан на рис 5.6.
(рис 5.6) Вывод данных за каждый 10-й деньЗадание 6
float на тип double. Проверьте работу программы.Пример 7. Напишите программу по перемножению двух матриц А и В с размерностями ( m $$\times$$ r ) и ( r $$\times$$ n ) соответственно. Матрицу А примите размером 4 $$\times$$ 5, матрицу В – размером 5 $$\times$$ 3 (обе целочисленные).
Условием перемножения двух матриц А и В является равенство числа столбцов матрицы А и числа строк матрицы В. Если первая матрица А имеет размер m $$\times$$ r, то вторая матрица В должна иметь размер r $$\times$$ n. В результате перемножения получим матрицу С размера m $$\times$$ n. Приведем следующую схему по размерностям:

Поэлементное перемножение двух матриц в стандартной математической форме имеет следующий вид:
$$C_{ij}=\sum^{n}_{k=1}a_{il}*b_{kj}, i=1,2,\cdots,n, j=1,2,\cdots,m.$$С учетом синтаксиса формирования массивов в языке С индексация должна начинаться с нуля, поэтому формулу перепишем в следующем виде:
$$C_{ij}=\sum^{n-1}_{k=1}a_{il}*b_{kj}, i=1,2,\cdots,n-1, j=0,1,2,\cdots,m-1.$$Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#define m 4
#define r 5
#define n 3
int main (void) {
int i, j, k; // переменные циклов
const int A[m][r] = {{1,2,3,4,5},
{2,3,4,5,6},
{2,2,2,2,2},
{3,3,3,3,3}};
const int B[r][n] = {{9,8,7},
{1,2,3},
{4,5,6},
{7,8,9},
{1,1,1}};
// Массив под результат произведения двух матриц
int C[m][n];
// Обнуление результирующей матрицы
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
C[i][j] = 0;
// Формирование результата произведения двух матриц
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
for (k = 0; k < r; k++)
C[i][j] = C[i][j] + A[i][k]*B[k][j];
// Распечатка результата произведения двух матриц
printf("\n 1) Index: \"ijk\". Matrix (%dx%d):\n", m, n);
for (i = 0; i < m; i++) {
printf("\n");
for (j = 0; j < n; j++)
printf(" %4d", C[i][j]);
}
printf("\n\n ... Press any key: ");
_getch();
return 0;
}
В программе используются три цикла по формированию произведения двух матриц. Первый цикл (переменная i ) связан с количеством строк первой матрицы (матрицы А ), второй цикл (переменная j ) связан с количеством столбцов второй матрицы (матрица В ), третий цикл (переменная k ) связан со смежной размерностью матриц, которая исчезает в результирующей матрице С. Матрицы А и В определены как неизменяемы типы ( const int ). Приведенный программный метод можно назвать как первый метод, метод "ijk".
Результат выполнения программы показан на рис 5.7.
(рис 5.7) Результат произведения двух матрицЗадание 7
"jki". Это можно назвать вторым методом программного перемножения двух матриц."kji". Это можно назвать третьим методом программного перемножения двух матриц.float для заданных матриц. Предусмотрите форматированный вывод результата на консоль.Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.