Как вводить двумерный массив. Двумерные массивы
При решении задач с большим количеством данных одинакового типа использование переменных с различными именами, не упорядоченных по адресам памяти, затрудняет программирование. В подобных случаях в языке Си используют объекты, называемые массивами.
— это непрерывный участок памяти, содержащий последовательность объектов одинакового типа, обозначаемый одним именем.
Массив характеризуется следующими основными понятиями:
Элемент массива (значение элемента массива)
– значение, хранящееся в определенной ячейке памяти, расположенной в пределах массива, а также адрес этой ячейки памяти.
Каждый элемент массива характеризуется тремя величинами:
- адресом элемента — адресом начальной ячейки памяти, в которой расположен этот элемент;
- индексом элемента (порядковым номером элемента в массиве);
- значением элемента.
Адрес массива – адрес начального элемента массива.
Имя массива – идентификатор, используемый для обращения к элементам массива.
Размер массива – количество элементов массива
Размер элемента – количество байт, занимаемых одним элементом массива.
Графически расположение массива в памяти компьютера можно представить в виде непрерывной ленты адресов.
Представленный на рисунке массив содержит q элементов с индексами от 0 до q-1 . Каждый элемент занимает в памяти компьютера k байт, причем расположение элементов в памяти последовательное.
Адреса i -го элемента массива имеет значение
Адрес массива представляет собой адрес начального (нулевого) элемента массива. Для обращения к элементам массива используется порядковый номер (индекс) элемента, начальное значение которого равно 0 . Так, если массив содержит q элементов, то индексы элементов массива меняются в пределах от 0 до q-1 .
Длина массива – количество байт, отводимое в памяти для хранения всех элементов массива.
ДлинаМассива = РазмерЭлемента * КоличествоЭлементов
Для определения размера элемента массива может использоваться функция
int
sizeof
(тип);
Например,
sizeof
(char
) = 1;
sizeof
(int
) = 4;
sizeof
(float
) = 4;
sizeof
(double
) = 8;
Объявление и инициализация массивов
Для объявления массива в языке Си используется следующий синтаксис:
тип имя[размерность]={инициализация};
Инициализация
представляет собой набор начальных значений элементов массива, указанных в фигурных скобках, и разделенных запятыми.
int
a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // массив a из 10 целых чисел
Если количество инициализирующих значений, указанных в фигурных скобках, меньше, чем количество элементов массива, указанное в квадратных скобках, то все оставшиеся элементы в массиве (для которых не хватило инициализирующих значений) будут равны нулю. Это свойство удобно использовать для задания нулевых значений всем элементам массива.
int
b = {0}; // массив b из 10 элементов, инициализированных 0
Если массив проинициализирован при объявлении, то константные начальные значения его элементов указываются через запятую в фигурных скобках. В этом случае количество элементов в квадратных скобках может быть опущено.
int
a = {1, 2, 3, 4, 5, 6, 7, 8, 9};
При обращении к элементам массива индекс требуемого элемента указывается в квадратных скобках .
Пример на Си
1
2
3
4
5
6
7
8
#include
int
main()
{
int
a = { 5, 4, 3, 2, 1 }; // массив a содержит 5 элементов
printf("%d %d %d %d %d\n"
, a, a, a, a, a);
getchar();
return
0;
}
Результат выполнения программы:
Однако часто требуется задавать значения элементов массива в процессе выполнения программы. При этом используется объявление массива без инициализации. В таком случае указание количества элементов в квадратных скобках обязательно.
int
a;
Для задания начальных значений элементов массива очень часто используется параметрический цикл:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include
int
main()
{
int
a;
int
i;
// Ввод элементов массива
for
(i = 0; i<5; i++)
{
printf("a[%d] = "
, i);
scanf("%d"
, &a[i]);
}
// Вывод элементов массива
for
(i = 0; i<5; i++)
printf("%d "
, a[i]); // пробел в формате печати обязателен
getchar(); getchar();
return
0;
}
Результат выполнения программы
Многомерные массивы
В языке Си могут быть также объявлены многомерные массивы. Отличие многомерного массива от одномерного состоит в том, что в одномерном массиве положение элемента определяется одним индексом, а в многомерном - несколькими. Примером многомерного массива является матрица.
Общая форма объявления многомерного массива
тип имя[размерность1][размерность2]...[размерностьm];
Элементы многомерного массива располагаются в последовательных ячейках оперативной памяти по возрастанию адресов. В памяти компьютера элементы многомерного массива располагаются подряд, например массив, имеющий 2 строки и 3 столбца,
int
a;
будет расположен в памяти следующим образом
Общее количество элементов в приведенном двумерном массиве определится как
КоличествоСтрок * КоличествоСтолбцов = 2 * 3 = 6.
Количество байт памяти, требуемых для размещения массива, определится как
КоличествоЭлементов * РазмерЭлемента = 6 * 4 = 24 байта.
Инициализация многомерных массивов
Значения элементов многомерного массива, как и в одномерном случае, могут быть заданы константными значениями при объявлении, заключенными в фигурные скобки {} . Однако в этом случае указание количества элементов в строках и столбцах должно быть обязательно указано в квадратных скобках .
Пример на Си
1
2
3
4
5
6
7
8
9
#include
int
main()
{
int
a = { 1, 2, 3, 4, 5, 6 };
printf("%d %d %d\n"
, a, a, a);
getchar();
return
0;
}
Однако чаще требуется вводить значения элементов многомерного массива в процессе выполнения программы. С этой целью удобно использовать вложенный параметрический цикл .
Пример на Си
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#define
_CRT_SECURE_NO_WARNINGS
#include
int
main()
{
int
a; // массив из 2 строк и 3 столбцов
int
i, j;
// Ввод элементов массива
for
(i = 0; i<2; i++) // цикл по строкам
{
for
(j = 0; j<3; j++) // цикл по столбцам
{
printf("a[%d][%d] = "
, i, j);
scanf("%d"
, &a[i][j]);
}
}
// Вывод элементов массива
for
(i = 0; i<2; i++) // цикл по строкам
{
for
(j = 0; j<3; j++) // цикл по столбцам
{
printf("%d "
, a[i][j]);
}
printf("\n"
); // перевод на новую строку
}
getchar(); getchar();
return
0;
}
Передача массива в функцию
Обработку массивов удобно организовывать с помощью специальных функций. Для обработки массива в качестве аргументов функции необходимо передать
- адрес массива,
- размер массива.
Исключение составляют функции обработки строк, в которые достаточно передать только адрес.
При передаче переменные в качестве аргументов функции данные передаются как копии. Это означает, что если внутри функции произойдет изменение значения параметра, то это никак не повлияет на его значение внутри вызывающей функции.
Если в функцию передается адрес переменной (или адрес массива), то все операции, выполняемые в функции с данными, находящимися в пределах видимости указанного адреса, производятся над оригиналом данных, поэтому исходный массив (или значение переменной) может быть изменено вызываемой функцией.
Пример на Си
Дан массив из 10 элементов. Поменять местами наибольший и начальный элементы массива. Для операций поиска максимального элемента и обмена использовать функцию.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#define
_CRT_SECURE_NO_WARNINGS
#include
// Функция обмена
void
change(int
*x, int
n)
{
// x - указатель на массив (адрес массива)
// n - размер массива
int
i;
int
max, index;
max = x;
index = 0;
// Поиск максимального элемента
for
(i = 1; i
if
(x[i]>max)
{
max = x[i];
index = i;
}
}
// Обмен
x = x;
x = max;
}
// Главная функция
int
main()
{
int
a;
int
i;
for
(i = 0; i<10; i++)
{
printf("a[%d] = "
, i);
scanf("%d"
, &a[i]);
}
change(a, 10); // вызов функции обмена
// Вывод элементов массива
for
(i = 0; i<10; i++)
printf("%d "
, a[i]);
getchar();
getchar();
return
p = p * x[i];
}
return
p;
}
// Главная функция
int
main()
{
int
a; // объявлен массив a из 5 элементов
int
i;
int
pr;
// Ввод элементов массива
for
(i = 0; i<5; i++)
{
printf("a[%d] = "
, i);
scanf("%d"
, &a[i]); // &a[i] - адрес i-го элемента массива
}
pr = func(a, 5); // вычисление произведения
printf("\n pr = %d"
, pr); // вывод произведения четных элементов
getchar(); getchar();
return
0;
}
Матрица – в – аналог двумерного массива – квадратная или прямоугольная таблица, состоящая из строк и столбцов:
Размер двумерного массива - количество элементов в массиве M*N,
где М – число строк, N – число столбцов (натураль – ные числа).
Квадратная матрица – матрица с равным числом строк и столбцов.
Порядок матрицы – число строк (столбцов) квадратной матрицы.
1. Описание двумерного массива
Двумерный массив – это массив массивов, т. е. двумерная таблица. Оперировать можно как с отдельными элементами массива, так и с массивом в целом.
В языке Pascal индексы заключаются в квадратные скобки:
А, A,..A.
Возможны 2 способа описания 2-мерного массива:
1 Описание массива в разделе переменных VAR:
iнач..iкон, jнач..jкон – диапазоны индексов (строк, столбцов);
t – тип элементов.
Например:
VAR y: of integer ;
VAR F: array of array of real;
VAR mb: array of real ;
VAR C: array OF string ;
CONST M= 4; N=2;
VAR A: array OF integer ;
2 Описание массива в разделе описания типов TYPE:
Для заполнения матрицы организуется наружный цикл по i , внутренний – по j (при условии, что i – строки, j –столбцы). При этом индекс строки i меняется медленнее индекса столбца j за счет того, что происходит постепенный перебор всех элементов строки, т. е. столбцов i-й строки.
Заполнение по столбцам:
А | А | … | … | … |
А | … | … | … | … |
А | … | … | … | … |
A | … | … | … | … |
Упражнения на заполнение 2-мерных массивов
Упражнение mas1: Заполнить матрицу А(5, 10) по строкам методом генерирования случайных чисел.
program mas_1; {заполнение матрицы по строкам}
A: array of INTEGER;
writeLn(‘Матрица А:’);
FOR i:= 1 to 5 DO {наружный цикл по строкам}
FOR j:=1 TO 10 DO {внутренний цикл по столбцам}
A:= random(10);
write(A:3); {печатаем подряд всю строку}
writeLn; {переходим на новую строку}
Упражнение mas2: Заполнить матрицу А(3, 4) по столбцам методом ввода чисел с клавиатуры.
program mas_2; {заполнение матрицы по столбцам}
Const N =4; M =3;
Var A: array of INTEGER;
FOR j:= 1 to M DO {наружный цикл по столбцам }
FOR i:=1 TO N DO {внутренний цикл по строкам}
write(‘Введите элемент A[",i,",",j,"]=’);
readLn(A);
writeLn(‘Результирующая матрица A:’);
for i:=1 to N do {Вывод матрицы}
for j:=1 to M do
write(A,’ ‘);
Упражнение mas3: Дана матрица A(N? M), состоящая из натуральных чисел. Определить ее максимальный элемент и его индексы.
program mas_3; {Max элемент матрицы}
CONST t= 10; r=10;
A: array of INTEGER;
n, m, Max, iMax, jMax, k: integer;
write(‘Введите число строк N=’); readLn(N);
write(‘Введите число столбцов M=’); readLn(M);
writeLn(‘Матрица:’);
FOR i:= 1 to N DO {заполнение массива генерированием случайных чисел}
FOR j:=1 TO M DO
A:= random(10);
write(A:3);
Max:= A; iMax:=1; jMax:=1; k:=0; {принимаем начальное значение Мах = значению 1-го эл-та}
For i:=1 to N do
For j:=1 to M do
IF A > Max then
Max:= A; iMax:=i; jMax:=j; k:=1
WriteLn(‘Max= ’ ,Max,’ в строке: ‘,imax, ‘ столбце:’, jmax);
Разделы: Информатика
Тема : Двумерные массивы. Заполнение двумерного массива по заданному правилу.
Цели: отработать навыки работы с элементами двумерного массива, научиться заполнять двумерные массивы по заданному правилу, научиться выводить зависимость между номером строки и номером столбца; развитие логического мышления учащихся.
ХОД ЗАНЯТИЯ
1. Актуализация знаний
Массивы, положение элементов в которых
описывается двумя индексами, называются
двумерными. Структура такого массива может быть
представлена прямоугольной матрицей. Каждый
элемент матрицы однозначно определяется
указанием номера строки и столбца, номер строки
– i, номер столбца – j.
Рассмотрим матрицу А размером n*m:
а 11 | а 12 | а 13 | а 14 |
а 21 | а 22 | а 23 | а 24 |
а 31 | а 32 | а 33 | а 34 |
Матрица из 3 строк и 4 столбцов, количество строк
n=3, количество столбцов m=4. Каждый элемент имеет
свой номер, который состоит из двух чисел –
номера строки, в которой находится элемент, и
номера столбца. Например, а23 – это элемент,
стоящий во второй строке и в третьем столбце.
Двумерный массив на языке Турбо Паскаль можно
описать по-разному. Чтобы описать двумерный
массив, надо определить какого типа его элементы,
и каким образом они пронумерованы (какого типа
его индекс). Существует несколько способов
описания двумерного массива.
Const maxN=…; {Максимальные значения количества
строк}
maxM=…; {Максимальные значения количества
столбцов}
1 способ
Type Mas = array of <тип элементов>; {Одномерный
массив}
Type TMas = array of Mas; {Одномерный массив,
элементами которого являются одномерные
массивы}
2 способ
Type TMas = array of array of <тип
элементов>;
{Одномерный массив, элементами которого являются
одномерные массивы}
3 способ
Type <имя типа>= array of <тип элементов>; {Двумерный массив}
Предпочтение отдается третьему способу описания двумерного массива.
Например:
Const N=3; M=4;
Type TMas= array of integer; {Двумерный массив из целых
чисел}
Формирование двумерного массива можно осуществлять четырьмя способами: ввод с клавиатуры, через генератор случайных чисел, по заданному правилу или с помощью файла.
1) Формирование двумерного массива при помощи ввода с клавиатуры и алгоритм построчного вывода элементов матрицы.
Const N=10;M=10;
Type Tmas= array of integer;
Var A:Tmas; i,j:integer;
Begin
{Ввод элементов матрицы}
For i:=1 to N do
For j:=1 to M do
Read(A);
{Вывод элементов матрицы}
For i:=1 to N do begin
For j:=1 to M do
Write(A:4);
{Печатается первая строка}
Writeln
{Переход на новую строку}
end;
End.
2) Фрагмент программы формирования двумерного массива через генератор случайных чисел.
Begin
Randomize; {Инициализация генератора случайных чисел}
{Ввод элементов матрицы}
For i:=1 to N do
For j:=1 to M do
A:=random(45)-22;
2. Изучение нового материала. Заполнение массива по правилу
Рассмотрим несколько фрагментов программ заполнения двумерного массива по некоторому закону. Для этого необходимо вывести правило заполнения.
1. Заполнить массив А размером n*m следующим образом, например
1
2
3
4
5
6
7 8
16 15
14 13
12 11
10 9
17 18
19 20
21 22
23 24
32 31
30 29
28 27
26 25
33 34
35 36
37 38
39 40
48 47
46 45
44 43
42 41
Массив заполняется по принципу «змейки». Правило заполнения: если номер строки – нечетное число, то A=(i-1)*m+j, иначе A=i*m-j+1.
program M1А;
n,m,i,j:
integer;
begin
readln(n,m);
for i:=1 to n do begin
for j:=1 to m do
begin
if i mod 2 = 1 then
A=(i-1)*m+j
else
A=i*m-j+1;
write(A:3);
end;
writeln;
end;
readln;
end.
Приведем пример программы другого способа заполнения по заданному правилу:
program M1В;
var A:array of integer;
n,m,i,j: integer;
c: integer;
begin
readln(n,m);
c:=1;
for i:=1 to n do
begin
for j:=1 to m do
begin
A:=c;
if (i mod 2 = 0) and (j<>m)
then
dec(c)
else
inc(c);
write(A:3);
end;
c:=c+m-1;
writeln;
end;
readln;
end.
2. Заполнить массив A по следующему принципу:
1
0
2
0
3
0 4
0
5
0
6
0
7 0
8
0
9
0
10
0 11
0
12
0
13
0
14 0
program M2;
var A:array of integer;
n,m,i,j: integer;
c: integer;
begin
readln(n,m);
c:=0;
for i:=1 to n do
begin
for j:=1 to m do
begin
if (i-1+j) mod 2 = 0 then
A:=0
else
begin
inc(c);
A:=c;
end;
write(A:5);
end;
writeln;
end;
readln;
end.
3. Заполнить массив A по следующему принципу:
1
12 13
24 25
36
2
11 14
23 26
35
3
10 15
22 27
34
4
9
16 21
28 33
5
8
17 20
29 32
6
7
18 19
30 31
var A:array of integer;
n,m,i,j: integer;
c: integer;
begin
readln(n,m);
c:=1;
for j:=1 to m do
begin
for i:=1 to n do
begin
A:=c;
if (j mod 2 = 0) and (i<>n)
then
dec(c)
else
inc(c);
end;
c:=c+n-1;
end;
for i:=1 to n do
begin
for j:=1 to m do
write(A:5);
writeln;
end;
readln;
end.
4. Заполнить массив A по следующему принципу:
1
2
3
4 5
2
3
4
5 1
3
4
5
1 2
4
5
1
2 3
5
1
2
3 4
var i,j,m,c,d: integer;
begin
c:=1;
readln(m);
for j:=1 to m do
begin
i:=c;
d:=1;
repeat
A:=d;
inc(i);
if i>m then
i:=1;
inc(d);
until i=c;
dec(c);
if c <= 0 then
c:=m-c;
end;
for i:=1 to m do
begin
for j:=1 to m do
write(A:2);
writeln;
end;
end.
5. Заполнить массив A по следующему принципу:
1
0
0
0 1
0
1
0
1 0
0
0
1
0 0
0
1
0
1 0
1
0
0
0 1
var m,i,j: integer;
A:array of integer;
begin
readln(m);
for i:=1 to m do
begin
for j:=1 to m do
begin
if (i=j) or (m-i+1=j) then
A:=1
else
A:=0;
write(A:2);
end;
writeln;
end;
end.
3. Задачи для самостоятельного решения
6
5
4
3
2 1
7
8
9
10 11
12
18 17
16 15
14 13
19 20
21 22
23 24
30 29
28 27
26 25
31 32
33 34
35 36
36
25 24
13 12
1
35 26
23 14
11 2
34 27
22 15
10 3
33 28
21 16
9 4
32 29
20 17
8 5
31 30
19 18
7 6
0
1
1
1 0
1
0
1
0 1
1
1
0
1 1
1
0
1
0 1
0
1
1
1 0
4) Заполнить массив по следующему принципу:
31
32 33
34 35
36
25 26
27 28
29 30
19 20
21 22
23 24
13 14
15 16
17 18
7
8
9
10 11
12
1
2
3
4
5 6
5) Заполнить массив по следующему принципу:
31
25 19
13
7 1
32 26
20 14
8 2
33 27
21 15
9 3
34 28
22 16
10 4
35 29
23 17
11 5
36 30
24 18
12 6
Домашние задание:
1) Заполнить массив по следующему принципу:
6
7
18 19
30 31
5
8
17 20
29 32
4
9
16 21
28 33
3
10 15
22 27
34
2
11 14
23 26
35
1
12 13
24 25
36
2) Заполнить массив по следующему принципу:
31
32 33
34 35
36
30 29
28 27
26 25
19 20
21 22
23 24
18 17
16 15
14 13
7
8
9
10 11
12
6
5
4
3
2 1
3) Заполнить массив по следующему принципу:
0
1
1
1 0
1
0
1
0 1
1
1
0
1 1
1
0
1
0 1
0
1
1
1 0
Массив (также индексный массив , иногда таблица , ряд ) - именованный (упорядоченный) набор однотипных переменных (данных), расположенных в памяти непосредственно друг за другом, доступ к которым осуществляется по индексу . В простейшем случае массив имеет постоянную длину и хранит единицы данных одного и того же типа.
Индекс же массива - это число целое , указывающее на конкретный элемент массива.
Количество используемых индексов массива может быть различным. Массивы с одним индексом называют одномерными , с двумя - двумерными и т. д.
Одномерный массив нестрого соответствует вектору в математике, двумерный - матрице . Чаще всего применяются массивы с одним или двумя индексами, реже - с тремя, ещё большее количество индексов встречается крайне редко.
Массив описывается так:
Чаще всего типом индекса является диапазон, например:
Выше описывается массив В , состоящий из 5 элементов и символьный массив R , состоящий из 34 элементов. Для массива В будет выделено 5*6=30 байт памяти (т.к. под переменные типа Real выделяется 6 байт памяти), для массива R - 1*34=34 байта памяти (под переменные типа Char - 1 байт). Базовый тип элементов массива может быть любым, как простым, так и структурированным, за исключением файлового! Массив можно объявить с использованием собственного типа:
Циклом может называться любая многократно исполняемая последовательность инструкций, организованная любым способом (например, с помощью условного перехода).
Единичное выполнение тела цикла называется итерацией . Выражение , определяющее, будет в очередной раз выполняться итерация , или цикл закончиться - это условие выхода или условие окончания цикла (но, может быть и условием продолжения). Переменная, хранящая текущий номер итерации, называется счётчиком итераций цикла или просто счётчиком цикла. Цикл не обязательно содержит счётчик .
Циклы бывают:
- Цикл cо счётчиком , в котором некоторая переменная изменяет своё значение от заданногоначального значения до конечного значения с некоторым шагом , и для каждого значения этой переменной тело цикла выполняется один раз. Реализуется оператором for
Пример. Заполнить массив :
А так можно заполнить двумерный массив:
- Цикл с предусловием , который выполняется пока истинно некоторое условие, указанное перед его началом. Реализуется оператором while .
- Цикл с постусловием , в котором условие проверяется после выполнения тела цикла, а, значит, тело всегда выполняется хотя бы один раз. В языке Паскаль этот цикл реализует оператор repeat...until
Существует операция пропуска итерации , когда в текущей итерации цикла необходимо пропустить все команды до конца тела выполняемого цикла. При этом сам цикл прерываться не должен, условия продолжения или выхода должны вычисляться обычным образом. Реализуется оператором continue .
Также в циклах нередко используется команда досрочного выхода из цикла , например, когда при выполнении тела цикла обнаруживается ошибка, после которой дальнейшая работа цикла не имеет смысла. Реализуется оператором EXIT или break .
Вернемся к началу, а точнее к в начале примеру . Нам нужно определить, что делает данный кусочек программы:
Исходя из вышесказанного, используемый двумерный массив А - это матрица размером n x n . Цикл используется со счетчиком от единицы до n , видимо определенной ранее.
Внутри цикла: переменная с получает значение двумерного массива с индексом (c:= A ),сначала это . Затем на место этого элемента массива заносится значение элемента того же массива, но с индексом (A:= A ), или при k:=1 (A:= A ). Т.е. заносятся элементы первой строки, т.к. первое число в индексе отвечает за номер строки в матрице - [i ,j], а второе за номер столбца - . И в конце, на место элемента с индексом , заносится первоначальное значение элемента массива А с индексом , которое мы занесли в переменную с (A:=c ).
И с каждой итерацией нашего цикла значение i увеличивается на единицу . Проследим по шагам. Сначала это :
с:=A A:=A A:=c
с:=A A:=A A:=c
с:=A A:=A A:=c
И так n раз до . Т.е. значение диагонали матрицы направления слева направо и сверху вниз. И элементы этой диагонали меняются значениями с элементами первой стоки матрицы (или k -той строки). Значит, правильный ответ - вариант 3 : данный алгоритм меняет местами элементы диагонали и k -го столбца таблицы .