Разбор примеров из книги

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

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

Re: Разбор примеров из книги

Сообщение Парнишка » 04.02.2013 20:25:28

Здравствуйте. Нашёл пару мелких недочётов в заданиях и ответах к ним.

Глава 26 ответ к заданию «а»:
Код: Выделить всё
var F: text;
  i: integer;
  s: string;
begin
  Assign(F, 'Test.txt');
  Rewrite(F);
  for i:=1 to 10 do Writeln(F, i);
  Close(F);
  Reset(F);
  while not Eof(F) do begin
     Readln(F, S);
     Writeln(S);
  end;
  Readln;
end.

В конце забыли второй Close(F);

Глава 30 задание «B»:
Сформируйте файл «Numbers.txt», поместив в него 100 случайных чисел
в диапазоне от 0 до 999(некоторые числа могут повторяться). Затем найдите в этом
файле: 1) максимальное и минимальное число; 2) сумму всех чисел; 3) среднее
арифметическое — напечатайте его с двумя знаками после точки.

Здесь сумма всех чисел будет превышать Integer, а о целочисленных типах больше Integer в предыдущих главах ничего не сказано. Если использовать Integer программа вылетает с ошибкой и ученик может не догадаться почему.

Сам ответ:
Код: Выделить всё
const
  CFileName = 'Numbers.txt';
  CNumbers = 100;
procedure CreateDataFile;      { создание файла с числами }
var
  F: Text;
  i, N : integer;
begin
  Assign(F, CFileName);
  Rewrite(F);
  for i:=1 to CNumbers do begin
     Write(F, Random(500)+Random(500):5);
     if i mod 10 = 0 then Writeln(F);
  end;
  Close(F);
end;

procedure Handle;   { обработка файла с числами }
var
  F: Text;
  N, min, max, Sum, Cnt : integer;
begin
  min:=1000; { минимум }
  max:=0;    { максимум }
  Sum:=0;    { сумма }
  Cnt:=0;    { счетчик }
  Assign(F, CFileName);
  Reset(F);
  while not Eof(F) do begin
     if Eoln(F) then Readln(F); { пропуск конца строки }
     Read(F, N);
     if N<min then min:=N;
     if N>max then max:=N;
     Sum:= Sum+N;
     Cnt:= Cnt+1;
     if Cnt=CNumbers then break;
   end;
   Close(F);
   Writeln('Минимальное=', min);
   Writeln('Максимальное=', max);
   Writeln('Сумма=', Sum);
   Writeln('Среднее=', Sum/Cnt : 12:2);
end;

begin
   CreateDataFile;
   Handle;
   Writeln('ok'); Readln
end.

В процедуре CreateDataFile объявлена неиспользуемая переменная N. Также Random(500) + Random(500) максимум дают 998, а по условию задачи максимум 999.

Ну и в конце, хочу спросить у знающих людей, если убрать if Cnt=CNumbers then break и позволить процедуре Read(F,N) читать последнюю пустую строку файла, почему она возвращает 0, там же ничего кроме управляющих кодов нет !?
Парнишка
незнакомец
 
Сообщения: 4
Зарегистрирован: 21.01.2013 23:39:23

Re: Разбор примеров из книги

Сообщение Oleg_D » 04.02.2013 21:28:15

Парнишка писал(а):Здравствуйте. Нашёл пару мелких недочётов в заданиях и ответах к ним.

Спасибо за полезные замечания, мы уже обсуждали их на форуме, у себя я исправил, но не успел ещё выложить на сайт, -- жду, пока накопится ещё немного.
Вот в частности изменение в процедуре обработки:
Код: Выделить всё
procedure Handle;   { обработка файла с числами }
var F: Text;
    N, min, max, Cnt : integer;  Sum : Real;
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение Paster Fob » 15.02.2013 15:36:32

В книге расказано о процедурах inc и succ ,но до сих пор,точно не знаю чем они отличаются.Как я понял succ (pred) увеличивает (уменьшает) значение переменной на 1 или на следующее (предыдущее) значение.Тогда как в inc (dec) можно задавать дополнительный параметр и уже увеличивать (уменьшать) на определённое кол-во единиц или значений.Или всё вообще не так.
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Разбор примеров из книги

Сообщение Oleg_D » 15.02.2013 15:57:50

Paster Fob писал(а):Или всё вообще не так.

Всё так, но я дополню.
Функции SUCC и PRED заложены в язык изначально (Виртом) и применимы к любым порядковым типам.
Процедуры INC и DEC введены фирмой BORLAND в свой диалект Паскаля позднее, и применимы только к целым числам. Причина сего нововведения, насколько мне известно, -- оптимизация кода (выполняются якобы быстрее).
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение bormant » 15.02.2013 16:09:17

Paster Fob писал(а):succ (pred) увеличивает (уменьшает) значение переменной на 1 или на следующее (предыдущее) значение.
Они 1) функции, 2) возвращают следующее (предыдущее) значение аргумента, в т.ч. и для порядковых типов. inc/dec изменяют аргумент (целое), увеличивая/уменьшая его на 1 или заданное значение.
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: Разбор примеров из книги

Сообщение Vapaamies » 15.02.2013 16:52:53

Oleg_D писал(а):Процедуры INC и DEC введены фирмой BORLAND в свой диалект Паскаля позднее, и применимы только к целым числам. Причина сего нововведения, насколько мне известно, -- оптимизация кода (выполняются якобы быстрее).

Если включен расширенный синтаксис {$X+}, Inc/Dec применимы много где, в том числе для PChar/PWideChar и для любых порядковых типов. Выполняются они не якобы быстрее, а на деле являются макросами компилятора, при кодогенерации раскрываемыми непосредственно в код. Поэтому для них нет реализации в System.
Аватара пользователя
Vapaamies
постоялец
 
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург

Re: Разбор примеров из книги

Сообщение Paster Fob » 15.02.2013 18:32:16

Oleg_D писал(а):Процедуры INC и DEC ... применимы только к целым числам.


Вот и в книге написано что inc для целых чисел,хотя применяется как и succ,например :

Код: Выделить всё
type
   TSuit = (Hearts, Clubs, Diamonds, Spades);
var
   Character : char;
   Number    : Integer;
   Card      : TSuit;

begin
   Character := 'A';
   writeln('Символ : '+Character);
   Inc(Character);
   writeln('Символ+1 : '+Character);

   Number := 23;
   writeln('Число : ',Number);
   Inc(Number, 5);
   writeln('Число+5 :' ,Number);

   Card := Hearts;
   writeln('начальное значение карты черви');
   Inc(Card);
   if Card = Clubs then
     writeln('Карта сейчас Крести');
   readln
end.


Да и про дополнительный параметр в книге ничего нет.По крайней мере я не нашёл.
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Разбор примеров из книги

Сообщение Oleg_D » 16.02.2013 13:35:30

Vapaamies писал(а):Выполняются они не якобы быстрее, а на деле являются макросами компилятора

Ага, вот оно как сделано! Для новичков поясню, что ускорение достигается за счёт устранения операций вызова подпрограммы и возврата из неё. Но объём кода будет, вероятно, несколько больше.
Paster Fob писал(а):Вот и в книге написано что inc для целых чисел,хотя применяется как и succ

Да, тут я неправ оказался, недооценил INC/DEC :) Вот моя тестирующая программка:
Код: Выделить всё
{$Q+,R-}
type TName = (_A_, _B_, _C_);
var  N: TName;
     C: Char;
     B: Boolean;
     i: integer;
begin
  N:= _A_;
  for i:=1 to 5 do begin
    Write(Ord(N):4);
    Inc(N);                { Ошибка при включеном R+ }
  end;
  Writeln;
  {---------------}
  C:= 'A';
  for i:=1 to 5 do begin
    Write(C:4);
    Inc(C);
  end;
  Writeln;
  {---------------}
  B:= False;
  for i:=1 to 5 do begin
    Write(Ord(B):4);
    Inc(B);
  end;
  Writeln;
  {---------------}
  Writeln(B);  { В Delphi  выводит абракадабру }
  Readln;
end.

Исследовал в FP, BP, Delphi и даже в ABCNet.
Кстати, обратил внимание, что FP не реагирует на директивы в тексте, они изменяются только через окно.
Paster Fob писал(а):Да и про дополнительный параметр в книге ничего нет.По крайней мере я не нашёл.

Я сознательно промолчал о втором параметре, поскольку в книге не применял. Был уверен, что ученик прочтёт и другие, более полные описания языка.
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение Vapaamies » 16.02.2013 21:33:52

Oleg_D писал(а):Но объём кода будет, вероятно, несколько больше.

Думается, что наоборот: процессорные инструкции INC/DEC применяются довольно часто, поэтому кодируются опкодом меньшей длины, чем вызов процедуры, который еще включает в себя адрес -- 4 байта для 32-битного режима.
Аватара пользователя
Vapaamies
постоялец
 
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург

Re: Разбор примеров из книги

Сообщение Oleg_D » 16.02.2013 23:09:05

Vapaamies писал(а):Думается, что наоборот: процессорные инструкции INC/DEC применяются довольно часто, поэтому кодируются опкодом меньшей длины, чем вызов процедуры, который еще включает в себя адрес -- 4 байта для 32-битного режима.

Согласен, в данном случае наверняка короче. Но, вообще говоря, макросы могут увеличивать код, повышая скорость.
Интересно, такие конструкции, как
N := N+1
или
N += 1
современные компиляторы оптимизируют как-то?
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение Garrus_En » 14.03.2013 20:28:11

Глава 44. немогу собрать в кучу разъехавшийся мозг :D

Задание на слабо (Б)
Код: Выделить всё
{P_44_5}


Function UpCode(arg:char):char;
var Kir : set of 'а'..'я';
    Lat : set of 'a'..'z';

Begin
        if arg in Kir then UpCode:=ord(arg)+33;
        if arg in Lat then UpCode:=ord(arg)+26;
end;

Var S:string;
    n:integer;

begin
        Writeln('Vvedite stroku ');Readln(S);
        for n:=1 to length(S) do UpCode(s[n]);
        Writeln(S);Readln;
end.
Garrus_En
незнакомец
 
Сообщения: 9
Зарегистрирован: 11.03.2013 22:38:26

Re: Разбор примеров из книги

Сообщение Paster Fob » 14.03.2013 21:32:09

Garrus_En писал(а):Глава 44. немогу собрать в кучу разъехавшийся мозг :D


Всё просто.
Код: Выделить всё
{P_44_5}

function UpCode(var arg:char):char;
Begin
  case arg of
    'a'..'z' : UpCode:=char(ord(arg)-32);
    'а'..'п' : UpCode:=char(ord(arg)-32);
    'р'..'я' : UpCode:=char(ord(arg)-80);
         'ё' : UpCode:=char(ord(arg)-1);
  end;
end;

Var
  S:string;
  n:integer;

begin
  Writeln('Vvedite stroku ');
  Readln(S);
  for n:=1 to length(S) do
    S[n]:=UpCode(S[n]);
  Writeln(S);
  Readln;
end.
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Разбор примеров из книги

Сообщение Garrus_En » 15.03.2013 16:26:15

Спасибо.
Блин отчего такие сложности с кириллицей.
Garrus_En
незнакомец
 
Сообщения: 9
Зарегистрирован: 11.03.2013 22:38:26

Пред.

Вернуться в Книга "Песни о Паскале"

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru