IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Очередь, менюха Case of
Jill
сообщение 14.09.2005 13:57
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


Есть программка - демонстрация работы очереди. Рабочая. Трабл в том, что менюха выбора действий Case of позволяет провести ОДНО действие. При перестановках всяких...очередь куда-то теряется sad.gif

Как сделать так, чтобы менюха висела постоянно (до команды "Выход"), и действий можно было МНОГО совершать над этой...очередью!!!

ПЛЗ!!!

Вот, собственно, программка:
Исходный код

Program SOD_3;
Uses Crt;
Type Pointer=^Line;
Line=Record
Inf:Integer;
Next:Pointer;
End;
Var Head, {голова очереди}
Tail, {хвост очереди}
First, {очередной элемент очереди}
PointerNew,P,NewP:Pointer;
f:boolean;
i:Integer;
a:Real;

{Вставка элемента в очередь}
Procedure Vstavka(Var Head,NewP,Tail:Pointer);
Var a:Real;
Begin
f:=True;
Repeat
Write('Введите целое число -> ');
{$I-} {временно отключаем контроль ошибок ввода-вывода}
Readln(a);
{$I+}
if IOResult<>0 then {ф-ция возвращает целое значение,
являющееся состоянием последней выполненной операции ввода-вывода}
begin
f:=False;
Exit;
end
Until (IOResult=0)and(a>=-32768)and(a<=32767);
New(NewP);
If Head=Nil then {очереди нет - создаем ее}
Head:=NewP
else
Tail^.Next:=NewP; {очередь есть - становимся в хвост}
Tail:=NewP; {новый хвост}
NewP^.Inf:=trunc(a);
NewP^.Next:=Nil;
End;

{Просмотр содержимого очереди}
Procedure Vyvod(Var Head,Tail:Pointer);
Begin
First:=Head;
if First<>Nil then
begin
Head:=First^.Next;
Write(First^.Inf,' ');
end;
End;

{удаление элемента}
Procedure Udalenie(var Head,Tail:Pointer);
var First:Pointer;
Begin
If Head<>Nil
then If Head=Tail {в очереди единственный элемент}
then begin Dispose(Head); Head:=Nil; Tail:=Nil end
else begin
First:=Head; Head:=Head^.Next; Dispose(First)
end
else Writeln('Удалять нельзя, т.к. очередь пуста!')
End;

{поиск максимального элемента}
Procedure Maximal(Head,Tail:Pointer);
Var K,First:Pointer;
max:Integer;
begin

if Head=Nil then Writeln('Очередь пуста!')
else begin
K:=Head;
First:=K^.Next;
max:=K^.Inf;
while First<>Nil do
begin
if max<First^.Inf then max:=First^.Inf;
First:=First^.Next;
end;
Writeln;
Writeln('Максимальный элемент: ',max);
Writeln;
end;
end;

{Основной модуль}
Begin
ClrScr;
Head:=Nil;
Mark(P);
Writeln;
Writeln('=================Создание очереди===================');
Writeln;
Writeln('Признак окончания ввода очереди - НЕ числовой символ');
Repeat Vstavka(Head,PointerNew,Tail) until not f;
if Head=Nil then
begin
Writeln('Очередь пуста!');
Readln;
Readln;
Exit;
end;
Writeln;
Writeln('Возможно произвести следующие действия:');
Writeln;
Readln;

Writeln('Показать очередь - 0');
Writeln('Добавить элемент - 1');
Writeln('Удалить элемент - 2');
Writeln('Найти максимальный - 3');
Writeln('Выход - 4');
Writeln;
Readln(i);

Case i of
0: begin First:=Head;
Writeln('Содержимое очереди:');
While First<>Nil do
Vyvod(Head,Tail); Readln; end;

1: begin First:=Head;
Vstavka(Head,NewP,Tail);
Writeln('Содержимое очереди:');
While First<>Nil do
Vyvod(Head,Tail); Readln; end;

2: begin First:=Head;
Udalenie(Head,Tail);
Writeln('Содержимое очереди:');
While First<>Nil do
Vyvod(Head,Tail); Readln; end;

3: begin First:=Head;
Maximal(Head,Tail);
Readln; end;

4: Exit end;

Readln;
Release(P); {освобождение кучи, начиная с адреса P}
End.


ЗЫ: препод злой - придираться будет к любым мелочам...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.09.2005 14:31
Сообщение #2


Гость






...
repeat
ClrScr;
Writeln;
Writeln('Возможно произвести следующие действия:');
Writeln;

Writeln('Показать очередь - 0');
Writeln('Добавить элемент - 1');
Writeln('Удалить элемент - 2');
Writeln('Найти максимальный - 3');
Writeln('Выход - 4');
Writeln;
Readln(i);

Case i of
0: begin First:=Head;
Writeln('Содержимое очереди:');
While First<>Nil do
Vyvod(Head,Tail); Readln; end;

1: begin First:=Head;
Vstavka(Head,NewP,Tail);
Writeln('Содержимое очереди:');
While First<>Nil do
Vyvod(Head,Tail); Readln; end;

2: begin First:=Head;
Udalenie(Head,Tail);
Writeln('Содержимое очереди:');
While First<>Nil do
Vyvod(Head,Tail); Readln; end;

3: begin First:=Head;
Maximal(Head,Tail);
Readln; end;
end;
until (i = 4);
...
 К началу страницы 
+ Ответить 
Jill
сообщение 14.09.2005 14:51
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


по логике - так, но... ОНА ОПЯТЬ ПРОПАДАЕТ!!!
при выбора вротого по счету действия - один ответ - "Очередь пуста!" sad.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.09.2005 15:16
Сообщение #4


Гость






Ты просто при первой же распечатке очереди полностью "расстраиваешь" указатели, и они начинают указывать совсем не туда, куда ты думаешь... Попробуй так:
procedure PrintQueue(Head: Pointer);
begin
While Head <> nil Do Begin
Write(Head^.Inf:4);
Head := Head^.Next;
End;
end;
и вызывай
  PrintQueue(Head);
вместо
  While First<>Nil do
Vyvod(Head,Tail);



P.S. Это конечно не мое дело, но вот тип указателя на Line не стоит называть Pointer, т.к. тип Pointer в Паскале уже существует. Тем более, что
Цитата
препод злой - придираться будет к любым мелочам...
 К началу страницы 
+ Ответить 
volvo
сообщение 14.09.2005 15:25
Сообщение #5


Гость






И еще... Вот альтернативный вариант реализации меню, все время "висящего" сверху:
...
clrscr;

{ Отрисовываем опции на экране }
Writeln('show - 0');
Writeln('add - 1');
Writeln('delete - 2');
Writeln('find max - 3');
Writeln('exit - 4');
Writeln;

{ Разрешаем программе работать только с нижней частью экрана }
window(1, 10, 80, 24);
repeat
repeat
i := Ord(ReadKey) - Ord('0'); { Берем выбор пользователя, без ReadLn }
until i in [0 .. 4];

Case i of
1: ...
2: ...
3: ...
end;
until (i = 4);
window(1, 1, 80, 25); { Восстанавливаем окно на весь экран }
Clrscr;
...
 К началу страницы 
+ Ответить 
Jill
сообщение 14.09.2005 15:30
Сообщение #6


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


таки-да - куда попало указывают ;-)

вроде ОК!!! спасибо большое :-) хоть с одной задачей разобралась... еще четыре...ууууух


ЗЫ: насчет Pointer вообще спасибо (буду знать, что не стоит) / но мысля эта не сама ко мне пришла - из методички нашего универа (ХАИ), содранной с инета ;-)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Jill
сообщение 14.09.2005 15:34
Сообщение #7


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


ух ты!!! интересно оЧЧЧ

попробую обязательно

спасибо smile.gif

вообще из программки ляльку сделали ;)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Jill
сообщение 14.09.2005 15:53
Сообщение #8


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


уууупс!!! все процедурки работают КРОМЕ УДАЛЕНИЯ!!! вываливается нафиг паскаль

что там не так??? sad.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.09.2005 15:58
Сообщение #9


Гость






...
If Head<>Nil
then If Head=Tail { <--- Вот это ! }
...

В Паскале нельзя сравнивать указатели друг с другом - можно только с Nil... Чтобы проверить, единственный ли это элемент:
If Head <> Nil Then
If Head^.Next = Nil { <--- Так должно быть... }


P.S. Да и вообще, что мешает сделать так:
Procedure Udalenie(var Head, Tail: Pointer);
var First: Pointer;
Begin
If Head<>Nil Then Begin
First:=Head; Head:=Head^.Next; Dispose(First);
If Head = nil Then Tail := nil
End
Else Writeln('Удалять нельзя, т.к. очередь пуста!')
End;
?
 К началу страницы 
+ Ответить 
Jill
сообщение 14.09.2005 16:08
Сообщение #10


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


ууууууууууу sad.gif

а так - черти что после удаления выдает..........

______________________________
я погибну под этой задачей.......
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.09.2005 16:09
Сообщение #11


Гость






Пост №4 перечитай, и сравни со своим выводом...
PrintQueue(Head);
Так - не работает?
 К началу страницы 
+ Ответить 
Jill
сообщение 14.09.2005 16:20
Сообщение #12


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


сейчас вообще что попало выводит sad.gif
c
PrintQueue(First);
только удаление не проходило...

забор полнейший...sad.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.09.2005 16:28
Сообщение #13


Гость






Не знаю, у меня все работает... Посмотри:


Прикрепленные файлы
Прикрепленный файл  test_it.pas ( 3.59 килобайт ) Кол-во скачиваний: 154
 К началу страницы 
+ Ответить 
Jill
сообщение 14.09.2005 16:35
Сообщение #14


Пионер
**

Группа: Пользователи
Сообщений: 105
Пол: Женский
Реальное имя: Юлия

Репутация: -  0  +


действительно работает...

пошла разбираться в чем дЫк

спасибо БОЛЬШОЕ!!! :-)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 6.05.2024 14:44
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"