Обучение начальных курсов методам программирования на языке Turbo Pascal
Краткая теория
Строковые типы
Значением строкового типа является последовательность симво-
лов с динамическим атрибутом длины (в зависимости от действитель-
ного числа символов при выполнении программы) и постоянным атри-
бутом размера в диапазоне от 1 до 255. Текущее значение атрибута
длины можно получить с помощью стандартной функции Length.
┌──────┐
строковый тип ───>│string├──┬──────────────────────────────>
└──────┘ │ ^
│ ┌───┐ ┌─────┐ ┌───┐ │
└─>│ [ ├──>│целое├──>│ ] ├─┘
└───┘ │ без │ └───┘
│знака│
└─────┘
Отношение между любыми двумя строковыми значениями устанав-
ливается согласно отношению порядка между значениями символов в
соответствующих позициях. В двух строках разной длины каждый сим-
вол более длинной строки без соответствующего символа в более ко-
роткой строке принимает значение "больше"; например, 'Xs' больше,
чем 'X'. Нулевые строки могут быть равны только другим нулевым
строкам, и они являются наименьшими строковыми значениями.
К идентификатору строкового типа и к ссылке на переменную
строкового типа можно применять стандартные функции Low и High. В
этом случае функция Low возвращает 0, а High возвращает атрибут
размера (максимальную длину) данной строки.
Параметр-переменная, описанная с помощью идентификатора
OpenString и ключевого слова string в состоянии {$P+}, является
открытым строковым параметром. Открытые строковые параметры поз-
воляют передавать одной и той же процедуре или функции строковые
переменные изменяющегося размера.
Конкретный элемент массива обозначается с помощью ссылки на
переменную массива, за которой указывается индекс, определяющий
данный элемент.
Конкретный символ в строковой переменной обозначается с по-
мощью ссылки на строковую переменную, за которой указывается ин-
декс, определяющий позицию символа.
┌───┐ ┌─────────┐ ┌───┐
индекс ──>│ [ ├───────>│выражение├────┬──>│ ] ├──>
└───┘ ^ └─────────┘ │ └───┘
│ ┌───┐ │
└───────┤ , │<───────┘
└───┘
Индексные выражения обозначают компоненты в соответствующей
размерности массива. Число выражений не должно превышать числа
индексных типов в описании массива. Более того, тип каждого выра-
жения должен быть совместимым по присваиванию с соответствующим
индексным типом.
В случае многомерного массива можно использовать несколько
индексов или несколько выражений в индексе. Например:
Matrix[I][J]
что тождественно записи:
Matrix[I,J]
Строковую переменную можно проиндексировать с помощью оди-
ночного индексного выражения, значение которого должно быть в ди-
апазоне 0...n, где n - указанный в описании размер строки. Это
дает доступ к каждому символу в строковом значении, если значение
символа имеет тип Char.
Первый символ строковой переменной (индекс 0) содержит дина-
мическую длину строки, то есть Length(S) тождественно Ord(S[0]).
Если атрибуту длины присваивается значение, то компилятор не про-
веряет, является ли это значение меньшим описанного размера стро-
ки. Вы можете указать индекс строки и вне ее текущей динамической
длины. В этом случае считываемые символы будут случайными, а
присваивания вне текущей длины не повлияют на действительное зна-
чение строковой переменной.
Когда с помощью директивы компилятора {$X+} разрешен расши-
ренный синтаксис, значение PChar может индексироваться одиночным
индексным выражением типа Word. Индексное выражение задает смеще-
ние, которое нужно добавить к символу перед его разыменованием
для получения ссылки на переменную типа Char.
Открытые параметры позволяют передавать одной и той же про-
цедуре или функции строки и массивы различных размеров.
Открытые строковые параметры могут описываться двумя спосо-
бами:
- с помощью идентификатора OpenString;
- с помощью ключевого слова string в состоянии {$P+}.
Идентификатор OpenString описывается в модуле System. Он
обозначает специальный строковый тип, который может использовать-
ся только в описании строковых параметров. В целях обратной сов-
местимости OpenString не является зарезервированным словом и мо-
жет, таким образом, быть переопределен как идентификатор, задан-
ный пользователем.
Когда обратная совместимость значения не имеет, для измене-
ния смысла ключевого слова string можно использовать директиву
компилятора {$P+}. В состоянии {$P+} переменная, описанная с клю-
чевым словом string, является открытым строковым параметром.
Для открытого строкового параметра фактический параметр мо-
жет быть переменной любого строкового типа. В процедуре или функ-
ции атрибут размера (максимальная длина) формального параметра
будет тем же, что у фактического параметра.
Открытые строковые параметры ведут себя также как парамет-
ры-переменные строкового типа, только их нельзя передавать как
обычные переменные другим процедурам или функциям. Однако, их
можно снова передать как открытые строковые параметры.
В следующем примере параметр S процедуры AssignStr - это
открытый строковый параметр:
procedure AssignStr(var S: OpenString);
begin
S := '0123456789ABCDEF';
end;
Так как S - это открытый строковый параметр, AssignStr можно
передавать переменные любого строкового типа:
var
S1: string[10];
S1: string[20];
begin
AssignStr(S1); { S1 := '0123456789' }
AssignStr(S2); { S2 := '0123456789ABCDEF' }
end;
В AssingStr максимальная длина параметра S та же самая, что
у фактического параметра. Таким образом, в первом вызове
AssingStr при присваивании параметра S строка усекается, так как
максимальная длина S1 равна 10.
При применении к открытому строковому параметру стандартная
функция Low возвращает 0, стандартная функция High возвращает
описанную максимальную длину фактического параметра, а функция
SizeOf возвращает размер фактического параметра.
В следующем примере процедура FillString заполняет строку
заданным символом до ее максимальной длины. Обратите внимание на
использование функции High для получения максимальной длины отк-
рытого строкового параметра.
procedure FillStr(var S: OpenString; Ch: Char);
begin
S[0] := Chr(High(S)); { задает длину строки }
FillChar(S[1], High(S), Ch); { устанавливает число
символов }
end;
Значения и параметры-константы, описанные с использованием
идентификатора OpenString или ключевого слова string в состоянии
{$P+}, не являются открытыми строковыми параметрами. Они ведут
себя также, как если бы были описаны с максимальной длиной стро-
кового типа 255, а функция Hingh для таких параметров всегда
возвращает 255.
uses crt,dos;
var i,j,i1,x:integer;
DI: SearchRec;
textf:array[1..800] of string[79];
procedure music;
begin
sound(800);
delay(200);
nosound;
end;
procedure myerror (s:string);
var c:char;
begin
textbackground(4);
window(10,10,70,16);
clrscr;
textcolor(15);
write('╔════════════════════════ Внимание ═════════════════════════╗');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('╚═══════════════════════════════════════════════════════════╝');
gotoxy(10,2);
write(' В текущем каталоге нет файла ',s,'.');
gotoxy(15,3);
write(' Без него не могу работать.');
textbackground(1);
gotoxy(27,5);
write(' Да ');
c:=chr(1);
{ выдаёт звукавой сигнал }
music;
while(c<>chr(13)) do
c:=readkey;
end;
procedure ins(x,y,w:integer;ct,ft:integer);
var l,i:integer;
attr:byte;
begin
attr:=ct+16*ft;
if lastmode=co40 then l:=y*80+2*x+1;
if lastmode=co80 then l:=y*160+2*x+1;
i:=l;
while (i<l+2*w) do
begin
mem[$b800:i]:=attr;
i:=i+2;
end;
end;
procedure hide;
var r:registers;
begin
r.ah:=$01;
r.ch:=$20;
r.cl:=$00;
intr($10,r);
end;
function myexit:boolean;
var c:char;
i,x:integer;
begin
window(20,8,55,13);
textbackground(7);
textcolor(0);
write('╔═══════Прекратить просмотр════════╗');
write('║ ║');
write('║ ║');
write('║ ║');
write('╚══════════════════════════════════╝');
textbackground(6);
gotoxy(8,3);
write(' да ' );
textbackground(3);
gotoxy(21,3);
write(' нет ');
ins(20,12,36,7,0);
ins(55,12,1,7,0);
ins(55,11,1,7,0);
ins(55,10,1,7,0);
ins(55,9,1,7,0);
ins(55,8,1,7,0);
c:=chr(1);
i:=1;
x:=26;
while(c<>chr(13)) do
begin
c:=readkey;
{ по ESC закрывает запрос }
if c=chr(27) then begin i:=2;break;end;
if c=chr(0) then begin
c:=readkey;
ins(x,9,7,15,3);
if c=chr(77) then if i=2 then begin x:=26;i:=1;end
else begin x:=39;i:=2;end;
if c=chr(75) then if i=2 then begin x:=26;i:=1;end
else begin x:=39;i:=2;end;
ins(x,9,7,15,6);
end;
end;
case i of
1:myexit:=true;
2:myexit:=false;
end;
end;
procedure obuch;
var n,c:char;
s,zx:string;
t:boolean;
y,x,y1,m:integer;
f:text;
begin
window(1,1,80,25);
textbackground(0);
clrscr;
hide;
m:=1;i:=1;
window(1,1,80,2);
textbackground(2);
clrscr;
textcolor(5);
write('строка 21');
gotoxy(20,1);
window(1,23,80,24);
textbackground(2);
clrscr;
window(1,2,80,23);
textbackground(1);
clrscr;
textbackground(7);
window(1,1,80,25);
gotoxy(20,1);
gotoxy(2,24);
write(' ',char(24),' - вверх ');
gotoxy(14,24);
write(' ',char(25),' - вниз ');
gotoxy(25,24);
write(' PgUp - лист вверх ');
gotoxy(45,24);
write(' PgDn - лист вниз ');
gotoxy(65,24);
write(' ESC - выход ');
textbackground(1);
textcolor(15);
window(1,2,80,23);
assign(f,'curswork.txt');
reset(f);
while((i=1)and(m<796)) do
begin
readln(f,s);
if (s[1]='#')and(s[2]='#')and(s[3]='#') then break;
textf[m]:=s;
if m<22 then writeln(s);
m:=m+1;
end;
x:=m;
c:=chr(1);
m:=0;
while c<>chr(27) do
begin
c:=readkey;
if c=chr(27) then if myexit then c:=chr(27) else begin
c:=chr(1);
window(1,2,80,23);
textbackground(1);
clrscr;
textcolor(15);
for i:=m to m+21 do
begin
writeln(textf[i]);
end;
end;
if c=chr(0) then begin
c:=readkey;
if ((c=chr(81))) then if (m+23<=x-23) then m:=m+21 else m:=x-21;
if ((c=chr(73))) then if (m-23>1) then m:=m-21 else m:=0;
if ((c=chr(80)) and (x-23>=m)) then m:=m+1;
if ((c=chr(72)) and (m>0))then m:=m-1;
clrscr;
for i:=m to m+21 do
begin
writeln(textf[i]);
end;
window(1,1,80,25);
gotoxy(1,1);
textbackground(2);
textcolor(5);
write(' ');
gotoxy(1,1);
write('строка ',m+1);
window(1,2,80,23);
textcolor(15);
textbackground(1);
end;
end;
textbackground(0);
window(1,1,80,25);
clrscr;
end;
function select:integer;
var om:integer;
c:char;
begin
om:=lastmode;
textmode(co40);
textbackground(0);
hide;
window(5,3,35,20);
textbackground(1);
clrscr;
textcolor(15);
window(1,1,40,25);
gotoxy(1,3);
for i:=5 to 35 do
begin
gotoxy(i,5);
write('═');
gotoxy(i,20);
write('═');
end;
for i:=5 to 20 do
begin
gotoxy(5,i);
write('║');
gotoxy(35,i);
write('║');
end;
gotoxy(5,20);
write('╚');
gotoxy(5,5);
write('╔');
gotoxy(35,20);
write('╝');
gotoxy(35,5);
write('╗');
textcolor(5);
gotoxy(5,3);
write(' Строковый тип данных в TP 7.0 ');
textcolor(15);
gotoxy(12,8);
write('Теория');
gotoxy(12,10);
write('Помощь');
gotoxy(12,12);
write('О программе');
gotoxy(12,14);
write('Выход');
ins(5,x,29,1,2);
c:=chr(1);
while(c<>chr(13)) do
begin
c:=readkey;
if c=chr(0) then begin
c:=readkey;
ins(5,x,29,15,1);
if c=chr(80) then
if i1=4 then begin x:=7;i1:=1;end
else begin x:=x+2;i1:=i1+1; end;
if c=chr(72) then
if i1=1 then begin x:=13;i1:=4;end
else begin x:=x-2;i1:=i1-1; end;
ins(5,x,29,1,2);
end;
end;
textmode(om);
case (i1) of
1:select:=1;
2:select:=2;
3:select:=3;
4:select:=4;
end;
end;
procedure help;
var s:string;
f:text;
i:byte;
begin
textmode(co80);
hide;
window(10,5,70,20);
textbackground(1);
textcolor(15);
clrscr;
write('╔═══════════════════════ Справка ═══════════════════════════╗');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ Выход любая клавиша ║');
write('╚═══════════════════════════════════════════════════════════╝');
assign(f,'help.txt');
reset(f); i:=2;
while not(eof(f)) do
begin
gotoxy(2,i);
readln(f,s);
if ((s[1]='#') and (s[2]='#')) then break;
writeln(s);
i:=i+1;
end;
close(f);
readkey;
end;
procedure about;
var f:text;
q:byte;
s:string;
begin
textmode(co80);
hide;
window(10,5,70,20);
textbackground(1);
textcolor(15);
clrscr;
write('╔═════════════════════ О программе ════════════════════════╗');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ ║');
write('║ Выход любая клавиша ║');
write('╚═══════════════════════════════════════════════════════════╝');
assign(f,'about.txt');
reset(f);
q:=2;
while not(eof(f)) do
begin
gotoxy(2,q);
readln(f,s);
if ((s[1]='#') and (s[2]='#')) then break;
writeln(' ',s);
q:=q+1;
end;
close(f);
readkey;
end;
begin
hide;
findfirst('curswork.txt',anyfile,di);
if doserror<>0 then begin
myerror('curswork.txt');
halt(1);
end;
findfirst('help.txt',anyfile,di);
if doserror<>0 then begin
myerror('help.txt');
halt(1);
end;
findfirst('about.txt',anyfile,di);
if doserror<>0 then begin
myerror('about.txt');
halt(1);
end;
j:=1;
i1:=1;
x:=7;
while j=1 do
begin
i:=select;
case i of
1:obuch;
2:help;
3:about;
4:begin textbackground(0);clrscr;halt;end;
end;
end;
end.