1. Заголовок темы должен быть информативным. В противном случае тема удаляется ... 2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения. 3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора). 5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM! 6. Одна тема - один вопрос (задача) 7.Проверяйте программы перед тем, как разместить их на форуме!!! 8.Спрашивайте и отвечайте четко и по существу!!!
Значит, где-то ещё ошибка. Смотри, перед этим ты вызвала Cearch_element(q); Значит, q должно указывать на нужный тебе элемент, так? И значит вставлять тебе нужно именно после q, а не после непонятного указателя p1, который вообще-то у тебя всегда указывает на начало списка, как и first
Володя, Миша спасибо большое с функцией получилось,(как-то все время, а времени то всего один прошедший семестр и предыдущий курсовик, пользовалась процедурами) переменные попробую исправить. Не прощаюсь насовсем, предполагаю, что будет еще проблемма. I'll be back!
Володя, Миша спасибо большое с функцией получилось,(как-то все время, а времени то всего один прошедший семестр и предыдущий курсовик, пользовалась процедурами) переменные попробую исправить. Не прощаюсь насовсем, предполагаю, что будет еще проблемма. I'll be back!
Are anybody here? Привет! Вот та самая проблемма, которую я вчера предполагала, так сама и не додумалась. Надо все эти действия со списком (поиск, вставка) проделать в графическом режиме. С выводом начального списка получилось без проблем, а вот со вставкой не получается. Не успевают написать маленький пример, вставляю всю программу.
Надо все эти действия со списком (поиск, вставка) проделать в графическом режиме.
А знаешь, почему у тебя это не получается или получается настолько сложно? Потому, что нельзя ни в коем случае перемешивать логику работы программы и ее интерфейс. Это - святой принцип, отступать от которого нельзя никогда.
Представь, что тебе понадобится немного изменить интерфейс. НО он у тебя настолько переплетен с логикой, что ты невольно будешь менять и ее, чего тебе совсем не хотелось бы. Обратное тоже верно... Я попробую покумекать над этой программой, и отделить "мух от котлет", сегодня к вечеру отпишусь, что получилось...
А знаешь, почему у тебя это не получается или получается настолько сложно? Потому, что нельзя ни в коем случае перемешивать логику работы программы и ее интерфейс. Это - святой принцип, отступать от которого нельзя никогда.
Представь, что тебе понадобится немного изменить интерфейс. НО он у тебя настолько переплетен с логикой, что ты невольно будешь менять и ее, чего тебе совсем не хотелось бы. Обратное тоже верно... Я попробую покумекать над этой программой, и отделить "мух от котлет", сегодня к вечеру отпишусь, что получилось...
Спасибо, Володя. Но, my time is over! Прийду на сайт только завтра. Я вот сомневаюсь можно-ли в поиске сравнивать таким образом переменные типа string?
Значит, так... Вот я и пришел с первоначальными результатами оптимизации. Именно первоначальными, ибо до окончательных еще очень далеко, можно еще улучшить программу, и сделать ее гораздо более читаемой.
Смотри, что я сделал:
1. Все циклы вида:
j:=0; While j<=10 do begin j:=j+1; SetFillStyle(SolidFill, White); Bar(x+(r+l)*(j-1),115,x+(l+r)*(j-1)+l,130); end;
заменены на циклы:
SetFillStyle(SolidFill, White); For j := 1 To 11 Do Bar(x+(r+l)*(j-1),115,x+(l+r)*(j-1)+l,130);
Почему? Потому, что во-первых они проще читаются, следовательно и находить недочеты и неполадки будет проще. Ну, а во-вторых - SetFillStyle делать на каждой итерации совершенно необязательно, достаточно это сделать один раз перед циклом...
2. Однотипные действия, вроде:
if(ch='0') then begin SetColor(LightRed); OutTextXY(200,120, 'You input 0. Input another number'); end
выделены в отдельные функции...
3. Немного подправлена сама организация работы с меню: вместо того, чтобы хранить все время текущую Y-позицию, я храню "индекс", т.е. порядковый номер текущего (в смысле, выбранного в данный момент) элемента. Это позволяет мне во-первых, избавиться от совершенно ненужных констант:
(зачем нужны 6 констант, если можно вычислить значение в любой момент по текущему индексу и стартовому значению?), и во-вторых, заменить булевские переменные n1, n2, n3 на массив n: array[1 .. 3] of boolean (ну, что поделать, я привык к структурированным программам )
Естественно, я не мог оставить в программе и вот это:
OutTextXY(10,45,'Create new list'); OutTextXY(10,120,'Paste cell'); OutTextXY(10,195,'Delete cell'); OutTextXY(10,270,'Find cell '); OutTextXY(10,345,'Move last cell'); OutTextXY(10,420,'Exit');
- строки были записаны в массив и выведены в простом цикле...
4. Блок обработки расширенных клавиш (то, что ты называешь HARD) внесен в основной Case:
Case ReadKey Of #0: begin { Здесь - расширенные клавиши } end; #27: ; { а здесь начинается обработка обычных ... } End;
Кстати, у тебя была ошибка:
While ch <> '27'do begin ... end;
это не везде будет компилироваться (зависит от настроек компилятора), ибо некорректно сравнивать символ со строкой...
5. Теперь о главном: у тебя же был список целых? Зачем ты его превратила в список строк? Теперь ты понимаешь, что я имел в виду, когда говорил, что нельзя смешивать интерфейс и логику? Ты изменила базовый тип, потому что он не вписывался в твой интерфейс!!! Не стоит этого делать. Интерфейс должен подстраиваться под логику, а не наоборот. Смотри, что нужно было сделать:
type pt = ^elem; elem = record info: Integer; { <--- Ничего не меняем !!! } next : pt; end;
procedure Create_list(var p, first, last, curr:pt); {Creation of new list} var n, A:byte; begin first := nil; last := nil; for n:=1 to 10 do begin A:=Random(99)+1; new(curr);
curr^.info := A; curr^.next := nil; ShowListItem(45, n, curr); { <--- Единственное, что добавить !!! }
if first=nil then first:=curr else last^.next:=curr;
last:=curr; end; p:=first; end;
То, что я добавил - это процедура отрисовки определенного элемента. Понимаешь? Тебя на этапе создания списка вообще не должно волновать, как именно будет отображаться этот элемент. Для этого есть Интерфейс. Ты ему передала все необходимые данные, и все. А как реализовать конкретно отрисовку этого элемента списка - это ты будешь думать уже потом, на этапе реализации интерфейса. Если он будет графическим, то функция ShowListItem, например, может быть такой:
Procedure ShowListItem(yPos, n: integer; p: pt); var s: string; begin str(p^.info, s);
, будет текстовым - процедура будет другой. НО!!! Изменяться будет только эта процедура! Сам принцип формирования списка остается неизменным, и потому - неприкосновенным...
6. Ну, и еще одно... Нежелательно описывать все переменные, как глобальные. Я уже как-то приводил на форуме пример программы, в которой при простом перемещении нескольких переменных ниже по тексту программы (ближе к концу) еще на этапе компиляции (!!!) выявлялась очень трудноуловимая ошибка, так что я еще раз повторяю: переменная должна быть описана как можно ближе к тому блоку, в котором она используется... Вот, например, у тебя в программе, где описаны переменные
var gd, gm: integer;
? А используются где? Только в основном блоке? Вот и описывай их там. Во избежание... Конечно, именно эти переменные ничего не меняют в данном случае, это просто пример, но все же...
Ну, и, наконец, сама подкорректированная программа: (я не стал добавлять отсутствующие функции, попробуй это сделать сама, если что - обращайся, подскажем как что поправить )
Я вот сомневаюсь можно-ли в поиске сравнивать таким образом переменные типа string?
madam, что касается сравнения string'ов, то есть определенные правила. Копирую кусок из руководства к ТР:
Цитата
Операции отношения =, о, >, <, >=, <= выполняются над двумя строками посимвольно, слева направо с учетом внутренней кодировки символов (см. табл.4.1 и прил.2). Если одна строка меньше другой по длине, недостающие символы короткой строки заменяются значением СНR(0) . Следующие операции отношения дадут значение TRUE: '''' < ' . ' 'А' > '1' 'Turbo' <' Turbo Pascal' 'Паскаль' >'Turbo Pascal'
Но кроме того, у меня совет общего характера.. Если у тебя возникает сомнение относительно применения чего-то, то наиболее простой путь - это попробовать. Быстренько варганишь прогу типа такого (в данном случае) :
Код
var s1,s2:string; begin s1:='aa'; s2:='bb'; WriteLn(s1<>s2); end.
- и прогоняешь ее. Потом уточняешь значения параметров или редактируешь конструкцию, перекомпилируешь - и снова.. Я понимаю, что до этого нетрудно догадаться, но иногда все же не приходит в голову..
--------------------
я - ветер, я северный холодный ветер я час расставанья, я год возвращенья домой
Володя, ты просто волшебник, а я еще только учусь. Но все равно, со стыда чуть не сгорела. Спасибо большое, теперь можно думать дальше, а то совсем головешку переклинило. Кстати, я пока только запустила твою программу, еще не разбиралась, но после поиска она выводит на экран не обновленный список, а новый элемент.
я пока только запустила твою программу, еще не разбиралась, но после поиска она выводит на экран не обновленный список, а новый элемент.
А что она раньше выводила?
А я ведь говорил:
Цитата(volvo @ 7.10.2006 1:55)
я не стал добавлять отсутствующие функции, попробуй это сделать сама
А то, что она ВООБЩЕ что-то выводит - это, как видно, побочный эффект, от которого, кстати, надо избавляться. Побочных эффектов в программе быть не должно...
А я ведь говорил: А то, что она ВООБЩЕ что-то выводит - это, как видно, побочный эффект, от которого, кстати, надо избавляться. Побочных эффектов в программе быть не должно...
Там есть процедура Insert, она-то и должна была выводить обновленный список.
Должна была и выводила - это разные вещи. Запусти свой первоначальный вариант, и посмотри, что именно процедура Insert делала...
Да то же ничего хорошего не делала. Или тоже новый элемент или последний элемент списка. Ладно, как раз сижу и разбираюсь. Что тебе сказать по поводу твоей программы: - НЕТ ПРЕДЕЛА СОВЕРШЕНСТВУ! В прошлом семестре сдала подобный корявый курсовик, так препод так и не поверила, что я сама сделала, а такой шикарный и показывать страшно. Может чуть-чуть подпортить? Это шутка юмора такая.
2. Немного изменен способ обработки вводимых значений: теперь (я пока имею в виду только пункт меню "Paste Cell") для того, чтобы вставить новый элемент списка после заданного, нужно ввести значение заданного элемента (1 или 2 цифры), и нажать Enter.
3. Кстати, теперь вставка нового элемента в список работает как положено (остальные функции еще не реализованы)...
4. Подправлена процедура создания списка (Create_List), удалены ненужные параметры, кроме того, наведен порядок в глобальных переменных (часть удалена и заменена локальными, некоторые заменены на константы)...
Вот программа: madam2.pas ( 8.23 килобайт )
Кол-во скачиваний: 544
P.S. А чего это я один в этой теме? Больше никому не интересно?
Нет, Volvo, ты не один, мне очень-очень интересно. Надо же, я тебя вчера всего десять минут не дождалась. Думала ты уже ушел отдыхать. И сегодня "... Чуть свет уж на ногах - и я у ваших ног." Вчерашнее толь-только переварила, а ты уже новое накузюкал. Буду разбираться поновой. Спасибо большое-пребольшое. { Мой личный смайлик: "Бурные аплодисменты, преходящие в продолжительную авацию."}
Volvo, я не поняла, зачем ты делаешь проверку на ноль значения V, CheckValueZero? При вводе искомого элемента на ноль проверяет CheckZero, а генерирует новый элемент Random(98)+1, так что вроде 0 неоткуда взяться, или я туплю? И еще была переменная для значения нового элемента M, а ты ее задублировал V?
Volvo, я тут умру сейчас совсем. удалить най денный элемент. слава Volvo, получилось. А потом пытаюсь вывести удаленный (4 кнопка), опять выводится всяка дрянь. А как поменять местами первый и последний элемент совсем не соображу. Пожаааалуйста, последний рывок, и я от тебя отстану (может быть навряд ли). Прикрепляю переделанный код.
А потом пытаюсь вывести удаленный (4 кнопка), опять выводится всяка дрянь
Ну, так правильно... Тебе, чтобы вывести только что удаленный элемент достаточно сделать так:
4: begin
if not CheckValueZero(2, M) then begin SetFillStyle(SolidFill, White); Bar(195, 265, 225, 280); str(M, s); { <--- !!! Этого достаточно !!! } SetColor(Black); OutTextXY(200, 270, s); end end;
, не правда ли?
P.S. Стоп, стоп...
Не в этом проблема. Все в самом меню остается как и было, там все верно... Ошибка - здесь:
procedure Delafter(var q:pt;var temp:pt);{Delete cell after number} var n:byte;
begin temp:= q^.next; { <-- Ты запомнила значение ? } q^.next:=q^.next^.next; temp^.next:= nil;
temp := p1; { <-- И тут же его разрушила ??? } n := 1; while temp<>nil do begin
ShowListItem(195, n, temp); inc(n);
temp:=temp^.next;
end; end;
Вот так исправляем:
procedure Delafter(var q:pt;var temp:pt);{Delete cell after number} var T: pt; n:byte;
begin temp:= q^.next; q^.next:=q^.next^.next; temp^.next:= nil;
Нет не правда. M это элемент, который стоит перед удаленным. Написано, что пока мы не сделали Dispose, к удаленному элементу сохраняется доступ и поэтому я его и передала по ссылке и обозвала спец-но так: temp?