Редактирование и вычитка книги

Книга адресована школьникам средних и старших классов, желающим испытать себя в «олимпийских схватках». Может быть полезна студентам-первокурсникам и преподавателям информатики.

Модераторы: Oleg_D, Модераторы

Oleg_D
постоялец
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Сообщение Oleg_D »

enot777 писал(а):В FPC начиная со 2-ой версии MemAvail и MaxAvail отсутствуют

Да, я в курсе, спасибо. Наверное, здесь следует сказать, что "в Borland Pascal были такие функции". Рудимент, конечно, но жаль выкидывать эту задачку.
Благодарю всех за обсуждение, и с Новым Годом всех!
enot777
новенький
Сообщения: 24
Зарегистрирован: 24.11.2016 14:20:58

Сообщение enot777 »

>> Oleg_D
Глава 57. стр.460
В тексте программы P_57_01 есть небольшой косячок.

Код: Выделить всё

procedure ReadData(var F: Text);
var C : Char;p, q : PNode;
begin
  Reset(F);
  while not Eof(F) do begin
    if not Eoln(F) then begin { если строка не пуста }
      Read(F, C); { читаем имя страны }
      C:=UpCase(C); { перевод в верхний регистр }
      p:= GetPtr(C); { а может эта страна уже существует? }
      if not Assigned(p) then p:= MakeNode(C); { если нет, – создаем }
      while not Eoln(F) do begin { чтение стран-соседей до конца строки }
        Read(F, C);
        C:= UpCase(C);
        if C in ['A'..'Z'] then begin { если это имя страны, а не пробел }
          q:= GetPtr(C); { проверяем существование страны }
          if not Assigned(q) { если не существует, – создаем }
            then q:= MakeNode(C);
          Link(p, q); { связываем страну p с q }
        end
      end
    end;
    Readln(F); { переход на следующую строку файла }
  end;
end;

В начале есть Reset(f);, а Close(f); перед закрывающим end; нет.
Да на работу программы это не влияет, но всё же лучше не расслабляться.
И здесь можно было бы применить continue

Код: Выделить всё

if not Eoln(F) then begin
...
end;
// а можно так
if eoln(f) then begin
  readln(f);
  continue;
end;
...

Спасибо за внимание.
Oleg_D
постоялец
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Сообщение Oleg_D »

Спасибо, enot777, с замечаниями согласен.
Здесь можно добавить несколько пояснений для учащихся, многие из которых заглядывают на этот форум.
Почему надо закрывать открытые для чтения файлы? Всякий раз, когда программа открывает такой файл, операционка выделяет некоторый объём памяти под дескриптор (описание) файла и буфер ввода (или вывода). При закрытии файла или по завершении программы эта память освобождается. Если программа работает со многими файлами, соответственно возрастает и потребление памяти. И потому закрытие уже ненужных файлов вполне разумно.
Что касается файлов, открытых для записи, то закрывать оные рекомендуется категорически, поскольку только это гарантирует попадание в файл всех данных, временно находящихся в буфере записи.
И ещё. Пользуясь случаем, напомню, что наряду со стандартными функциями Eoln() и Eof(), в современных версиях Паскаля существуют более удобные функции SeekEoln() и SeekEof(). Первая из них игнорирует все пробелы и табуляции до конца строки, а вторая – те же символы и пустые строки до конца файла.
Oleg_D
постоялец
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Сообщение Oleg_D »

2017-01-10 выложена редакция 12-10 (см. ветку с новостями)

В числе исправленных ошибка в главе 32, где изменено имя месяца декабрь: Dec --> Dcb
Но полноты картины ради надо сказать, что ошибка эта не совсем ошибка, имя месяца Dec можно применять так:

Код: Выделить всё

var m : (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);

begin
  m:= Dec;        // имя месяца Dec
  System.Dec(m);  // имя процедуры Dec в модуле System
end.
Аватара пользователя
bormant
постоялец
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Сообщение bormant »

Oleg_D писал(а):Что касается файлов, открытых для записи, то закрывать оные рекомендуется категорически, поскольку только это гарантирует попадание в файл всех данных, временно находящихся в буфере записи.

Если уж думать о заглядывающих учащихся, то не будем скрывать от них голую правду: попадание в файл всех данных, временно находящихся в буфере записи, гарантирует вызов Flush(). Просто Close()/CloseFile() вызывают Flush() перед закрытием, только и всего.
Oleg_D
постоялец
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Сообщение Oleg_D »

bormant писал(а):попадание в файл всех данных, временно находящихся в буфере записи, гарантирует вызов Flush(). Просто Close()/CloseFile() вызывают Flush() перед закрытием, только и всего.

Всё верно, спасибо! Но в "песнях" Flush() не упоминается (по ранее обсуждённым причинам), поэтому на начальном этапе обучения надо хотя бы о Close() не забывать.
enot777
новенький
Сообщения: 24
Зарегистрирован: 24.11.2016 14:20:58

Сообщение enot777 »

>> Oleg_D
Глава 61. стр.519 Задание Б)

Код: Выделить всё

TSetArray = array [0..4096] of word; { хранит 65536 бит (4096*16) }

Диапазон массива от 0 до 4096, т.е. 4097 элементов. Следовательно и размер массива в битах будет 65536+16.
Необходимо изменить диапазон [1..4096] или [0..4095].
Oleg_D
постоялец
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Сообщение Oleg_D »

enot777 писал(а):Необходимо изменить диапазон [1..4096] или [0..4095]

Точно, это досадная опечатка :( , надо будет поправить, спасибо!
Oleg_D
постоялец
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Сообщение Oleg_D »

2018-02-09 Выложена редакция 12-11

Глава 61 стр. 519 В задании "Б" исправлен диапазон TSetArray = array [0..4096] --> [0..4095]

Других поправок за истекший период не поступало.
Ответить