while (S[1]=' ') do Delete(S,1,1);
New(P); { Создаем новую запись в куче }
{ Заполняем поля записи }
P^.mNumber := N; P^.mFam := S;
{ Указатель на запись помещаем в массив }
DataBase[i]:= P;
end;
Close(F); ReadData:= i;
end;
procedure ExpoDataBase; { Распечатка базы данных }
var i : integer;
begin
i:=1;
{ Пока индекс в пределах массива и указатель не пуст }
while (i<=CSize) and Assigned(DataBase[i]) do begin
{ Печатаем номер, четыре пробела и фамилию }
Writeln(DataBase[i]^.mNumber :6, '':4, DataBase[i]^.mFam);
Inc(i); { i+1 }
end;
end;
var F : text; i : integer;
begin {--- Главная программа ---}
for i:= 1 to CSize do DataBase[i]:= nil;
Assign(F,'P_50_1.in');
Count:= ReadData(F);
Writeln ('Всего записей: ',Count);
ExpoDataBase; Readln;
end.
Типы данных объявлены так, как уговорено выше. Предельный размер базы данных задан константой CSize=1000.
Функция ReadData читает строки текстового файла и помещает данные в кучу. После ввода номера автомобиля оператором Read(F,N) указатель чтения в файле остановится на первом пробеле за числом. Следующий оператор Readln(F,S) дочитает остаток строки. Так в переменной S окажется фамилия с пробелами в начале строки, – они потом удаляются.
Последующие операторы внутри функции ReadData создают динамическую переменную (запись), адрес которой содержится в указателе P. Затем поля записи заполняем номером автомобиля и фамилией владельца, после чего указатель P копируем в очередной элемент массива указателей. Эти действия можно записать короче – без вспомогательного указателя P, вот так:
New(DataBase[i]); { создаем переменную-запись, указатель в массиве }
DataBase[i]^.mNumber := N; { копируем номер }
DataBase[i]^.mFam := S; { и фамилию }
Но при пошаговой отладке удобнее пользоваться промежуточными переменными, что мы и сделали.
Теперь обратимся к процедуре ExpoDataBase – она распечатывает данные, размещенные в куче. Выражение Assigned(DataBase[i]) в условии цикла WHILE равнозначно выражению DataBase[i]<>NIL и проверяет, ссылается ли указатель на динамическую переменную. Такая проверка исключает ошибку обращения через пустой указатель.
В главной программе заслуживает внимание строка, заполняющая пустым значением NIL все указатели массива. Ведь пока динамические переменные не созданы, указатели на них следует «заглушить» константой NIL.
for i:= 1 to CSize do DataBase[i]:= nil;