На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Название темы должно быть информативным !
Прежде чем задать вопрос, воспользуйтесь Поиском. и проверьте в FAQ (ЧАВО) Паскаля
Чтобы получить вразумительный ответ, подробно опишите проблему: что надо сделать, что не получается и номер ошибки (если есть), которую выводит компилятор.
Для вставки кода ваших программ используйте, пожалуйста, кнопку СODE=pas или выпадающий список СODE для других языков (подсветка синтаксиса).
[!] Как правильно задавать вопросы | Руководство по языку B.Pascal 7 & Objects/LR | Borland Pascal. Руководство пользователя
Модераторы: volvo877
  
> Стеки в Паскаль
    Всем привет. Помогите плиз исправить 1 процедуру добавления в паскаль. у меня процедура добавляет елементы но когда ее вызвать наново она стирает все элементы и начинает наново записывать элементы, но мне нужно чтобы мы опять когда вызывали процедуру добавления оно уже к существующим элементам добавило то что мы ввели.
    Вот мой код:
    ExpandedWrap disabled
      uses
        crt;
        const
             n=4;
      type
        Tinf=integer;
        List=^TList;  
        TList=record
          data:TInf;  
          next:List;  
          N:byte;
           Prizv:string[20];
           matan:byte;
           prog:byte;
           OS:byte;
           alg:byte;
        end;
       
       
      procedure AddElem(var stek1:List;znach1:TInf);
      var
        tmp:List;
      begin
        GetMem(tmp,sizeof(TList));
        tmp^.next:=stek1;  
        tmp^.data:=znach1;
        stek1:=tmp;
      end;
       
       
       
       
       
       
      procedure Line(m:integer);
      var i:integer;
      begin
      for i:=1 to m do
      write('-');
      writeln;
      end;
       
       
       
       
      procedure Print(stek1:List);
      begin
        if stek1=nil then {проверка на пустоту стека}
        begin
          writeln('Стек пуст.');
          exit;
        end;
        while stek1<>nil do {пока указатель stek1 не станет указывать в пустоту}
        begin   {а это произойдёт как только он перейдёт по ссылке последнего элемента}
          Write(stek1^.data, ' '); {выводить данне}
          stek1:=stek1^.next  {и переносить указатель вглубь по стеку}
        end;
      end;
       
       
       
      var
        Stk,
        tmpl:List;
        znach:Tinf;
        ch:char;
        i:integer;
        
        tabl:array[1..n] of Tlist;
        
        
      begin
          Stk:=nil;
          
          
          repeat
           writeln('1) add elements');
         writeln('2) output');
         writeln('3) exit');
         writeln('press key 1..3');
         ch:=readkey;
        
        
         case ch of
         '1':begin
        
        
         for i:=1 to  n do
         begin
         writeln('enter data item' , i);
        
        
          tabl[i].N := i;
            readln(tabl[i].Prizv, tabl[i].matan, tabl[i].prog, tabl[i].OS, tabl[i].alg);
            addelem(stk,znach);
            end;
                End;
                
                
                
                
                
                
                '2':begin
                Line(69);
        writeln('|   | Призвіще | Matematuchnuy | Programyvannya | OS | Algebra | cer|');
        writeln('|   |          |    analis     |                |    |  i geom.|    |');
        Line(69);
        
        for i := 1 to n do
        begin
        print(stk);
        
        write('|', tabl[i].N: 2, ' |', tabl[i].Prizv: 10, '|');
          write(tabl[i].matan: 15, '|', tabl[i].prog: 16, '|', tabl[i].OS: 4, '|', tabl[i].alg: 9, '|',
           ((tabl[i].matan + tabl[i].prog + tabl[i].OS + tabl[i].alg) / n): 0: 2, '|');
          writeln;
          Line(69);
        end;
        writeln;
        writeln('vidcortov');
        Line(69);
        for i := 1 to n do
        begin
          if ((tabl[i].matan + tabl[i].prog + tabl[i].OS + tabl[i].alg) / 4 >= 4) then
          begin
            write('|', tabl[i].N: 2, ' |', tabl[i].Prizv: 10, '|');
            write(tabl[i].matan: 15, '|', tabl[i].prog: 16, '|', tabl[i].OS: 4, '|', tabl[i].alg: 9, '|', ((tabl[i].matan + tabl[i].
            prog + tabl[i].OS + tabl[i].alg) / n): 0: 2, '|');
            writeln;
            Line(69);
          end;
        end;
        
           End;
           end;
          
           until ch= '3';
           End.

    неделю сижу, ничего не выходит оно тупо наново пишет элементы и хоть ты тресни. спасибо
      m-misha-m,
      чтобы мне побыстрее сообразить, уточни какую процедуру ты хочешь исправить.
        Цитата Федосеев Павел @
        m-misha-m,
        чтобы мне побыстрее сообразить, уточни какую процедуру ты хочешь исправить.

        процедуру add она записывает все данные сначала если ёё вызвать повторно, а мне нужно чтобы оно дальше без удаления добавляло элементы. спасибо вам наперёд )
          m-misha-m,
          смотри - я сократил твою программу до тестового примера - оставил неизменными процедуры и основную программу переделал под тест этих процедур
          ExpandedWrap disabled
            program tak;
             
            uses
              crt;
             
            const
              n = 4;
            type
              Tinf = integer;
              List = ^TList;
             
              TList = record
                Data:  TInf;
                Next:  List;
              end;
             
              procedure AddElem(var stek1: List; znach1: TInf);
              var
                tmp: List;
              begin
                GetMem(tmp, sizeof(TList));
                tmp^.Next := stek1;
                tmp^.Data := znach1;
                stek1     := tmp;
              end;
             
              procedure Line(m: integer);
              var
                i: integer;
              begin
                for i := 1 to m do
                  Write('-');
                WriteLn;
              end;
             
              procedure Print(stek1: List);
              begin
                if stek1 = nil then {проверка на пустоту стека}
                begin
                  WriteLn('Стек пуст.');
                  exit;
                end;
                while stek1 <> nil do {пока указатель stek1 не станет указывать в пустоту}
                begin   {а это произойдёт как только он перейдёт по ссылке последнего элемента}
                  Write(stek1^.Data, ' '); {выводить данне}
                  stek1 := stek1^.Next;  {и переносить указатель вглубь по стеку}
                end;
              end;
             
            var
              Stk: List;
              znach: Tinf;
            begin
              Stk := nil;
              for znach:=1 to 10 do
                addelem(stk, znach);
              print(stk);
            end.

          Этот пример вполне работоспособен. К нему одно лишь замечание - он не освобождает память.
          Поэтому я начинаю смотреть на вызовы AddElem в теле программы. И что я вижу?
          1. Переменной znach ничего нигде не присваивается - значит в стек при вызове AddElem(stk, znach) будет заноситься какой-то "мусор".
          2. Вместо заполнения данных для стека ты заполняешь какой-то "левый" массив. Как я понимаю в стек должны заноситься и затем распечатываться все поля описанные в типе TList, а не только одно поле Data.
          Сообщение отредактировано: Федосеев Павел -
            Цитата Федосеев Павел @
            m-misha-m,
            смотри - я сократил твою программу до тестового примера - оставил неизменными процедуры и основную программу переделал под тест этих процедур
            ExpandedWrap disabled
              program tak;
               
              uses
                crt;
               
              const
                n = 4;
              type
                Tinf = integer;
                List = ^TList;
               
                TList = record
                  Data:  TInf;
                  Next:  List;
                end;
               
                procedure AddElem(var stek1: List; znach1: TInf);
                var
                  tmp: List;
                begin
                  GetMem(tmp, sizeof(TList));
                  tmp^.Next := stek1;
                  tmp^.Data := znach1;
                  stek1     := tmp;
                end;
               
                procedure Line(m: integer);
                var
                  i: integer;
                begin
                  for i := 1 to m do
                    Write('-');
                  WriteLn;
                end;
               
                procedure Print(stek1: List);
                begin
                  if stek1 = nil then {проверка на пустоту стека}
                  begin
                    WriteLn('Стек пуст.');
                    exit;
                  end;
                  while stek1 <> nil do {пока указатель stek1 не станет указывать в пустоту}
                  begin   {а это произойдёт как только он перейдёт по ссылке последнего элемента}
                    Write(stek1^.Data, ' '); {выводить данне}
                    stek1 := stek1^.Next;  {и переносить указатель вглубь по стеку}
                  end;
                end;
               
              var
                Stk: List;
                znach: Tinf;
              begin
                Stk := nil;
                for znach:=1 to 10 do
                  addelem(stk, znach);
                print(stk);
              end.

            Этот пример вполне работоспособен. К нему одно лишь замечание - он не освобождает память.
            Поэтому я начинаю смотреть на вызовы AddElem в теле программы. И что я вижу?
            1. Переменной znach ничего нигде не присваивается - значит в стек при вызове AddElem(stk, znach) будет заноситься какой-то "мусор".
            2. Вместо заполнения данных для стека ты заполняешь какой-то "левый" массив. Как я понимаю в стек должны заноситься и затем распечатываться все поля описанные в типе TList, а не только одно поле Data.

            подождите. я понял что вы сделали чортировку по убыванию. что мне остаеться делать основную программу под свою поменять?
              Причём здесь сортировка?

              Как я сказал выше, в тестовой программе я лишь показал работоспособность процедур print и AddElem. Для этого я в цикле for поместил в стек числа подряд от 1 до 10. А потом попросил print распечатать содержимое стека - естественно, были выведены числа в обратном (относительно помещения в стек) порядке, т.е. от 10 до 1.

              К чему это всё я говорю - не трогай AddElem. Прочти что я написал в предыдущем посте относительно znach.

              Делать за тебя я ничего не буду. Моя учёба в институте уже завершилась.
                Цитата Федосеев Павел @
                Причём здесь сортировка?

                Как я сказал выше, в тестовой программе я лишь показал работоспособность процедур print и AddElem. Для этого я в цикле for поместил в стек числа подряд от 1 до 10. А потом попросил print распечатать содержимое стека - естественно, были выведены числа в обратном (относительно помещения в стек) порядке, т.е. от 10 до 1.

                К чему это всё я говорю - не трогай AddElem. Прочти что я написал в предыдущем посте относительно znach.

                Делать за тебя я ничего не буду. Моя учёба в институте уже завершилась.

                спасибо что исправили процедуру, извините за мою тупость пожалуйста и за ваше время
                  Я ничего не исправил. Просто показал, что её не нужно исправлять.
                  Ошибка твоей программы в том, что НИ РАЗУ в теле программы переменной znach не присваивается значение, но мусорное содержимое этой переменной заносится в стек. Как следствие - ты не видишь после print на экране вводимых данных и пытаешься искать ошибку в другом месте.

                  Плюс ко всему данные ты сохраняешь в таблице tabl, а потом их неправильно используешь при выводе.

                  Разберись что такое стек.

                  Давай сделаем упрощённый пример со стеком. Шапку с описанием типов оставим от твоей программы, а изменим только основную программу. Признаком завершения ввода примем 0
                  ExpandedWrap disabled
                    begin
                      stk:=nil;
                      repeat
                        write('Input next elem: ');
                        readln(znach);
                        AddElem(stk, znach);
                      until znach=0;
                      Writeln('Stack:');
                      print(stk);
                    end.

                  Выполни этот тест. Всё корректно, не так ли?

                  Теперь давай усложним тип TInf и соответственно его ввод и вывод
                  ExpandedWrap disabled
                      TInf = record
                        a: integer;
                        b: string;
                      end;


                  ExpandedWrap disabled
                    program tak;
                     
                    type
                      TInf = record
                        a: integer;
                        b: string[10];
                      end;
                      List = ^TList;
                      TList = record
                        Data:  TInf;
                        Next:  List;
                      end;
                     
                      procedure AddElem(var stek1: List; znach1: TInf);
                      var
                        tmp: List;
                      begin
                        GetMem(tmp, sizeof(TList));
                        tmp^.Next := stek1;
                        tmp^.Data := znach1;
                        stek1     := tmp;
                      end;
                     
                      procedure Print(stek1: List);
                      begin
                        if stek1 = nil then {проверка на пустоту стека}
                        begin
                          WriteLn('Стек пуст.');
                          exit;
                        end;
                        while stek1 <> nil do {пока указатель stek1 не станет указывать в пустоту}
                        begin   {а это произойдёт как только он перейдёт по ссылке последнего элемента}
                          WriteLn(stek1^.Data.a, '-', stek1^.Data.b); {выводить данне}
                          stek1 := stek1^.Next;  {и переносить указатель вглубь по стеку}
                        end;
                      end;
                     
                    var
                      Stk: List;
                      znach: TInf;
                    begin
                      Stk := nil;
                      repeat
                        writeln('Input next elem: ');
                        write(' - a: ');
                        readln(znach.a);
                        write(' - b: ');
                        readln(znach.b);
                        AddElem(stk, znach);
                      until znach.a=0;
                      Writeln('Stack:');
                      print(stk);
                    end.


                  Обрати внимание, как определён тип стека TList, тип данных TInfo. Обрати внимание как вводятся данные в теле программы, как организован их вывод на экран.
                  Применительно к твоей ошибке - я заполняю значением переменную znach и только потом заталкиваю её в стек.
                    http://www.cyberforum.ru/turbo-pascal/thread77419.html
                    вот по этому я пытался сделать свою программу с данными о студентах

                    Добавлено
                    кстати спасибо за более простой пример, нам на лекции сразу дали немного сложный код )
                      На всех форумах есть свой FAQ с примерами. Здесь на сорцах в разделе паскаля тоже есть ([1], [2]. Кроме того много раз со многими учениками обсуждалось на форуме - пользуемся поиском.

                      Разбирайся, пробуй решить - получится. Что не понятно - задавай вопросы.

                      P.S. Ещё, могу посоветовать воспользоваться форматтером исходного кода. Если у тебя Lazarus - то там встроенное средство. Кажется, в Delphi тоже. Или можно воспользоваться сторонним средством - JediCodeFormat. Здесь на форуме в заготовках к FAQ я уже упоминал о нём (ссылка). Именно ним я форматнул твои исходники перед тем как начать их изучать.
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0504 ]   [ 15 queries used ]   [ Generated: 27.04.24, 23:52 GMT ]