Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Turbo Pascal / Stud_1_1 / LecRus / MainPart.doc
Скачиваний:
117
Добавлен:
03.03.2016
Размер:
5.03 Mб
Скачать

Процедура заполнения FillChar

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

FillChar(Var V; N:word; b:byte)

или FillChar(Var V; N:word; ch:char).

Здесь V - переменная любого типа;

N - количество байтов в поле V, которые заполняются значением b или ch.

Поскольку после имени формальной переменной V не записано имя типа, то этой переменной может соответствовать фактический параметр любого типа.

Предположим, что нам требуется обнулить целочисленный массив A и вещественный массив B. В цикле это можно сделать следующим образом:

Const NaMax = 1000; MbMax = 25; NbMax = 30;

Type Ar = array[1..Namax] of integer;

Matrix = array[0..MbMax,1..NbMax] of real;

Var i,j : word;

A : Ar;

B : Matrix;

Begin

For i:=1 to NaMax do

a[i]:=0;

For i:=0 to MbMax do

For j:=1 to NbMax do

b[i,j]:=0;

Однако более эффективно (по быстродействию и требуемому объему памяти) эта задача решается с помощью процедуры FillChar:

FillChar(A,SizeOf(A),0); FillChar(B,SizeOf(B),0).

Здесь процедура FillChar заполняет каждый байт полей A и B нулевым значением.

Если в массиве A нужно обнулить только элементы 101 .. 500, а в матрице B - ее первые две строки, то это можно сделать следующим образом:

FillChar(A[101],400*SizeOf(integer),0);

FillChar(B,2*NbMax*SizeOf(real),0).

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

FillChar(A,SizeOf(A),1)

каждому элементу массива A будет присвоено значение 257, а не 1 ( = 00010001 ).

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

Пример.

Var S1 : string[80];

S2 : string;

Begin

FillChar(S1,SizeOf(S1),' '); S1[0]:=chr(80);

FillChar(S2[1],100,#32); S2[0]:=chr(100);

Так как SizeOf(S1) = 81, то процедура FillChar заполняет пробелом все байты строки S1, в том числе и нулевой байт. После этого в нулевой байт принудительно заносится текущая длина строки. При отсутствии оператора S1[0]:=chr(80) в нулевой байт S1[0], как и в другие байты строки S1, будет занесен пробел, номер которого по таблице ASCII равен 32. Следовательно, при дальнейшей обработке строки S1 будет считаться, что ее длина равна 32 символам.

В строке S2 заполнение пробелом начинается с адреса S2[1], т.е. с первого ее символа. Поскольку содержимое нулевого байта при этом не изменилось (в данном случае оно осталось неопределенным), то оператором присваивания формируется конкретное значение текущей длины строки S2.

Каждый байт строки, в том числе и нулевой байт, рассматривается как символ. В связи с этим нельзя указывать текущую длину строки оператором S1[0] := 80.

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

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

Move(Var Source,Dest; n:word),

где Source - имя исходного поля памяти (источник данных);

Dest - имя конечного поля памяти (приемник данных);

n - количество байтов перемещаемых данных.

Пример 1. Даны два однотипных массива. Присвоить элементам одного из этих массивов значения элементов другого массива.

Const Nmax = 1000;

Type Ar = array[1..Nmax] of real;

Var i : word;

A,B : Ar;

Begin

A:=B;

Эту же работу можно выполнить процедурой Move(B,A,SizeOf(A)).

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

Пример 2. Элементам 101 .. 500 массива A присвоить значения элементов 401 .. 800 массива B.

Варианты решения:

a) For i:=101 to 500 do

a[i]:=b[i+300];

б) Move(B[401],A[101],400*SizeOf(real)).

Второй вариант более эффективен по сравнению с первым.

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

Const Nmax = 1000;

Type Ar1 = array[1..Nmax] of real;

Ar2 = array[1..Nmax] of real;

Var i : word;

A : Ar1; B : Ar2;

Begin

Варианты решения:

a) For i:=1 to 1000 do

a[i]:=b[i];

б) Move(B,A,SizeOf(A)).

Оператор присваивания A := B в данном случае недопустим, так как массивы A и B формально имеют различные имена типов.

Процедура Move эффективно работает также при сдвиге элементов массива.

Пример 4. Элементы массива A, начиная с , сдвинуть на две позиции влево.

Type Ar1 = array[1..1000] of real;

Var i : word;

A : Ar1;

Begin

a) For i:=101 to 1000 do

a[i-2]:=a[i];

б) Move(a[101],a[99],900*SizeOf(real)).

Пример 5. То же, но на две позиции вправо.

a) For i:=1000 downto 103 do

a[i]:=a[i-2];

б) Move(a[101],a[103],898*SizeOf(real)).

Пример 6. Из массива X(n) удалить подмассив элементов с индексами от k1 до k2 .

Решение:

Move(x[k2+1],x[k1],(n-k2)*SizeOf(real))

Dec(n,k2-k1+1);

Здесь

m = n-k2 – количество переносимых элементов;

k = k2-k1+1 – количество удаляемых элементов.

Соседние файлы в папке LecRus