IX.2.5. Ф у н к ц и и MKI$(), MKS$(), MKD$(), CVI(), CVS(), CVD() Вам, конечно, известно, что буферные переменные являются строковыми. Пусть γ- буферная переменная и ей командой FIELD в FCB отведено поле дли- ной m байтов. Если требуется "упаковать" в γ числовое значение,то поль- зуются функциями: ┌────────────────────────────────────────────────────────────┐ α) │ MKI$(L) │ │ где: MKI("MaKe Integer"-"преобразовать целое значение") │ │ - служебное слово; │ │ L - арифметическое выражение целого типа; │ │ m=2 │; └────────────────────────────────────────────────────────────┘ ┌────────────────────────────────────────────────────────────┐ β) │ MKS$(L) │ │ где: MKS("MaKe Single"-"преобразовать значение одинарной │ │ точности") - служебное слово; │ │ L - арифметическое выражение одинарной точности; │ │ m=4 │; └────────────────────────────────────────────────────────────┘ ┌────────────────────────────────────────────────────────────┐ γ) │ MKD$(L) │ │ где: MKD ("MaKe Double"-"преобразовать значение двойной │ │ точности") - служебное слово; │ │ L - арифметическое выражение двойной точности; │ │ m=8 │. └────────────────────────────────────────────────────────────┘ Каждая из этих функций преобразует значение арифметического выражения L к строковому типу. После этого операторами LSET или RSET эти значения можно разместить в γ и соответствующем поле буфера. Обращаем Ваше внимание на тот факт,что функции MKI$(), MKS$() и MKD$() не переводят числовые величины в эквивалентные им знаки кода ASCII, как это делается при использовании других функций. Они просто "упаковывают" соответствующие значения в два,четыре или восемь знаков по той же схеме, которая реализуется в компьютере для представления числовых величин в оперативной памяти. Именно поэтому с помощью оператора PRINT невозможно выдать на печать или экран дисплея результаты работы функций MKI$(), MKS$() и MKD$() ! П р и м е р 1. ────────────── α) функция MKI$(17217) возвращает строку "AC". Рассмотрим, как это по- лучается: 17217=&B0100001101000001=&H4341=&H43·256+&H41=67·256+65 └──────┘└──────┘ ▲ ▲ C A │ └─ Код символа "A" └──────── Код символа "C" β) MKS$(4.14141) возвращает строку "AAAA" П р и м е р 2. A$=MKI$(&HE276):PRINT HEX$(ASC(MID$(A$,1,1)));" "; ────────────── HEX$(ASC(MID$(A$,2,1))) 76 E2 Ok П р и м е р 3. 10 MAXFILES=5:OPEN "LU" AS#4 ────────────── 20 FIELD #4, 2 AS A$, 4 AS B$, 8 AS E$ 30 INPUT X%:LSET A$=MKI$(X%) 40 INPUT Y!:LSET B$=MKS$(Y!) 50 INPUT Z#:LSET E$=MKD$(Z#) 60 PRINT A$;" ";B$;" ";E$ 70 RSET A$=MKI$(X%):RSET B$=MKS$(Y!):RSET E$=MKD$(Z#) 80 PRINT A$;" ";B$;" ";E$ run ? 1096 ? 1.535 ? -3.4 H A5 a4 H A5 a4 Ok Функции MKI$(),MKS() и MKD() выполняют обратное преобразование по отно- шению к функциям CVI(), CVS() и CVD(), к рассмотрению которых мы сейчас приступаем. Пусть в буфер с дискеты считана запись и в некотором ее поле,определен- ном по команде FIELD элементом m AS γ "упаковано" числовое значение. "Распаковка" его или, выборка из γ этого значения, реализуется одной из следующих функций: ┌────────────────────────────────────────────────────────────┐ α) │ CVI(γ) │ │где: CVI("ConVert to Integer"-"преобразовать к целому")- │ │ служебное слово; │ │ γ - имя буферной переменной; │ │ m=2 │; └────────────────────────────────────────────────────────────┘ ┌────────────────────────────────────────────────────────────┐ β) │ CVS(γ) │ │где: CVS("ConVert to Single"-"преобразовать к значению оди-│ │ нарной точности") - служебное слово; │ │ γ - имя буферной переменной; │ │ m=4 │; └────────────────────────────────────────────────────────────┘ ┌────────────────────────────────────────────────────────────┐ γ) │ CVD(γ) │ │где: CVD("ConVert to Double"- "преобразовать к значению │ │ двойной точности") - служебное слово; │ │ γ - имя буферной переменной; │ │ m=8 │. └────────────────────────────────────────────────────────────┘ Эти функции преобразуют строки символов в числа. Аргумент состоит из 2, 4 или 8 байтов и преобразуется в целое число, либо число с одинарной или двойной точностью, в зависимости от вида используемой функции (CVI, CVS или CVD). П р и м е р 4. ────────────── α) print CVI("AC") print MKI$(17217) 17217 ,так как AC Ok Ok β) print CVS("GWYF") print MKS$(5759460) 5759460 ,так как GWYF Ok Ok Посмотрите на схему... "G" "W" "Y" "F" 0100 0111 0101 0111 0101 1001 0100 0110 ▲───▲──── 5 7 5 9 4 6 │ │ │ Порядок числа = &B1000111-&B1000000 = &B111 = 7 Знак числа Сравните эти результаты с представлением чисел в памяти компьютера (см. далее главу 10). П р и м е р 5. ────────────── 10 OPEN "SL" AS#1 LEN=8:FIELD #1,8 AS R$ 20 INPUT X:RSET R$=MKD$(X) 40 PRINT R$,CVD(R$) run ? 123 C0 123 Ok IX.2.6. О п е р а т о р ы PUT и GET Для пересылки ("сброса") сформированной в оперативной памяти записи на дискету используется оператор ┌────────────────┐ │ PUT [#]n[,P] │ , └────────────────┘ где: PUT ("записать", "разместить") - служебное слово; n, P - арифметические выражения, целые части значений которых зада- ют соответственно номер контрольного буфера файла и номер записи. До выполнения оператора PUT в оперативной памяти: α) оператором MAXFILES= должен быть объявлен контрольный буфер файла FCBn ; β) открыт некоторый файл В, связанный с FCBn (оператором OPEN); γ) задан формат его записей (оператором FIELD) и, наконец, δ) в FCBn создана сама запись (операторами LSET, RSET). После всей этой процедуры оператором PUT содержимое FCBn будет выве- дено под номером P на дискету, или, как говорят , с ф о р м и р о в а н а новая или о б н о в л е н а старая запись Р файла В. При открытии файла значение Р равно 0. Т е к у щ и м значением Р счи- тается номер той записи, с которой работал последний выполненный оператор PUT или GET. Далее, если в операторе PUT параметр Р не указан, то берется его текущее значение, увеличенное на 1. Например, в операторе PUT #1,3 второе число (3) определяет номер записи в файле. Если этот номер будет пропущен, то будет использовано число, на единицу большее,чем в последнем выполненном операторе PUT или GET. Номер записи может находиться в диапазоне от 1 до 4294967295, в чем Вы можете убедиться самостоятельно. П р и м е р 1. 10 REM формирование файла ────────────── 20 MAXFILES=2:OPEN"массив" AS#2 LEN=8:FIELD #2,8 AS M 50 FOR I=1 TO 30 60 INPUT"Введите число";А:LSET M=MKD$(A):PUT #2 90 NEXT 100 CLOSE #2 П р и м е р 2. 10 'Объявление FCB0, FCB1, FCB2 и FCB3 ────────────── 20 'Открытие файла "рыба" с буфером #2 30 MAXFILES=3:OPEN "Рыба" AS#2 LEN=13 40 'Определение формата записи 50 FIELD #2,8 AS L$, 5 AS M$ 60 'Формирование первых 10 записей 70 FOP K=1 TO 10 80 INPUT"X$-8";X$:INPUT"Y$-5";Y$ 90 LSET L$=X$:RSET M$=Y$:PUT #2,K 99 NEXT:END Пусть открыт некоторый файл данных, связанный с буфером FCBn. Полезную информацию о файле можно извлечь с помощью функций LOF и LOC. ┌──────────────┐ Функция │ LOF(n) │ , └──────────────┘ где: LOF ("Length Of File"-"длина файла") - служебное слово; n - арифметическое выражение, целая часть значения которого опреде- ляет номер контрольного буфера файла, возвращает размер файла, связанного с FCBn, в байтах. ┌──────────────┐ Функция │ LOC(n) │ , └──────────────┘ где: LOC ("LOCation"-"определение позиции")- служебное слово; n - арифметическое выражение, целая часть значения которого являет- ся номером файла, возвращает номер т е к у щ е й записи файла (номер записи, использован- ный в последнем выполненном операторе PUT или GET). Для считывания записей файла с дискеты в оперативную память использует- ся оператор ┌─────────────────┐ │ GET [#]n[,P] │ , └─────────────────┘ где: GET ("to get"-"получать") - служебное слово; n, P - арифметические выражения, целые части значений которых задают соответственно номер контрольного буфера файла и номер записи. До выполнения оператора GET необходимо: α) объявить контрольный буфер файла FCBn (оператором MAXFILES=); β) открыть некоторый файл данных В,связанный с FCBn (оператором OPEN); γ) задать формат его записей (оператором FIELD). После всей этой процедуры по оператору GET с диска в буфер # n будет считана запись с номером Р. Фактически будут сформированы значения всех строковых переменных буфера (числовые значения буферных переменных надо "распаковать" с помощью функций CVI, CVS и CVD). Например, оператор GET #1,3 выполняет передачу записи с номером 3 из файла #1 в буфер полей. Если в записи оператора параметр Р отсутствует, то берется текущее зна- чение этого параметра, увеличенное на единицу (как и в операторе PUT). П р и м е р 3. 10 REM Считывание из файла "Массив" ────────────── 20 MAXFILES=2:OPEN"Массив" AS#2 LEN=8:FIELD 2,8 AS M 50 FOR I=30 TO 1 STEP-1 60 GET 2,I:PRINT CVD(M); 80 NEXT П р и м е р 4. ────────────── 1 OPEN"числа" AS#1 LEN=10 2 FIELD #1,2 AS A$(1),2 AS A$(2),2 AS A$(3),2 AS A$(4),2 AS A$(5) 3 FOR I=1 TO 5:LSET A$(I)=MKI$(I):NEXT I 8 PUT #1,1:CLOSE #1:END 10 OPEN"числа" AS#1 11 FIELD #1,2 AS B$(1),2 AS B$(2),2 AS B$(3),2 AS B$(4),2 AS B$(5) 12 GET #1,1 13 FOR I=1 TO 5:A(I)=CVI(B$(I)):NEXT I 18 P=1:FOR T=1 TO 5:P=P+A(T):NEXT T 19 PRINT P:CLOSE #1:END П р и м е р 5. ────────────── 10 CLOSE:OPEN"числа" AS#1 LEN=25 30 FIELD #1,5 AS A$(1),5 AS A$(2),5 AS A$(3),5 AS A$(4), 5 AS A$(5) 40 FOR T=1 TO 5 50 LINEINPUT"Еще слово:";J$(T):LSET A$(T)=J$(T) 60 NEXT T 70 PUT#1,1:CLEAR 'Чистка оперативной памяти 90 OPEN"числа" AS#1 100 FIELD #1,5 AS B$(1),5 AS B$(2),5 AS B$(3),5 AS B$(4), 5 AS B$(5) 110 GET#1,1:U$="" 120 FOR T=1 TO 5:U$=U$+B$(T):NEXT T 150 PRINT"Сумма:";U$ П р и м е р 6. ────────────── 10 CLOSE:OPEN"числа" AS#1 LEN=25 20 FIELD #1,5 AS A$(1),4 AS A$(2),5 AS A$(3),4 AS A$(4), 5 AS A$(5) 30 FOR T=1 TO 5 STEP 2 40 LINEINPUT"Еще слово:";J$(T) 50 LSET A$(T)=J$(T):NEXT 60 FOR T=2 TO 4 STEP 2 70 INPUT"Еще число";J(T) 80 LSET A$(T)=MKS$(J(T)):NEXT 90 PUT #1,1:CLEAR 'Чистка оперативной памяти 110 OPEN"числа" AS#1 120 FIELD #1,5 AS B$(1),4 AS B$(2),5 AS B$(3),4 AS B$(4), 5 AS B$(5) 130 GET #1,1:U$=B$(1) 140 FOR T=2 TO 4 STEP 2 150 U$=U$+STR$(CVS(B$(T)))+B$(T+1):NEXT 160 PRINT"Сумма:";U$ Отметим ключевой момент при работе с файлами п р я м о г о доступа: отслеживание "невидимых" указателей. Их два: для дискеты и для буфера. Первый указатель содержит ссылку на текущую запись и задается номером в операторах PUT или GET. Буферный указатель ссылается на элемент данных - переменную, которая в этот момент пишется или читается. Он задается длиной полей в операторе FIELD. Ниже приведены д в е с х е м ы, дающие наглядное представление о по- следовательности операций, которые должны быть выполнены при перемещениях з а п и с е й файлов прямого доступа из оперативной памяти на дискету и в обратном направлении. 1. Общая схема формирования н о в ы х записей уже существующего или вновь создаваемого файла F. ┌────────────────────────────────────────────────────────────────────┐ │ А. В оперативной памяти резервируется буфер (оператором MAXFILES=)│ │ B. О т к р ы в а е т с я файл F (оператором OPEN) │ │ C. Производится распределение полей буфера файла под │ │ значения переменных (оператором FIELD) │ │ D. В буфере формируется запись (при помощи операторов │ │ SET, RSET и функций MKI$(), MKS$(), MKD$() │ │ E. Производится "сброс" записи из буфера на дискету с │ │ присваиванием ей некоторого номера (оператором PUT) │ │ F. Файл F з а к р ы в а е т с я (оператором CLOSE) │ └────────────────────────────────────────────────────────────────────┘ П р и м е р 7. Запись слова в файл прямого доступа. ────────────── 10 MAXFILES=2:OPEN "EASY" AS#2:FIELD #2,18 AS N$,110 AS D$ 20 LSET N$="Психокомпьютерапия":LSET D$=" ":PUT #2,1:CLOSE #2 2. Общая схема с ч и т ы в а н и я записей из уже существующего файла. ┌────────────────────────────────────────────────────────────────────┐ │ А. В оперативной памяти резервируется буфер (оператором MAXFILES=)│ │ B. О т к р ы в а е т с я файл F (оператором OPEN) │ │ C. Производится распределение полей буфера файла под значения │ │ переменных (оператором FIELD) │ │ D. Производится считывание с диска в буфер оперативной памяти │ │ записи с конкретным номером (оператором GET) │ │ E. По записи из буфера в соответствии с распределением │ │ его поля формируются значения требуемых переменных │ │ (при помощи функций CVI(),CVS(),CVD()). После перенесения │ │ записи в буфер Вы можете манипулировать данными, полученны- │ │ ми из файла, так же, как любыми другими переменными │ │ ┌────────────────────────────────────────────────────────────┐│ │ │Пункты D и E повторяются столько раз, сколько это требуется ││ │ └────────────────────────────────────────────────────────────┘│ │ F. Файл F з а к р ы в а е т с я (оператором CLOSE) │ └────────────────────────────────────────────────────────────────────┘ П р и м е р 8. Чтение слова из файла прямого доступа. ────────────── 10 MAXFILES=2:OPEN "EASY" AS#2:FIELD #2,18 AS N$,110 AS D$ 20 GET #2,1:PRINT N$:CLOSE #2 run Психокомпьютерапия Ok В заключении этого пункта приведем примеры, иллюстрирующие действие изученных Вами операторов и функций при работе с дисковыми файлами данных прямого доступа. П р и м е р 9. ────────────── 5 CLS 10 OPEN "ЭКЗАМЕН" AS#1 LEN=45:FIELD#1,5 AS G$,25 AS F$,1 AS O$ 25 INPUT "Введите количество студентов";N 30 FOR I=1 TO N 40 INPUT "Группа";GG$:INPUT "Ф.И.О";FF$:INPUT"Оценка";OO$ 50 LSET G$=GG$:LSET F$=FF$:LSET O$=OO$:PUT #1,I 65 NEXT:CLS 66 FOR I=1 TO N 70 GET #1,I:IF O$="5" OR O$="4" THEN PRINT G$,F$;O$ 80 NEXT 90 CLOSE #1 П р и м е р 10. Дана таблица: ─────────────── ┌──────────────┬─────────┬─────────┐ │ Ф.И. ученика │ Т е м а │ Б а л л │ ├──────────────┼─────────┼─────────┤ │ Фомина Н. │ Графика │ 5 │ │ │ Массивы │ 5 │ ├──────────────┼─────────┼─────────┤ │ Бобкова Н. │ Графика │ 4 │ │ │ Массивы │ 3 │ Заполнить два файла: ├──────────────┴─────────┴─────────┤ 1) список учеников,у которых сре- │ ··· │ дний балл по двум темам ≥ 4 ; ├──────────────┬─────────┬─────────┤ 2) список учеников,у которых хо- │ Герасимова Е.│ Графика │ 5 │ тя бы по одной теме балл 4 или 5. │ │ Массивы │ 3 │ └──────────────┴─────────┴─────────┘ 10 MAXFILES=3 20 OPEN "экзамен"AS#1 LEN=39 30 FIELD #1, 15 AS I$, 10 AS T1$, 2 AS O1$, 10 AS T2$, 2 AS O2$ 31' ▲ ▲ ▲ ▲ ▲ 32' │ │ │ │ │ 33' Фамилия,имя Первая Балл по Вторая Балл по 34' тема первой теме тема второй теме 40 OPEN "Фамилия"AS#2 LEN=15 50 FIELD #2,15 AS F$ 'Фамилия ученика, у которого средний балл по 'двум темам ≥ 4 60 OPEN "особенное"AS#3 LEN=15 70 FIELD #3,15 AS F1$ 'Фамилия ученика, у которого хотя бы по одной 'теме балл 4 или 5 75 INPUT "Введите количество учащихся";N 80 FOR I=1 TO N 90 INPUT "Ф.И.";D$:LSET I$=D$:INPUT "Тема1";D$:LSET T1$=D$:INPUT"Б алл";D%:LSET O1$=MKI$(D%):INPUT "Тема2";D$:LSET T2$=D$:INPUT "Б алл";D%:LSET O2$=MKI$(D%):PUT#1,I 110 NEXT:A=0 'A - количество учеников, у которых средний балл по 'двум темам ≥ 4 120 FOR K=1 TO N:GET#1,K 'Заполнение файла #2 125 L=(CVI(O1$)+CVI(O2$))/2 130 IF L>=4 THEN LSET F$=I$:A=A+1:PUT #2,A 140 NEXT K 146 PRINT"Ф.И. хорошистов и отличников:" 150 FOR I=1 TO A:GET #2,I:PRINT F$:NEXT I 'Вывод на экран 170 B=0 'B - количество учеников,у которых хотя бы по одной 'теме балл 4 или 5 175 FOR K=1 TO N 'Заполнение файла #3 177 GET #1,K 180 IF CVI(O1$)=4 OR CVI(O1$)=5 OR CVI(O2$)=4 OR CVI(O2$)=5 THEN LSET F1$=I$:B=B+1:PUT #3,B 190 NEXT K 195 PRINT"Ф.И. успевающих" 200 FOR I=1 TO B:GET#3,I:PRINT F1$:NEXT I:END 'Вывод на экран П р и м е р 11. ─────────────── 10 MAXFILES=3:OPEN"A3" AS#2 LEN=2:FIELD #2,2 AS K$ 20 POKE VARPTR(#2)+9,66:POKE VARPTR(#2)+10,65 'Вместо LSET K$="ba" 30 PUT #2,2:CLOSE#2 40 OPEN"a3"AS#2 LEN=2:FIELD #2,2 AS K$:GET #2,2:CLOSE #2 run ba Ok IX.3. Ф а й л ы д а н н ы х п о с л е д о в а т е л ь н о г о д о с т у п а При использовании дискеты достаточно указать имя файла,чтобы компьютер начал поиск с использованием каталога. Все участки дискеты в равной степе- ни доступны для записи и чтения, т.е. для обращения к любому участку тре- буется примерно одинаковое время. Напомним Вам, что ┌─────────────────────────────────────────────────────────────────────┐ │ файл, в котором информация может быть найдена без полного просмотра │ │ носителя, мы назвали файлом с п р я м ы м доступом │. └─────────────────────────────────────────────────────────────────────┘ ┌────────────────────────────────────────────────────────────────────┐ │ Файл будем называть файлом с п о с л е д о в а т е л ь н ы м │ │ д о с т у п о м , если компьютер должен "просматривать" его │ │ с самого начала до момента нахождения нужной части. │ └────────────────────────────────────────────────────────────────────┘ Поиск файла на кассетной ленте называется п о с л е д о в а т е л ь- н ы м, потому что компьютер ищет требуемый файл, последовательно перематы- вая магнитную ленту. Любой файл можно организовать так, чтобы можно было использовать либо последовательный, либо прямой доступ, но не оба способа одновременно. Каж- дый способ имеет свои "за" и "против".Последовательный способ намного про- ще для программирования и при его реализации требуется меньше дисковой па- мяти, но может понадобиться больше времени для поиска информации, находя- щейся "в конце" длинного файла. Кроме того, обновление существующих запи- сей в файлах с последовательным доступом трудноосуществимо, а иногда и просто невозможно. Файлы с прямым доступом требуют более сложного программирования и зани- мают обычно больше места на дискете, но очень легко поддаются обновлению, и поиск нужной информации осуществляется с одинаковой скоростью. ┌──────────────────────────────────────────────────────────────────────┐ │ Если при каждом обращении к файлу Вы собираетесь использовать почти │ │ все данные, а менять их содержимое часто не предполагается, то выби- │ │ райте метод п о с л е д о в а т е л ь н о г о доступа. Его приме- │ │ нение будет и более оптимальным и облегчит Вам программирование. │ └──────────────────────────────────────────────────────────────────────┘ Файлы данных последовательного доступа состоят из отдельных групп зна- чений, называемых л о г и ч е с к и м и строками (или просто с т р о - к а м и). Логические строки не имеют номеров и их можно считывать с дискеты или магнитной ленты в оперативную память или записывать из памяти на дискету или магнитную ленту лишь последовательно друг за другом, причем запись производится от начала или конца файла, а чтение - только от его начала. ┌────────────────────────────────────────────────────────────────────┐ │ Каждая логическая строка имеет специальную к о н ц е в у ю метку,│ │ а весь файл имеет еще и метку EOF ("End Of File"-"конец файла"). │ └────────────────────────────────────────────────────────────────────┘ Кроме того, любой конкретный файл открывается или только для чтения, или только для записи, но не для одновременного выполнения этих операций. Для работы с файлами данных п о с л е д о в а т е л ь н о г о доступа в MSX-Disk BASIC предусмотрен ряд операторов и функций.