Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.03.2017, 14:47   #1
mindchamber
 
Регистрация: 28.03.2017
Сообщений: 7
По умолчанию Ошибка времени выполнения в примере из книги.

Всем привет. Изучаю паскаль, как первый язык программирования по книге Культина "Программирование в Pascal и delphi". Есть там пример с программой, которая форматирует элементы односвязного списка по алфавиту. В компиляторе ошибка времени выполнения.
Код:
{ формирования упорядоченного по алфавиту (по возрастанию) списка } 
program p10_6;

type
  pStudent = ^TStudent;
  TStudent = record 
    name: string[20]; 
    next: pStudent; 
  end;

var
  head: pStudent; { указатель на первый элемент списка } 
  cur: pStudent; { текущий элемент списка } 
  p: pStudent; { элемент, после которого вставляем новый узел } 
  name: string[20]; { фамилия, вводимая с клавиатуры } 
  node: pStudent;{ новый узел списка } 

begin
  repeat
    write('Фамилия-> '); 
    readln(name); 
    if length(name) <> 0 then 
    begin
      { создадим новый элемент списка } 
      new(node); 
      node^.name := name; 
      node^.next := nil; 
      
      { найти место для вставки } 
      cur := head; 
      p := nil; 
      { Список упорядочен по возрастанию, найдем 
      элемент, который больше чем добавляемый. 
      Перед ним и вставим.} 
      while (cur^.name < name) and (cur <> nil) do 
      begin
        { введенное значение больше текущего } 
        p := cur; 
        cur := cur^.next; { к следующему узлу } 
      end; 
      if p = nil then 
      begin
        { узел в начало списка } 
        node^.next := head; 
        head := node; 
      end 
      else 
      begin
        node^.next := p^.next; 
        p^.next := node; 
      end; 
    end; 
  until length(name) = 0; { строка не введена, нажата клавиша < Enter > } 
  
  { распечатаем введенный список } 
  writeln; 
  writeln('Список:'); 
  
  cur := head; 
  while cur <> nil do 
  begin
    writeln(cur^.name); 
    cur := cur^.next; 
  end; 
  
  writeln; 
  write('Для завершения нажмите <Enter>'); 
  readln; 
end.
Подскажите пожалуйста, в чем ошибка и как её исправить? И если не сложно подскажите где можно узнать про сортировку списков. Спасибо за ответы.
mindchamber вне форума Ответить с цитированием
Старый 28.03.2017, 15:08   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

head:=nil; // в начале ЕСТЬ пустой список
Цитата:
Код:
      { найти место для вставки } 
      cur := head; 
      p := nil; 
      { Список упорядочен по возрастанию, найдем 
      элемент, который больше чем добавляемый. 
      Перед ним и вставим.} 
      while (cur^.name < name) and (cur <> nil) do 
в пустом списке указатель на элемент будет тоже пустым( cur =nil)
а для такого указателя невозможно выполнить доступ к его содержимому (cur^.name)
сначала надо проверять доступность данных и только потом их значения
Код:
(cur<>nil)  and (cur^.name <name)
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 28.03.2017, 15:15   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

mindchamber, любопытно, Вы текст программы набирали самостоятельно или он на диске с книгой был?

evg_m, в точку!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 28.03.2017, 17:12   #4
mindchamber
 
Регистрация: 28.03.2017
Сообщений: 7
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
head:=nil; // в начале ЕСТЬ пустой список

в пустом списке указатель на элемент будет тоже пустым( cur =nil)
а для такого указателя невозможно выполнить доступ к его содержимому (cur^.name)
сначала надо проверять доступность данных и только потом их значения
Код:
(cur<>nil)  and (cur^.name <name)
Спасибо!

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
mindchamber, любопытно, Вы текст программы набирали самостоятельно или он на диске с книгой был?
Нашел у себя пыльную книгу по паскалю. Внутри был диск -


Обложка


Текст проги с косяком

Название проги
mindchamber вне форума Ответить с цитированием
Старый 28.03.2017, 17:17   #5
mindchamber
 
Регистрация: 28.03.2017
Сообщений: 7
По умолчанию

http://rgho.st/7jQCyCzcH вот данные с диска.

Кстати вместо исходников там иногда пустые файлы были, которые я сам заполнил. Тоесть файл с расширением .pas, а внутри ничего.
Вложения
Тип файла: rar самоучитель.rar (3.04 Мб, 8 просмотров)

Последний раз редактировалось mindchamber; 28.03.2017 в 18:09.
mindchamber вне форума Ответить с цитированием
Старый 28.03.2017, 17:57   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

mindchamber, спасибо. Это очень убедительно.

Значит, этому учебному пособию можно поставить БОЛЬШОЙ минус!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 28.03.2017, 17:58   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от mindchamber Посмотреть сообщение
http://rgho.st/7jQCyCzcH вот данные с диска.
а почему на форум не выложить архивчик (прикрепить к сообщению через вложения)?
На мой взгляд, тут в теме это будет не лишним.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 28.03.2017, 18:13   #8
mindchamber
 
Регистрация: 28.03.2017
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
а почему на форум не выложить архивчик (прикрепить к сообщению через вложения)?
На мой взгляд, тут в теме это будет не лишним.
Залил. Кстати вконтакте один человек, который мне часто помогает написал следующее:

Цитата:
на старом добром Borland Pascal 7.0 эта программа работает. Правда не факт, что она там работает правильно.

Операция разыменовывания нулевого указателя в BP 7.0 не приводит к ошибке. То есть код:

cur := NIL;
write('debug: ');
writeln(cur^.name);

... не приводит к выбросу исключения. На экран при этом печатается мусорная строка откуда-то из памяти.

Вероятно, автор книги проверял программы на BP 7.0, и не заметил этого бага в программе. В современных компиляторах (Free Pascal, PascalABC) операция разыменовывания нулевого указателя конечно же приводит к выбросу исключения.

смена местами двух условий приводит к тому, что второе условие не вычисляется, если первое условие ложно. Это называется Short-Circuit Evaluation (или наиболее грамотный перевод "вычисления по короткой схеме"):
https://en.wikipedia.org/wiki/Short-circuit_evaluation
http://www.vzmakh.ru/info/pascal/data/html/605.html
Очень интересно.
mindchamber вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ошибка времени выполнения. индекс выходит за границы массива Anton19901505 Помощь студентам 1 08.01.2017 11:42
Ошибка времени выполнения: Индекс находился вне границ массива (pascal) dijetol Помощь студентам 2 10.04.2014 16:16
Ошибка в примере PinkPink C/C++ Сетевое программирование 0 03.04.2013 23:58
Не могу найти ошибку в примере из книги pashqacpp Общие вопросы C/C++ 7 05.02.2013 15:02
Замер времени выполнения nickel-j Компоненты Delphi 3 28.05.2010 17:02