Исправление ошибок индексации при работе с массивами записей в Pascal
При работе с массивами записей в языке программирования Pascal часто возникают ситуации, когда данные не сохраняются должным образом. В данном случае рассмотрим проблему, связанную с инициализацией массива записей и выводом данных на экран.
Описание проблемы
Разработчик столкнулся с проблемой при работе с массивом записей Person. При вводе информации о людях, начиная со второго человека, имя не сохраняется. Проблема возникает из-за неправильной последовательности операций ввода данных.
Структура типа и переменные
type
grade = 1..5;
Person = record
Name: string[16];
isMale: boolean;
grades: array [1..6] of grade;
end;
var
Table: array [1..10] of Person;
R: Person;
N, J, I: Integer;
Часть кода с инициализацией и выводом
readln(n);
if N > 10 then N := 10; if N < 1 then N := 1;
for I := 1 to N do begin
R := Table[I]; // Ошибка: не происходит сохранение данных в массив
write('Name? '); readln(R.Name);
write('Gender? '); readln(j); R.isMale := j >= 0;
write('Grades? ');
for J := 1 to 6 do read(R.grades[J]); writeln;
end;
for I := 1 to N do begin
R := Table[I];
write(I, ' ', R.Name, ' ', R.isMale);
end;
Анализ ошибки
Основная проблема заключается в том, что после заполнения записи R данными, она не сохраняется в массив Table. При каждом проходе цикла создаётся новый экземпляр записи, который не связан с элементами массива.
Исправление кода
Чтобы исправить проблему, необходимо после инициализации записи R присвоить её значение соответствующему элементу массива Table. Это делается путём копирования данных из R в массив:
for I := 1 to N do begin
// Заполнение данных для записи R
write('Name? '); readln(R.Name);
write('Gender? '); readln(j); R.isMale := j >= 0;
write('Grades? ');
for J := 1 to 6 do read(R.grades[J]);
writeln(R.grades[6]); // Использование ReadLn для чтения символа перевода строки
writeln;
Table[I] := R; // Копирование данных из записи R в массив Table
end;
Также стоит отметить, что при чтении оценок следует использовать ReadLn после последнего ввода оценки, чтобы корректно обработать символ перевода строки.
Альтернативный подход
Вместо использования промежуточной переменной R, можно напрямую работать с элементами массива:
for I := 1 to N do begin
write('Name? '); readln(Table[I].Name);
write('Gender? '); readln(j); Table[I].isMale := j >= 0;
// ... заполнение остальных полей ...
end;
for I := 1 to N do begin
Writeln(I, ' ', Table[I].Name, ' ', Table[I].IsMale);
end;
Это упрощает код и устраняет необходимость в копировании данных.
Заключение
При работе с массивами записей важно помнить о необходимости сохранения изменённых значений в массив. В Pascal при присвоении записи переменной происходит копирование данных, а не создание ссылки на объект. Следуя этим правилам, можно избежать многих распространённых ошибок.
Проблема заключается в неправильном сохранении данных при работе с массивами записей в Pascal из-за отсутствия их копирования после инициализации полей записи.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS