Другое > Hard'n'Soft
Вспоминаем Turbo Pascal и решаем задачи на нём
(1/15) > >>
gepar:
Решил создать эту тему по совету topos84 так как прошлая была больше о программировании в общем чем о Паскале .
Хочу научиться использовать метки , но в интернете в основном написано что-то типа " не стоит их использовать так что расписывать как ими пользоваться не будем..." , то что ими злоупотреблять не стоит я понял , но всё же я хочу научиться пользоваться и ими .Подскажите кто разбирается плыз как их обозначать в описании переменных и как потом вызывать в самой программе , можно на примере любой простенькой програмульки  .
RBM13s:
http://pascal.proweb.kz/index.php?page=12
Про метки в ТР, но использовать реально не стоит. Лучше освоить циклы.
Йобан Матич:

--- Цитата ---j := 0;
for i := 0 to 10 do
begin
      j := j + 1;
      if j = 5 then break
end;

--- Конец цитаты ---

По рукам за такое бить надо.
gepar:
RBM13s, с метками разобрался .

Добавлено позже:
Йобан Матич, а за что конкретно хоть ?Что в примере приведённом на той странице не так? :)
aUruM:

--- Цитата: RBM13s ---использовать реально не стоит
--- Конец цитаты ---
Надо заметить, что, хотя использование меток и goto в языках высокого уровня считается дурным тоном, в некоторых случаях в реальной жизни к этому приему приходится прибегать. Например, в случае, когда надо выйти сразу из нескольких вложенных циклов.
Йобан Матич:

--- Цитата: gepar --- а за что конкретно хоть ?
--- Конец цитаты ---
Может пример немного неудачен, но можно написать так:

--- Цитата ---i := 4;
j := 5;

--- Конец цитаты ---
Результат будет тем же =)
gepar:
Проблема: у меня есть три условия и если они все три не выполняются я хочу чтобы выполнялось 4ое условие else .
Вопрос:как это сделать ?Если без if , а с использованием case то тоже как это сделать ?
Задача программы:вывести наибольшее число из 3ёх введённых чисел .
Код НЕработающей программы :
program   ex_2;
uses crt;
var
a,b,c,s,res:integer;
label 1,2;
Begin
     1:writeln('enter a');
     read(a);
     writeln('enter b');
     read(b);
     writeln('enter c');
     read(c);
     if (a>b) and (b>c) then writeln(a);
     if (b>a) and (a>c) then writeln(b);
     if (c>a) and (c>b) then writeln(c);
     else writeln ('2 chisla sovpadaut');
     write('Prodljit" vi4islrniya ? 1 - da , 2 - net ');
     read(s);
     if s=1 then goto 1;
end.
Заранее спасибо ответившему .
aUruM:
gepar, а что мешает сделать вложенные if'ы? Например, вот так:

--- Код: ---if (a>b) and (b>c)
  then
    writeln(a)
  else
    if (b>a) and (a>c)
      then
        writeln(b)
      else
        if (c>a) and (c>b)
            then
              writeln(c)
            else
              writeln ('2 chisla sovpadaut');
--- Конец кода ---
gepar:
aUruM, спасибо за подсказку .В том учебнике что я читал (откуда и упражнения кстати) я не нашёл информации о вложенных if'ах и лишь после твоей наводки нагуглил инфу о вложенных if'ах .
RBM13s:

--- Цитата: aUruM от 27 Октябрь 2009, 18:38:22 ---Надо заметить, что, хотя использование меток и goto в языках высокого уровня считается дурным тоном, в некоторых случаях в реальной жизни к этому приему приходится прибегать. Например, в случае, когда надо выйти сразу из нескольких вложенных циклов.

--- Конец цитаты ---
А что мешает тем же break'ом при определенном условии выходить из циклов? Хотя лучше приведи пример, мне понятнее будет о чём ты.
aUruM:

--- Цитата: RBM13s ---А что мешает тем же break'ом при определенном условии выходить из циклов?
--- Конец цитаты ---
В принципе, ничто не мешает. Но куда проще один раз написать goto метка, чем в каждом из вложенных циклов прописывать условия выхода.
RBM13s:
У меня до сих пор от таких "простых выходов" бросает в дрожь. Как представлю, что потом надо будет блок-схему чертить XD
HardWareMan:

--- Цитата: Йобан Матич от 27 Октябрь 2009, 20:05:38 ---Может пример немного неудачен, но можно написать так:Результат будет тем же =)

--- Конец цитаты ---
А кто говорит, что требуется именно результат? Может задача стоит в том, чтобы научиться прерывать цикл. Например все тот же код, но несколько измененный:

--- Код: ---j := 0;
for i := 0 to 10 do
begin
     inc(j);
     if j = d then break
end;
--- Конец кода ---
(Извините, не удержался. Не люблю конструкции типо x:=x+1, я предпочитаю inc/dec) А d может изменяться перед вызовом этого куска кода.


--- Цитата: RBM13s от 28 Октябрь 2009, 01:54:14 ---У меня до сих пор от таких "простых выходов" бросает в дрожь. Как представлю, что потом надо будет блок-схему чертить XD
--- Конец цитаты ---
Сразу видно, кто тут АСМа не нюхал.  :D Нарисуй блок-схему проги на асме и ты поймешь, что ты еще только в песочнице, а на стройку тебе еще рано.
Касаемо goto - согласен. Моя первая программа на пасе (лет 10 назад) после АСМа содержала порядка 80(!) меток, но работала стабильно (+ метки я привык обзывать тематически, поэтому всегда понятно что и куда). Сейчас уже лет 8 как в моих программах метки если встречаются, то только в ассемблерных вставках, и то, стараюсь все делать линейно.

Например, надо выйти из куска кода, если ни одно условие не выполнено. Казалось бы, заюзай goto и будет тебе счастье, так ведь нет - дурной тон. Ок, второй вариант - break, но он работает только для циклов. Тогда приходится делать так:

--- Код: ---var ok:boolean;
// Наш код
...
// Точка входа в кусок кода, который и проверяет что-то
while true do begin
 ok:=false;
 if (....) then break;
// Чтонить делаем и еще проверяем
 if (....) then break;
// Еще чтото сделаем
 if (....) then break;
// Делаем
....
// Выход из секции
  ok:=true;
  break;
  end;
// Проверяем, выполнен ли весь инит?
if ok then begin
  // Все ОК, работаем
  end else begin
  // Чтото обломалось, скажем юзеру
  end;

--- Конец кода ---
В принципе все понятно, ведь правда? И гораздо аккуратнее и более читабельнее, чем вложенные условия. Если вложенных циклов несколько, то все будет так же:

--- Код: ---// Наш код
while a<b do begin
  ok:=false;
  // Код
  for d:=0 to 30 do begin
      // Код
      if (....) then break;
      if (....) then ok:=true;
      // Еще код
      end;
  if not ok then break;
  // Продолжающийся код
  end;
--- Конец кода ---
Ну, в общем идея понятна, да? Работаем с флагами. Кстати, прием хорошо работает и на асме.

В случае с case'ом все по другому. Как и в циклах, там есть жесткое ограничение типов переменных, которые можно использовать. Например, можно использовать любые целые числа и делать условия:

--- Код: ---var a:integer(byte, word, longint, dfword, etc...);

case a of
  0     : // Код
  3     : // Код
  8..10 : // Код
  else // Код
  end;
--- Конец кода ---
Третье условие показывает диапазон значений, а else сработает только если не сработает ни одно из условий. case - это однопроходная структура, нужно помнить, что срабатывает только одно из условий и остальные не выполняться. Можно использовать даже char:

--- Код: ---var key,ext:char;

key:=readkey;
case key of
  'Y','y' : //Код
  #10  : //Код
  #0   : begin ext:=readkey;
               case ext of
                #$33 : // код
                end;
               end;
  end;

--- Конец кода ---
Видно, что я читаю код нажатой клавиши и делаю какие-то действия. Если код клавиши =0 (это символ, поэтому это будет chr(0) или #0), то надо дополнительно считать код расширенной клавиши и обработать вложенным case, так опрашивают курсоры, функционалы и нумпад.
Можно использовать перечисления:

--- Код: ---type TMode = (mdIdle, mdRun, mdStop);
var Mode:TMode;
     key:char;
// Наш код
key:=readkey;
case key of
  'R','r' : Mode:=mdRun;
  'S','s' : Mode:=mdStop;
  else Mode:=mdIdle;
// Теперь заюзаем наш флаг
case Mode of
  mdIdle  : sleep(1000);
  mdStop : // Код
  mdRun  : // Код
  else Mode:=mdIdle; // На всякий атас
  end;

--- Конец кода ---
Понятно? Кстати, булево так и описано: type boolean = (false, true);. Перечисления - на самом деле обычный байт (если их много, то больше: слово). Поэтому, первое обозначение получает код 0, второе 1 и т.д. Т.е. этот код эквивалентен предыдущему:

--- Код: ---const mdIdle = 0;
      mdRun = 1;
      mdStop = 2;
var Mode:byte;
     key:char;
// Наш код
key:=readkey;
case key of
  'R','r' : Mode:=mdRun;
  'S','s' : Mode:=mdStop;
  else Mode:=mdIdle;
// Теперь заюзаем наш флаг
case Mode of
  mdIdle  : sleep(1000);
  mdStop : // Код
  mdRun  : // Код
  else Mode:=mdIdle; // На всякий атас
  end;

--- Конец кода ---
Но первый более элегантен.
RBM13s:

--- Цитата: HardWareMan от 28 Октябрь 2009, 06:17:11 ---Сразу видно, кто тут АСМа не нюхал.  :D Нарисуй блок-схему проги на асме и ты поймешь, что ты еще только в песочнице, а на стройку тебе еще рано.
--- Конец цитаты ---
В общем-то это я и так знаю. Пасквиль помню по лекциям из ВУЗа. Сейчас вообще только быдлокодю на PHP.
HardWareMan:

--- Цитата: RBM13s от 28 Октябрь 2009, 11:45:58 ---В общем-то это я и так знаю. Пасквиль помню по лекциям из ВУЗа. Сейчас вообще только быдлокодю на PHP.
--- Конец цитаты ---
Индусский код?
gepar:
Задание :вычислить сумму ряда s=sin(1)+sin(2)+...sin(n) , для n введённого с клавиатуры .
Перед этим был текст с repeat until , как решить не могу понять так как не могу понять что надо будет задать until тоесть начало у меня получилось таковое
program repeat_until;
uses crt;
var
n,y,x,s:real;
begin
     write('Enter n');
     read(n);
     if n>0 then
     repeat
     s:=sin(1)+sin(2)
     until
end. а как дальше поступить что-то не могу придумать так как ни разу не сталкивался с таким условием .
Fly:
Во-первых, советую в начале написать:

--- Код: ---var
  s:real;
  i,n:byte;

--- Конец кода ---
и

--- Код: ---begin
  write('Enter n: ');
  readln(n);
  s:=0; i:=1;

--- Конец кода ---
Ну а потом

--- Код: ---  repeat
    s:=s+sin(i);
    inc(i)
  until i>n;

--- Конец кода ---


Добавлено позже:
А можно даже так:

--- Код: ---var
  s:real;
  n:byte;
begin
  write('Enter n: ');
  readln(n);
  s:=0;
  repeat
    s:=s+sin(n);
    dec(n)
  until n=0;

--- Конец кода ---
gepar:
А dec(n) и  inc(i) что по сути делают ?Если можно распиши .
MetalliC:
dec(n) это n:=n-1
inc(i) i:=i+1
gepar:
Если можно , то лучше напишите пожалуйста как прошлое упражнение должен был выполнить новичок , ато так как я не разобрался с тем упражнением я не могу выполнить последующие типа этого :
Вычислить A *(A+1)*(A+2)*(A+3)* (A+N), где A и N вводятся с клавиатуры , а разобрацца с задачкой то ведь хоццо  :)

Добавлено позже:
MetalliC, понял , сейчас испытаю этот способ на други примерах .

Добавлено позже:
мда , что-то с последним уравнением тоже возникла проблемка - я снова никак не могу придумать как задать в паскале такое условие .Подскажите плыз , хотя возможно что я утром на свежую голову и придумаю что-то , но помощ если что не помешает  :)
Навигация
Главная страница сообщений
Следующая страница

Перейти к полной версии