Как вводить двумерный массив. Двумерные массивы

При решении задач с большим количеством данных одинакового типа использование переменных с различными именами, не упорядоченных по адресам памяти, затрудняет программирование. В подобных случаях в языке Си используют объекты, называемые массивами.

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

Массив характеризуется следующими основными понятиями:

Элемент массива (значение элемента массива) – значение, хранящееся в определенной ячейке памяти, расположенной в пределах массива, а также адрес этой ячейки памяти.
Каждый элемент массива характеризуется тремя величинами:

  • адресом элемента — адресом начальной ячейки памяти, в которой расположен этот элемент;
  • индексом элемента (порядковым номером элемента в массиве);
  • значением элемента.

Адрес массива – адрес начального элемента массива.

Имя массива – идентификатор, используемый для обращения к элементам массива.

Размер массива – количество элементов массива

Размер элемента – количество байт, занимаемых одним элементом массива.

Графически расположение массива в памяти компьютера можно представить в виде непрерывной ленты адресов.

Представленный на рисунке массив содержит 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 -го столбца таблицы .