русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Процедура перемещения данных Move


Дата добавления: 2015-06-12; просмотров: 671; Нарушение авторских прав


Процедура Move в некотором роде — уникальная. Она практически не имеет аналогов в стандартах языков высокого уровня. По своей сути она скорее является командой машинного уровня. Процедура содержит три параметра:

Move( VAR Source, Dest; NBytes : Word )

и служит для перемещения в ОЗУ блоков данных размером NBytes. Начало блока задается переменной Source любого типа (первый байт блока соответствует первому байту значения Source). Переменная Dest, точнее задаваемый ею первый байт, указывает на место в {301} памяти, начиная с которого будет размещен блок. Длина блока должна измеряться в байтах.

Очень эффективно работает процедура Move в различных трюках программистов, таких как копирование области видеопамяти (см. пример к процедуре Keep модуля DOS). Но не менее эффективно ее можно использовать и в более традиционных задачах. Например, копирование массива B в массив A:

А := В;

может быть выполнено процедурой

Move( В, A, SizeOf( В ) );

т.е. блок байтов — значений массива B соответствующего размера — будет скопирован в область памяти, занимаемую массивом A. В этом случае применение Move не дает особого эффекта. Но если, например, нам надо скопировать одну структуру в другую, причем сами структуры — разнотипные, то Move позволяет проделать это максимально просто и с наибольшим быстродействием (рис. 14.5). В этом случае не надо уже беспокоиться об индексах, а надо только указать размер копируемого блока.

VAR R : RECORD { запись R : } X, Y :Integer; { поля-числа } Arr : Array [ 20..120 ] of Real; { поле-массив } S :String { поле-строка } END; A : Array [ 1..500 J of Real; { массив А } i : Word; BEGIN {"Традиционное" решение: for i:=20 to 120 do A[ i-19 ] := R.Arr[ i ]; } { Оптимальное решение : } Move( R.Arr, A, SizeOf( R.Arr ) ); END.

Рис. 14.5



Еще одна область приложения, где Move эффективнее прочих способов — это перемещение значений (сдвиг) внутри одного массива. Пусть, к примеру, объявлен массив

VAR

A : Array[ 1..10000 ] of Real; {302}

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

for i:=1 to 1000 do A[ i+100] := A[ i ];

который лишь испортит данные массива A. Это произойдет из-за перекрытия исходного и конечного отрезков значений (рис. 14.6).

A[1] A[1000] A[10000]

┌─────────┼───────────────┼──────────────────────── − ──┐

½ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ï

└─────────┼───────────────┼──────────────────────── − ──┘

½ ½

A[1] A[100] ½ A[1100] A[10000]

┌─────────┼───────────────┼──────────────────────── − ──┐

½▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ï

└─────────┼───────────────┼──────────────────────── − ──┘

├───перекрытие────┤

▒ — перемещаемые элементы массива

Рис. 14.6

Здесь элементы, начиная со 101-го, будут замещены раньше, чем скопированы! Корректный цикл FOR должен быть убывающим:

for i:=1000 downto 1 do A[ i+100 ] := А[ i ];

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

Move( А[ 1 ], А[ 101 ], 1000 * SizeOf( Real ) );

При этом проблема перекрытия снимается автоматически самой процедурой Move (она выбирает направление копирования исходя из заданных параметров). Параметры A[1] и A[101] в вызове имеют смысл не значений 1-го и 101-го элементов массива A, а адресов этих элементов в памяти.

Если же понадобится вернуть 1000 элементов «назад» в первую позицию массива, вызов будет таким:

Move( А[ 101 ], А[ 1 ], 1000 * SizeOf( Real ) );

и проблема перекрытия вновь будет решена автоматически.

Помните, что никаких проверок на корректность значений параметров в Move не происходит, и если значение длины блока больше, чем может вместить переменная — адрес назначения (второй параметр Move), то будет заполнена часть памяти, отведенная под другие {303}

данные, что весьма неприятно. Советуем использовать функцию SizeOf для вычисления длин блока. Выражения типа 1000*SizeOf (Real) состоят из констант и могут быть вычислены еще во время компиляции программы, так что длинные арифметические последовательности в вызове Move ничуть не замедляют работу программ.



<== предыдущая лекция | следующая лекция ==>
Процедура заполнения FillChar | Функции обработки машинных слов Lo, Hi и Swap


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 5.714 сек.