Tw-city.info

IT Новости
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Программирование на c массивы

Массивы

Ярким примером ссылочного типа данных являются массивы (как объекты!).

Массив представляет собой совокупность переменных одного типа с общим для обращения к ним именем.
В C# массивы могут быть как одномерными, так и многомерными.
Массивы служат самым разным целям, поскольку они предоставляют удобные средства для объединения связанных вместе переменных.
Массивами в C# можно пользоваться практически так же, как и в других языках программирования.
Тем не менее, у них имеется одна особенность: они реализованы в виде объектов. Смотрите также заметку «Массивы. Класс System.Array».
Объединение данных возможно и в коллекции, об этом — в статье Класс ArrayList. Пример необобщенной коллекции

Объявление массивов

Для того чтобы воспользоваться массивом в программе, требуется двухэтапная процедура. Во-первых, необходимо объявить переменную, которая может обращаться к массиву. И во-вторых, нужно создать экземпляр массива (объект), используя оператор new.

Важно! Если массив только объявляется, но явно не инициализируется, каждый его элемент будет установлен в значение, принятое по умолчанию для соответствующего типа данных (например, элементы массива типа bool будут устанавливаться в false, а элементы массива типа int — в 0). В примере, если мы удалим строки с инициализацией, будет напечатано пять нулей.

Примечание. Такие же действия с полями объекта-структуры выполняет конструктор по умолчанию (без параметров).

Доступ к элементам массива

Для обращения к элементам массива используются индексы . Индекс представляет номер элемента в массиве, при этом нумерация начинается с нуля, поэтому индекс первого элемента будет равен 0. А чтобы обратиться к пятому элементу в массиве, нам надо использовать индекс 4, к примеру: myArr[4] .

Инициализация массива

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

Для этого необходимо перечислить включаемые в массив элементы в фигурных скобках < >. Такой синтаксис удобен при создании массива известного размера, когда нужно быстро задать его начальные значения:

1) инициализация массива с использованием ключевого слова new:
int[] m1 = new int[] <10,20,30,40,50>;

2) инициализации строкового массива без использования слова new:
string[] m2 = < «Фамилия», «Имя», «Отчество» >;

3) используем ключевое слово new и желаемый размер массива символов:
char[] m3 = new char[4] < ‘Я’,’з’,’ы’,’к’ >;

Обратите внимание, что в случае применения синтаксиса с фигурными скобками размер массива указывать не требуется (как видно на примере создания переменной m1), поскольку этот размер автоматически вычисляется на основе количества элементов внутри фигурных скобок.

Кроме того, применять ключевое слово new не обязательно (как при создании массива m2).

Неявно типизированные массивы

Ключевое слово var позволяет определить переменную так, чтобы лежащий в ее основе тип выводился компилятором. Аналогичным образом можно также определять неявно типизированные локальные массивы. С использованием такого подхода можно определить новую переменную массива без указания типа элементов, содержащихся в массиве.

Результат:

Разумеется, как и при создании массива с использованием явного синтаксиса C#, элементы, указываемые в списке инициализации массива, должны обязательно иметь один и тот же базовый тип (т.е. должны все быть int, string или char). Обратите внимание на метод GetType(), позволяющий программным путем определять тип элементов массива.

Определение массива объектов

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

Хотя на первый взгляд это выглядит довольно понятно, существует одна важная особенность. В основе каждого типа в системе типов .NET (в том числе фундаментальных типов данных) в конечном итоге лежит базовый класс System.Object.

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

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

Результат:

Обратите внимание на четвертый тип цикла foreach (object me in arrByObject). Легко запомнить: Для каждого (for each) объекта с именем me, входящего в (in) массив arrByObject (учите английский!). На печать выводится как сам объект (элемент массива объектов), так и тип этого объекта (метод GetType(), присущий всем объектам класса Object, от которого наследуются все типы).

Свойство Length

Реализация в C# массивов в виде объектов дает целый ряд преимуществ. Одно из них заключается в том, что с каждым массивом связано свойство Length, содержащее число элементов, из которых может состоять массив. Следовательно, у каждого массива имеется специальное свойство, позволяющее определить его длину.

Когда запрашивается длина многомерного массива, то возвращается общее число элементов, из которых может состоять массив. Благодаря наличию у массивов свойства Length операции с массивами во многих алгоритмах становятся более простыми, а значит, и более надежными.

Вставим в предыдущем примере перед Console.ReadKey() оператор
Console.WriteLine(arrByObject.Length);
Будет напечатано значение, равное 4 (число объектов в массиве). Чаще всего оно используется для задания числа элементов массива в цикле for<>.

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

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

Двумерные массивы. Простейшей формой многомерного массива является двумерный массив. Местоположение любого элемента в двумерном массиве обозначается двумя индексами. Такой массив можно представить в виде таблицы, на строки которой указывает первый индекс, а на столбцы — второй. Пример объявления и инициализации двумерного массива показан ниже:

Обратите особое внимание на способ объявления двумерного массива. Схематическое представление массива myArr[,] показано ниже:

Заметим, что в программе используется еще один объект – ran, принадлежащий к классу Random, метод которого (функция Next() ) возвращает целое число в заданном диапазоне (1,15).

В C# допускаются массивы трех и более измерений. Ниже приведена общая форма объявления многомерного массива:
тип[,…,] имя_массива = new тип[размер1, размер2, … размеры];

Инициализация многомерных массивов

Для инициализации многомерного массива достаточно заключить в фигурные скобки список инициализаторов каждого его размера:
тип[,] имя_массива = <
,
< val, val, val, …, val>,

>;
где val обозначает инициализирующее значение, а каждый внутренний блок — отдельный ряд.

Первое значение в каждом ряду сохраняется на первой позиции в массиве, второе значение — на второй позиции и т.д.

Обратите внимание на то, что блоки инициализаторов разделяются запятыми, а после завершающей эти блоки закрывающей фигурной скобки ставится точка с запятой.

Ниже в качестве примера приведена общая форма инициализации двумерного массива (4 строки, 2 столбца):

Перейдем к рассмотрению примеров решения задач, где применяются массивы и циклы.

Задача «Три цикла»

Требуется найти сумму и произведение N элементов массива, используя три варианта циклов (for, while, do-while).
Решение. В классе Program объявим статический массив действительных чисел a[1000] и 7 методов (кроме Main()), ввод исходных данных и вычисление сумм и произведений с использованием трех типов циклов.

Тогда наша программа может быть написана так:

Результат:

Задание. Сравните алгоритмы вычисления суммы и произведения и циклы между собой, найдите общее и различия.

Оператор foreach

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

Результат:

Задачи, предполагающие использование массивов и циклов, подробно рассмотрены в разделе «Примеры решения задач на тему «Массивы строки»»

Перейдем к рассмотрению объектов, относящихся к классу String (строка).

ITandLife.ru

Статьи об IT, программировании, политике, экономике, жизни и изучении научных дисциплин

Массивы в C++

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

Описание массива в программе отличается от описания простой переменной наличием после имени квадратных скобок, в которых задается количество элементов массива (размерность):

float а [ 10 ] ; // описание массива из 10 вещественных чисел

Элементы массива нумеруются с нуля. При описании массива используются те же модификаторы (класс памяти, const и инициализатор), что и для простых переменных. Инициализирующие значения для массивов записываются в фигурных скобках. Значения элементам присваиваются по порядку. Если элементов в массиве больше, чем инициализаторов, элементы, для которых значения не указаны, обнуляются:

int b [ 5 ] = < 3 , 2 , 1 >; / / b [ 0 ] = 3 , b [ l ] = 2 , b [ 2 ] = l, b [ 3 ] = 0 , b [ 4 ] = 0

Размерность массива вместе с типом его элементов определяет объем памяти, необходимый для размещения массива, которое выполняется на этапе компиляции, поэтому размерность может быть задана только целой положительной константой или константным выражением. Если при описании массива не указана размерность, должен присутствовать инициализатор, в этом случае компилятор выделит память по количеству инициализирующих значений. В дальнейшем мы увидим, что размерность может быть опущена также в списке формальных параметров.

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

#include
int main ( ) <
const int n = 10 ;
int i,. sum ;
int marks [ n ] = < 3 , 4 , 5 , 4 , 4 >;
for ( i = 0 , sum = 0 ; i

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

Пример. Сортировка целочисленного массива методом выбора. Алгоритм состоит в том, что выбирается наименьший элемент массива и меняется местами с первым элементом, затем рассматриваются элементы, начиная со второго, и наименьший из них меняется местами со вторым элементом, и так далее n-1 раз (при последнем проходе цикла при необходимости меняются местами предпоследний и последний элементы массива).

Идентификатор массива является константным указателем на его нулевой элемент. Например, для массива из предыдущего листинга имя b — это то же самое, что &Ь[0], а к i-му элементу массива можно обратиться, используя выражение *(b+1). Можно описать указатель, присвоить ему адрес начала массива и работать с массивом через указатель. Следующий фрагмент программы копирует все элементы массива а в массив b:

int а [ 100 ] , b [ 100 ] :
int * ра = а ; // или int *р = &а[0];
int * pb = b ;
for ( int i = 0 ; i * pa ++ ; // или pb[1] = pa[1];

Динамические массивы

Динамические массивы создают с помощью операции new, при этом необходимо указать тип и размерность, например:

int п = 100 :
float * р = new float [ n ] ;

В этой строке создается переменная-указатель на float, в динамической памяти отводится непрерывная область, достаточная для размещения 100 элементов вещественного типа, и адрес ее начала записывается в указатель р. Динамические массивы нельзя при создании инициализировать, и они не обнуляются.

Преимущество динамических массивов состоит в том, что размерность может быть переменной, то есть объем памяти, выделяемой под массив, определяется на этапе выполнения программы. Доступ к элементам динамического массива осуществляется точно так же, как к статическим, например, к элементу номер 5 приведенного выше массива можно обратиться как р[5] или *(р+5).

Альтернативный способ создания динамического массива — использование функции mallос библиотеки С:

int n = 100 ;
float * q = ( float * ) malloc ( n * sizeof ( float ) ) ;

Операция преобразования типа, записанная перед обращением к функции mallос, требуется потому, что функция возвращает значение указателя тина void*, а инициализируется указатель на float.

Память, зарезервированная под динамический массив с помощью new [], должна освобождаться оператором delete [], а память, выделенная функцией mallос — посредством функции free, например:

delete [ ] р ; free ( q ) ;

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

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

Многомерные массивы задаются указанием каждого измерения в квадратных скобках, например, оператор

int matr [ 6 ] [ 8 ] ;

задает описание двумерного массива из 6 строк и 8 столбцов. В памяти такой массив располагается в последовательных ячейках построчно. Многомерные массивы размещаются так, что при переходе к следующему элементу быстрее всего изменяется последний индекс. Для доступа к элементу многомерного массива указываются все его индексы, например, matr[i][j], или более экзотическим способом: * ( matr [ i ] + j ) или * ( * ( matr + i ) + j ) . Это возможно, поскольку matr[i] является адресом начала i-й строки массива.

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

int mass2 [ ] [ 2 ] = < < 1 , 1 >, < 0 , 2 >, < 1 , 0 >> :
int mass2 [ 3 ] [ 2 ] =

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

Номер искомой строки хранится в переменной istr, количество нулевых элементов в текущей (i-й) строке — в переменной Kol, максимальное количество нулевых элементов — в переменной MaxKol. Массив просматривается по строкам, в каждой из них подсчитывается количество нулевых элементов (обратите внимание, что переменная Kol обнуляется перед просмотром каждой строки). Наибольшее количество и номер соответствующей строки запоминаются.

Для создания динамического многомерного массива необходимо указать в операции new все его размерности (самая левая размерность может быть переменной), например:

int nstr = 5 :
int ** m = ( int ** ) new int [ nstr ] [ 10 ] ;

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

int nstr, nstb ;
cout > nstr >> nstb ;
int ** a = new int * [ nstr ] ; // 1
for ( int i = 0 ; i

В операторе 1 объявляется переменная типа «указатель на указатель на int» и выделяется память под массив указателей на строки массива (количество строк — nstr). В операторе 2 организуется цикл для выделения памяти под каждую строку массива. В операторе 3 каждому элементу массива указателей на строки присваивается адрес начала участка памяти, выделенного под строку двумерного массива. Каждая строка состоит из nstb элементов типа int.

Освобождение памяти из-под массива с любым количеством измерений выполняется с помощью операции delete [ ] . Указатель на константу удалить нельзя.

Строки как массивы символов

Строка представляет собой массив символов, заканчивающийся нуль-символом. Нуль-символ — это символ с кодом, равным О, что записывается в виде управляющей последовательности ‘’. По положению нуль-символа определяется фактическая длина строки. Строку можно инициализировать строковым литералом.

char str [ 10 ] = «Vasia» ;
// выделено 10 элементов с номерами от 0 до 9
// первые элементы — ‘V’, ‘а’, ‘s’, ‘i’, ‘а’, ‘’

В этом примере под строку выделяется 10 байт, 5 из которых занято под символы строки, а шестой — под нуль-символ. Если строка при определении инициализируется, ее размерность можно опускать (компилятор сам выделит соответствующее количество байт):

char str [ ] = «Vasia» ; // выделено и заполнено 6 байт

char * str = «Vasia»

создает не строковую переменную, а указатель на строковую константу, изменить которую невозможно (к примеру, оператор str[l]=’o’ не допускается). Знак равенства перед строковым литералом означает инициализацию, а не присваивание. Операция присваивания одной строки другой не определена (поскольку строка является массивом) и может выполняться с помощью цикла или функций стандартной библиотеки. Библиотека предоставляет возможности копирования, сравнения, объединения строк, поиска подстроки, определения длины строки и т. д., а также содержит специальные функции ввода строк и отдельных символов с клавиатуры и из файла.

При работе со строками часто используются указатели.

Существует несколько способов работы со строками (через массивы или указатели) и они имеют свои плюсы и минусы, но в общем случае лучше не изобретать велосипед, а пользоваться функциями библиотеки или определенным в стандартной библиотеке C++ классом string, который обеспечивает индексацию, присваивание, сравнение, добавление, объединение строк и поиск подстрок, а также преобразование из С-строк, то есть массивов типа char, в string, и наоборот.

По материалам книги Т.А. Павловской «СС++. Программирование на языке высокого уровня».

Массив в языке программирования C#

Массив – это коллекция однотипных данных, рассматриваемая как одно целое. То есть, мы определяем набор переменных одного типа, и можем обращаться к ним всем с помощью одного общего имени, а также при необходимости обратиться к каждому конкретному элементу. Массивы позволяют комфортно манипулировать наборами связанных данных. Массив можно представить себе как поезд. Каждый вагон представляет собой переменную. Вагоны сцеплены между собой, и мы можем рассматривать весь поезд как единое целое.

Что такое массив

Массивы бывают различной размерности. Но на практике чаще всего используются одномерные и двумерные массивы, максимум трехмерные. Массивы большей размерности встречаются достаточно редко.

Объявление массива задается в следующем формате

Теперь мы можем записать значения в него. Это называется инициализация. Обратите внимание, что нумерация элементов массива ведется с нуля.

Мы можем сократить количество кода, объединив объявление и инициализацию массива, если все исходные данные заранее известны.

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

Двумерный массив C#

Для объявления многомерного массива необходимо указывать его размерность при объявлении. Например, для объявления двумерного массива необходимо написать следующее:

И соответственно для обращения к элементам необходимо указывать адрес в двух измерениях:

Для массивов большей размерности соответственно необходимо использовать больше измерений, но это не очень удобно и не рекомендуется.

Массив массивов

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

Объявление массива массивов (его еще называют зубчатый массив) немного отличается от объявления обычного массива.

Перебор цикла

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

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

Для перебора массива удобнее всего использовать специализированный цикл для коллекций foreach. Он позволяет перебрать все элементы коллекции, не беспокоясь о выходе за границы. Кроме того, он позволяет сократить количество написанного кода

При необходимости можно использовать и другие циклы. Например аналогичное поведение мы можем записать и с помощью цикла for

и с помощью цикла while

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

Заключение

В данной статье мы рассмотрели основы работы с массивами в языке программирования C#. Исходный код доступен в репозитории GitHub. Предыдущая статья Основы C#. Коментарии и переменные. А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.

Дадим формальное определение:

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

Для того чтобы разобраться в возможностях и особенностях обработки массивов в программах на ассемблере, нужно ответить на следующие вопросы:

· Как описать массивв программе?

· Как инициализировать массив, то есть как задать начальные значения его элементов?

· Как организовать доступк элементам массива?

· Как организовать массивыс размерностью более одной?

· Как организовать выполнениетиповых операций с массивами?

Описание и инициализация массива в программе

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

1. Перечислением элементов массива в поле операндов одной из директив описания данных. При перечислении элементы разделяются запятыми. К примеру:

;массив из 5 элементов.Размер каждого элемента 4 байта:

2. Используя оператор повторения dup. К примеру:

;массив из 5 нулевых элементов.

;Размер каждого элемента 2 байта:

Такой способ определения используется для резервирования памяти с целью размещения и инициализации элементов массива.

3. Используя директивы labelиrept. Пара этих директив может облегчить описание больших массивов в памяти и повысить наглядность такого описания. Директиваreptотносится к макросредствам языка ассемблера и вызывает повторение указанное число раз строк, заключенных между директивой и строкой endm. К примеру, определим массив байт в области памяти, обозначенной идентификаторомmas_b. В данном случае директиваlabelопределяет символическое имяmas_b, аналогично тому, как это делают директивы резервирования и инициализации памяти. Достоинство директивыlabelв том, что она не резервирует память, а лишь определяет характеристики объекта. В данном случае объект — это ячейка памяти. Используя несколько директивlabel, записанных одна за другой, можно присвоить одной и той же области памяти разные имена и разный тип, что и сделано в следующем фрагменте:

mas_b label byte

mas_w label word

В результате в памяти будет создана последовательность из четырех слов f1f0. Эту последовательность можно трактовать как массив байт или слов в зависимости от того, какое имя области мы будем использовать в программе —mas_bилиmas_w.

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

5. Посмотрим на примере листинга 2, каким образом это делается.

Листинг 2 Инициализация массива в цикле

mes db 0ah,0dh,’Массив- ‘,’$’

mas db 10 dup (?) ;исходный массив

xor ax,ax ;обнуление ax

mov cx,10 ;значение счетчика цикла в cx

mov si,0 ;индекс начального элемента в cx

go: ;цикл инициализации

mov mas[si],bh ;запись в массив i

inc i ;инкремент i

inc si ;продвижение к следующему элементу массива

loop go ;повторить цикл

;вывод на экран получившегося массива

mov ah,02h ;функция вывода значения из al на экран

add dl,30h ;преобразование числа в символ

mov ax,4c00h ;стандартный выход

end main ;конец программы

Доступ к элементам массива

При работе с массивами необходимо четко представлять себе, что все элементы массива располагаются в памяти компьютера последовательно.

Само по себе такое расположение ничего не говорит о назначении и порядке использования этих элементов. И только лишь программист с помощью составленного им алгоритма обработки определяет, как нужно трактовать эту последовательность байт, составляющих массив. Так, одну и ту же область памяти можно трактовать как одномерный массив, и одновременно те же самые данные могут трактоваться как двухмерный массив. Все зависит только от алгоритма обработки этих данных в конкретной программе. Сами по себе данные не несут никакой информации о своем “смысловом”, или логическом, типе. Помните об этом принципиальном моменте.

Эти же соображения можно распространить и на индексы элементов массива. Ассемблер не подозревает об их существовании и ему абсолютно все равно, каковы их численные смысловые значения.

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

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

Пусть эта последовательность чисел трактуется как одномерный массив. Размерность каждого элемента определяется директивой dw, то есть она равна2байта. Чтобы получить доступ к третьему элементу, нужно к адресу массива прибавить6. Нумерация элементов массива в ассемблере начинается с нуля.

То есть в нашем случае речь, фактически, идет о 4-м элементе массива — 3, но об этом знает только программист; микропроцессору в данном случае все равно — ему нужен только адрес.

В общем случае для получения адреса элемента в массиве необходимо начальный (базовый) адрес массива сложить с произведением индекса (номер элемента минус единица) этого элемента на размер элемента массива:

база + (индекс*размер элемента)

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

· индексная адресация со смещением — режим адресации, при котором эффективный адрес формируется из двух компонентов:

o постоянного (базового)— указанием прямого адреса массива в виде имени идентификатора, обозначающего начало массива;

o переменного (индексного)— указанием имени индексного регистра.

;поместить 3-й элемент массива mas в регистр ax:

· базовая индексная адресация со смещением — режим адресации, при котором эффективный адрес формируется максимум из трех компонентов:

o постоянного(необязательный компонент), в качестве которой может выступать прямой адрес массива в виде имени идентификатора, обозначающего начало массива, или непосредственное значение;

o переменного (базового)— указанием имени базового регистра;

o переменного (индексного)— указанием имени индексного регистра.

Этот вид адресации удобно использовать при обработке двухмерных массивов. Пример использования этой адресации мы рассмотрим далее при изучении особенностей работы с двухмерными массивами.

Напомним, что в качестве базового регистра может использоваться любой из восьми регистров общего назначения. В качестве индексного регистра также можно использовать любой регистр общего назначения, за исключением esp/sp.

Микропроцессор позволяет масштабировать индекс. Это означает, что если указать после имени индексного регистра знак умножения “*” с последующей цифрой 2, 4 или 8, то содержимое индексного регистра будет умножаться на 2, 4 или 8, то есть масштабироваться.

Применение масштабирования облегчает работу с массивами, которые имеют размер элементов, равный 2, 4 или 8 байт, так как микропроцессор сам производит коррекцию индекса для получения адреса очередного элемента массива. Нам нужно лишь загрузить в индексный регистр значение требуемого индекса (считая от 0). Кстати сказать, возможность масштабирования появилась в микропроцессорах Intel, начиная с модели i486. По этой причине в рассматриваемом здесь примере программы стоит директива .486. Ее назначение, как и ранее использовавшейся директивы.386, в том, чтобы указать ассемблеру при формировании машинных команд на необходимость учета и использования дополнительных возможностей системы команд новых моделей микропроцессоров.

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

Листинг 3. Просмотр массива слов с использованием

C++. Операции над массивами

Вычисление суммы элементов массива

Дан массив X, состоящий из n элементов. Найти сумму элементов этого массива. Процесс накапливания суммы элементов массива достаточно прост и практически ничем не отличается от суммирования значений некоторой числовой последовательности. Переменной S присваивается значение равное нулю, затем последовательно суммируются элементы массива X. Блок-схема алгоритма расчета суммы перед вами:

Соответствующий фрагмент алгоритма программы будет иметь вид:

Сортировка элементов в массиве

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

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

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

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

Сортировка методом «пузырька»

Данный метод является наиболее популярным. Возможно это из за того, что название (метод пузырька) хорошо запоминается и сам алгоритм достаточно прост. Здесь используется метод обменной сортировки, который мы рассмотрим более подробно.

Сравним нулевой элемент массива с первым, если нулевой окажется больше первого, то поменяем их местами. Те же действия выполним для первого и второго, второго и третьего, i-го и (i+1)-го, предпоследнего и последнего элементов. В результате этих действий самый большой элемент станет на (n-1)-е место. Теперь повторим данный алгоритм сначала, но последний элемент рассматривать не будем. После проведения данной операции самый большой элемент оставшегося массива станет на (n-2)-е место. Так нужно повторять до тех пор, пока не упорядочим весь массив. Блок-схема алгоритма:

Обратите внимание на то, что для перестановки элементов используется буферная переменная b, в которой временно хранится значение элемента, подлежащего замене.

Также, думаю стоит продемонстрировать текст программы, сортирующей элементы массива по возрастанию методом «пузырька»:

Читать еще:  Асинхронное программирование c
Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector