• Добро пожаловать на компьютерный форум Tehnari.ru. Здесь разбираемся с проблемами ПК и ноутбуков: Windows, драйверы, «железо», сборка и апгрейд, софт и безопасность. Форум работает много лет, сейчас он переехал на новый движок, но старые темы и аккаунты мы постарались сохранить максимально аккуратно.

    Форум не связан с магазинами и сервисами – мы ничего не продаём и не даём «рекламу под видом совета». Отвечают обычные участники и модераторы, которые следят за порядком и качеством подсказок.

    Если вы у нас впервые, загляните на страницу о форуме и правила – там коротко описано, как задать вопрос так, чтобы быстро получить ответ. Чтобы создавать темы и писать сообщения, сначала зарегистрируйтесь, а затем войдите под своим логином.

    Не знаете, с чего начать? Создайте тему с описанием проблемы – подскажем и при необходимости перенесём её в подходящий раздел.
    Задать вопрос Новые сообщения Как правильно спросить
    Если пришли по старой ссылке со старого Tehnari.ru – вы на нужном месте, просто продолжайте обсуждение.

Паскаль: обсуждение вариантов решения задач

Регистрация
25 Янв 2011
Сообщения
27
Реакции
0
Баллы
0
Паскаль: обсуждение вариантов решения задач

Задача:
Для массива Х [1..40] вывести первый отрицательный элемент и его порядковый номер.

Вот мой вариант:
Uses Crt;
Label met1;
Var a:array[1..40] of Word;
i,k:integer;
Begin
randomize; {я могу ошибиться}
For i:=1 to 40 do
a:=random(1000)-1000;
For i:=1 to 40 do
begin
if a<0 then begin
k:=i; Writeln(a,k); goto met1;
end;
end;
met1:Readkey;
End.
 
Вот мой вариант:
Между прочим - куча ошибок. Не говоря уже о том, что использование меток и переходов по меткам - вообще дурной стиль.
Uses Crt;
Label met1;
Var a:array[1..40] of Word;
i,k:integer;
Begin
randomize; {я могу ошибиться}
For i:=1 to 40 do
a:=random(1000)-1000;
Итак, вы определили тип массива Word. Но тип Word вообще не допускает отрицательных значений! А вот присваиваете Вы значение элементам массива в диапазоне -1..-1000, что плохо по двум причинам: во-первых, как уже говорилось, явная нестыковка по типам, во-вторых, при такой выборке ВСЕ БЕЗ ИСКЛЮЧЕНИЯ элементы массива будут отрицательными, а потому исходная задача (поиск первого отрицательного элемента) теряет смысл.
Непонятно, зачем вообще нужно k? Почему не написать просто Writeln(a,i);? Между прочим, и сам вывод сделан безграмотно: без форматов или пробелов оба числа просто сольются в одно целое. Ну очень удобно!
P.S. Мне кажется, рановато Вы такой ник выбрали. Учитесь!
P.P.S. А если Вы не знаете, как без меток выйти из цикла - подскажу. Для этого в Паскале предусмотрен оператор Break. С его помощью блок выбора первого отрицательного числа можно преобразовать, например, так:
Код:
For i:=1 to 40 do
  if a[i]<0 then 
   begin
    Writeln(i,'   ',a[i]); 
    break;
   end;
Readkey;
 
:tehnari_ru_657:
Uses Crt;
Var a:array[1..40] of longint;
i,k:integer;
Begin
randomize; {я могу ошибиться}
For i:=1 to 40 do
a:=random(10000)-10000;
For i:=1 to 40 do
begin
if a<0 then begin
Writeln(a,' ',i); break;
end;
end;
Readkey;
End.
 
Уже лучше, но вот эта строка:

по-прежнему никуда не годится.
Операция Random(N) возвращает случайно выбранное целое число в диапазоне 0..(N-1); соответственно Random(N)-N возвращает число в диапазоне -N..-1, т.е. опять ВСЕ БЕЗ ИСКЛЮЧЕНИЯ элементы массива оказываются отрицательными и задача полностью теряет смысл.
P.S. Чтобы не путать заказчицу, перенесу обсуждение Вашей программы в отдельную тему.
 
Уважаемый Vladimir S
Не подумайте что я ноль в Паскале я его довольно хорошо знаю просто я ещё учусь в школе 9 класс и всех тонкостей не знаю
Расскажите как сделать так как надо по задаче.
 
Уважаемый Vladimir S
Не подумайте что я ноль в Паскале я его довольно хорошо знаю просто я ещё учусь в школе 9 класс и всех тонкостей не знаю
Расскажите как сделать так как надо по задаче.
Ну... один из вариантов решения "так, как надо" был мною выложен:
http://www.tehnari.ru/f41/t46278/#post452337
Посмотрите внимательно.
P.S. К сожалению, тег "Spoiler" на этом форуме не задействован.
P.P.S. И еще пара замечаний. Во-первых, если Вы видите, что кто-то из программистов уже выложил решение задачи, то не следует выкладывать своё (по принципу "А вот мой вариант!"), если только Вы не уверены, что Вам удалось найти существенно лучшее решение или что выложенное содержит принципиальные ошибки - это просто невежливо по отношению к коллеге. Кроме того, даже если на Ваш взгляд программа совсем простая, нужно обязательно провести ее тестирование: оттранслировать, запустить и т.д., а не просто "написал-выложил".
 
полностью согласен с Vladimir_S. ну и что что ты в 9-м учишься? я допустим учусь в 11м и паскаль также проходил только в 9-м классе. В любом случае если ты помогаешь решать кому-то, то сам сначала реши. причем не на литске бумаги, а в самом паскале. Протестируй на предельные значения и прочее. Со всем уважением. Успехов в изучении паскаля.
 
Сделаем немного эффективнее
Uses Crt;
var A,B,D: array[1..10] of integer;
m,i:integer;
begin
clrscr;
write('введите число элементов массивов <=10 - ');
readln(m);
writeln('введите элементы массива A и B');
for i:=1 to m do
begin
write ('A[',i,']= ');
readln (A);
Writeln;
write ('B[',i,']= ');
readln (B);
D:=A-B;
end;
writeln;
writeln('вывод массивов');
for i:=1 to m do
write (A:5);
writeln;
write (B:5);
writeln;
write (D:5);
writeln;
readkey;
end;
Я тоже не проверял, но думаю заработает
 
Mr.Програмист Приставки з в русском языке нет!

В чем заключается эффективность вашего варианта? В неправильной организации вывода массивов? К тому же, в вашей программе при заполнении исходных массивов легко запутаться в выборе нужного значения для ввода. Программа на языке Pascal согласно синтаксису должна заканчиваться точкой, а не точкой с запятой.

Просьба к вам - используйте тег [ code ] для оформления листинга
 
Вот моя задача чтобы раскачать тему. Разбирайте.
Код:
Program bankomat;
Uses Crt;
Label met1,met2,met3,met4,met5,met6,met7,met8;
Var a,c,b,d,i,n,k5000,k1000,k500,k100,k50:integer;
Begin
k5000:=10000;
k1000:=10000;
k500:=10000;
k100:=10000;
k50:=10000;
met3:
i:=1;
n:=5;
Repeat
Begin
Writeln('Введите пинкод');
Readln(a);
If a=1973
Then begin Writeln('Пин код веден верно'); goto met1; end
Else Writeln('Вы ошиблись');
If i=4
Then
begin
Writeln('Карточка заблокирована'); goto met2;
end;
i:=i+1;
end;
Until i>n;
met1: Writeln('Введите какую сумму вы хотите получить');
Readln(b);
c:=b div 5000;
d:=b mod 5000;
If k5000<c
then begin
k1000:=k1000+(c-k5000); goto met4; end
Else
For i:=1 to c do
begin
Writeln('5000 руб;');
k5000:=k5000-1;
end;
met4:c:=d div 1000;
d:=d mod 1000;
If k1000<c
then begin
k500:=k500+(c-k1000); goto met5; end
Else
For i:=1 to c do
begin
Writeln('1000 руб');
k1000:=k1000-1;
end;
met5:c:=d div 500;
d:=d mod 500;
If k500<c
then begin
k500:=k500+(c-k1000); goto met6; end
Else
For i:=1 to c do
begin
Writeln('500 руб');
k500:=k500-1;
end;
met6:c:=d div 100;
d:=d mod 100;
If k100<c
then begin
k100:=k100+(c-k500); goto met7; end
Else
For i:=1 to c do
begin
Writeln('100 руб');
k100:=k100-1;
end;
met7:c:=d div 50;
d:=d mod 50;
If k5000<c
then
goto met8;
For i:=1 to c do
begin
Writeln('50 руб');
k50:=k50-1;
end;
met8:Writeln(d,'удержано');
Writeln('Введите 1 чтобы повторить, 2 чтобы выйти');
Readln(d);
If d=1
Then goto met3
Else
readkey;
met2:end.
 
Последнее редактирование:
Вот моя задача чтобы раскачать тему. Разбирайте.
Ага, спасибо. А то нам как раз заняться нечем.
Хотя, с другой стороны, всё-таки занялся, и считаю, что это очень полезное сообщение. И всем начинающим программистам советую внимательно предложенный код изучить. Потому что перед нами - ярчайший пример того, как НЕ СЛЕДУЕТ писать программы.
Что касается самого автора, то объяснять и доказывать что-либо ему я уже не берусь - реакция последует привычная: соплячье самоутверждение и деланье нарочито поперёк, дескать, вот я какой! Ну да не о нем речь.
Прежде всего, сформулируем задачу (чего MrПрограМист, естественно, сделать не сподобился):
Код:
Написать программу, имитирующую работу банкомата: 
проверку пинкода, блокировку карточки при трехкратном неверном
вводе, запрос требуемой суммы и раскладку выдачи по количеству и
номиналам купюр.
В принципе, предложенная автором программа работает, и даже правильно, но:
1. Как неоднократно указывалось тому же Mr.ПрограМисту, один из признаков хорошего стиля программирования - неиспользование оператора goto, т.е. переходов по меткам. В предложенном же варианте этих меток понатыкано немерено, отсюда программа - лапша лапшой.
2. Наличие "мертвых" условных переходов с заведомо невыполнимым условием, ведущим к ветви, содержащей какую-то неудопонятную ахинею. Ну в самом деле, если мы присваиваем переменной k5000 значение 10000, то как результат целочисленного деления некоей величины на 5000 может оказаться большим k5000, т.е. 10000? Об этом знает только один MrПрограМист, равно как и вообще о смысле всех тих переменных k5000, k1000 и т.д. Я как-то смысла в них, равно как и в последовательности действий типа k1000:=k1000+(c-k5000); не уловил абсолютно. По-моему, галиматья полная.
Приведу с моей точки зрения нормальный код, решающий эту задачу:
Код:
Program bankomat;
Const
 Pincod=1973;
 Nom:Array[1..5] of Word=(5000,1000,500,100,50);

Var
 pc,c,d,ex,i,j:Word;

BEGIN
 i:=1;
 Repeat
  Writeln('Введите пинкод');
  Readln(pc);
  If pc=Pincod then
   Writeln('Пинкод введен верно')
  else Writeln('Вы ошиблись');
  Inc(i);
 Until (pc=Pincod) or (i=4);
 If i=4 then
  begin
   Writeln('Карточка заблокирована!');
   Readln;
  end
 else
  Repeat
   Writeln('Введите сумму (не более 65500 руб.), которую вы хотите получить:');
   Readln(d);
   For j:=1 to 5 do
    begin
     c:=d div Nom[j];
     d:=d mod Nom[j];
     for i:=1 to c do
      Writeln(Nom[j]:4,' руб;');
    end;
   Writeln('Удержано ',d,' руб;');
   Write('Введите 1 чтобы повторить, 2 чтобы выйти: ');
   Readln(ex);
  Until ex=2;
END.
Как говорится - "Почувствуйте разницу!".
 
Назад
Сверху