на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Массивы. Двумерные массивы
p align="left">Пример программы вывода двумерного массива Паскаля

for i :=1 to 5 do {цикл для перебора всех строк}

begin

for j :=1 to 10 do {перебор всех элементов строки по столбцам}

write ( a [ i , j ]:4); {печать элементов, стоящих в i -й строке матрицы в одной экранной строке, при этом для вывода каждого элемента отводится 4 позиции}

writeln ; {прежде, чем сменить номер строки в матрице, нужно перевести курсор на начало новой экранной строки}

end ;

Замечание (это важно!): очень часто в программах студентов встречается ошибка, когда ввод с клавиатуры или вывод на экран массива пытаются осуществить следующим образом: readln (a), writeln (a), где а - это переменная типа массив. При этом их удивляет сообщение компилятора, что переменную этого типа невозможно считать или напечатать. Может быть, вы поймете, почему этого сделать нельзя, если представите N кружек, стоящих в ряд, а у вас в руках, например, чайник с водой. Можете вы по команде «налей воду» наполнить сразу все кружки? Как бы вы ни старались, но в каждую кружку придется наливать отдельно. Заполнение и вывод на экран элементов массива также должно осуществляться последовательно и поэлементно, т.к. в памяти ЭВМ элементы массива располагаются в последовательных ячейках.

Представление двумерного массива Паскаля в памяти

Элементы абстрактного массива в памяти машины физически располагаются последовательно, согласно описанию. При этом каждый элемент занимает в памяти количество байт, соответствующее его размеру. Например, если массив состоит из элементов типа integer , то каждый элемент будет занимать по два байта. А весь массив займет S^2 байта, где S - количество элементов в массиве.

А сколько места займет массив, состоящий из массивов, т.е. матрица? Очевидно: S i^S j , где S i - количество строк, а S j - количество элементов в каждой строке. Например, для массива типа

Matrix = array [1..3, 1..2] of integer ;

потребуется 12 байт памяти.

Как будут располагаться в памяти элементы этого массива? Рассмотрим схему размещения массива M типа matrix в памяти.

Под каждый элемент M [i,j] типа integer выделяется две ячейки памяти. Размещение в памяти осуществляется «снизу вверх». Элементы размещаются в порядке изменения индекса, что соответствует схеме вложенных циклов: сначала размещается первая строка, затем вторая, третья... Внутри строки по порядку идут элементы: первый, второй и т.д.

Как мы знаем, доступ к любой переменной возможен, только если известен адрес ячейки памяти, в которой хранится переменная. Конкретная память выделяется для переменной при загрузке программы, то есть устанавливается взаимное соответствие между переменной и адресом ячейки. Но если мы объявили переменную как массив, то программа «знает» адрес начала массива, то есть первого его элемента. Как же происходит доступ ко всем другим элементам массива?

При реальном доступе к ячейке памяти, в которой хранится элемент двумерного массива, система вычисляет ее адрес по формуле:

Addr + Size Elem * Cols *( I -1)+ Size Elem *( J -1),

где Addr - фактический начальный адрес, по которому массив располагается в памяти; I , J - индексы элемента в двумерном массиве; SizeElem - размер элемента массива (например, два байта для элементов типа integer ); Cols - количество элементов в строке.

Выражение SizeElem * Cols *( I -1)+ SizeElem *( J -1) называют смещением относительно начала массива.

Примеры решения задач с двумерными массивами Паскаля

Задача: Найти произведение ненулевых элементов матрицы.

Решение:

Для решения данной задачи нам потребуются переменные: матрица, состоящая, например, из целочисленных элементов; P - произведение элементов, отличных от 0; I , J - индексы массива; N , M - количество строк и столбцов в матрице. Входными данными являются N , M - их значения введем с клавиатуры; матрица - ввод матрицы оформим в виде процедуры, заполнение матрицы осуществим случайным образом, т.е. с помощью функции random (). Выходными данными будет являться значение переменной P (произведение). Чтобы проверить правильность выполнения программы, необходимо вывести матрицу на экран, для этого оформим процедуру вывода матрицы. Ход решения задачи:

обсудим сначала выполнение основной программы, реализацию процедур обговорим чуть позже:

введем значения N и M ; Введем двумерный массив Паскаля, для этого обращаемся к процедуре vvod ( a ), где а - матрица; Напечатаем полученную матрицу, для этого обращаемся к процедуре print ( a ); Присвоим начальное значение переменной P =1; Будем последовательно перебирать все строки I от 1-й до N -й, в каждой строке будем перебирать все столбцы J от 1-го до M -го, для каждого элемента матрицы будем проверять условие: если a ij ? 0, то произведение P будем домножать на элемент a ij ( P = P * a ij ); Выведем на экран значение произведения ненулевых элементов матрицы - P ;

А теперь поговорим о процедурах.

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

Type

Matrix=array [1..10, 1..10] of integer;

..............................

procedure primer (a: matrix);

..............................

Вернемся теперь к нашим процедурам.

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

Тогда заголовок нашей процедуры будет выглядеть так:

Procedure vvod ( var m : matrix );

Для реализации вложенных циклов в процедуре нам потребуются локальные переменные-счетчики, например, k и h . Алгоритм заполнения матрицы уже обсуждался, поэтому не будем его повторять.

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

Procedure print ( m : matrix );

И вновь для реализации вложенных циклов внутри процедуры нам потребуются счетчики, пусть они называются так же - k и h . Алгоритм вывода матрицы на экран был описан выше, воспользуемся этим описанием.

Пример программы двумерного массива Паскаля

Program proizvedenie;

Type

Matrix=array [1..10, 1..10] of integer;

Var

A: matrix;

N, m, i, j: byte;

P: integer;

Procedure vvod (var m: matrix);

Var k , h : byte ;

Begin

For i :=1 to n do {переменная n для процедуры является глобальной, а значит «известной»}

For j :=1 to m do {переменная m для процедуры является глобальной, а значит «известной»}

M[i,j]:= random(10);

End;

Procedure print (m: matrix);

Var k, h: byte;

Begin

For i:=1 to n do

begin

For j:=1 to m do

Write (M[i, j]: 4);

Writeln;

end ;

End ;

Begin {начало основной программы}

Writeln (`Введите размерность матрицы:');

Readln(N, M);

Vvod(a);

14

Print(a);

P:=1;

For i:=1 to N do

For j:=1 to M do

If a[i, j]<>0 then p:=p*a[i, j];

Writeln ( p );

End .

Методы доступа к элементам массивов

В языке СИ между указателями и массивами существует тесная связь. Например, когда объявляется массив в виде int array[25], то этим определяется не только выделение памяти для двадцати пяти элементов массива, но и для указателя с именем array, значение которого равно адресу первого по счету (нулевого) элемента массива, т.е. сам массив остается безымянным, а доступ к элементам массива осуществляется через указатель с именем array. С точки зрения синтаксиса языка указатель arrey является константой, значение которой можно использовать в выражениях, но изменить это значение нельзя.

Поскольку имя массива является указателем допустимо, например, такое присваивание:

int array[25];

int *ptr;

ptr=array;

Здесь указатель ptr устанавливается на адрес первого элемента масcива, причем присваивание ptr=arrey можно записать в эквивалентной форме ptr=&arrey[0].

Для доступа к элементам массива существует два различных способа. Первый способ связан с использованием обычных индексных выражений в квадратных скобках, например, array[16]=3 или array[i+2]=7. При таком способе доступа записываются два выражения, причем второе выражение заключается в квадратные скобки. Одно из этих выражений должно быть указателем, а второе - выражением целого типа. Последовательность записи этих выражений может быть любой, но в квадратных скобках записывается выражение следующее вторым. Поэтому записи array[16] и 16[array] будут эквивалентными и обозначают элемент массива с номером шестнадцать. Указатель используемый в индексном выражении не обязательно должен быть константой, указывающей на какой-либо массив, это может быть и переменная. В частности после выполнения присваивания ptr=array доступ к шестнадцатому элементу массива можно получить с помощью указателя ptr в форме ptr[16] или 16[ptr].

Второй способ доступа к элементам массива связан с использованием адресных выражений и операции разадресации в форме *(array+16)=3 или *(array+i+2)=7. При таком способе доступа адресное выражение равное адресу шестнадцатого элемента массива тоже может быть записано разными способами *(array+16) или *(16+array).

При реализации на компьютере первый способ приводится ко второму, т.е. индексное выражение преобразуется к адресному.

15

Для приведенных примеров array[16] и 16[array] преобразуются в *(array+16).

Для доступа к начальному элементу массива (т.е. к элементу с нулевым индексом) можно использовать просто значение указателя array или ptr. Любое из присваиваний

*array = 2;

array[0] = 2;

*(array+0) = 2;

*ptr = 2;

ptr[0] = 2;

*(ptr+0) = 2;

присваивает начальному элементу массива значение 2, но быстрее всего выполнятся присваивания *array=2 и *ptr=2, так как в них не требуется выполнять операции сложения.

Указатели на многомерные массивы

Указатели на многомерные массивы в языке СИ - это массивы массивов, т.е. такие массивы, элементами которых являются массивы. При объявлении таких массивов в памяти компьютера создается несколько различных объектов. Например при выполнении объявления двумерного массива int arr2[4][3] в памяти выделяется участок для хранения значения переменной arr, которая является указателем на массив из четырех указателей. Для этого массива из четырех указателей тоже выделяется память. Каждый из этих четырех указателей содержит адрес массива из трех элементов типа int, и, следовательно, в памяти компьютера выделяется четыре участка для хранения четырех массивов чисел типа int, каждый из которых состоит из трех элементов. Такое выделение памяти показано на схеме на arr

Распределение памяти для двумерного массива.

arr[0] а

arr[0][0]

arr[0][1]

arr[0][2]

arr[1] а

arr[1][0]

arr[1][1]

arr[1][2]

arr[2] а

arr[2][0]

arr[2][2]

arr[2][1]

arr[3] а

arr[3][0]

arr[3][1]

arr[3][2]

Страницы: 1, 2, 3, 4, 5



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.