Другое > Hard'n'Soft
Вспоминаем Turbo Pascal и решаем задачи на нём
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, понял , сейчас испытаю этот способ на други примерах .
Добавлено позже:
мда , что-то с последним уравнением тоже возникла проблемка - я снова никак не могу придумать как задать в паскале такое условие .Подскажите плыз , хотя возможно что я утром на свежую голову и придумаю что-то , но помощ если что не помешает :)
Навигация
Перейти к полной версии