Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Free Pascal, Pascal ABC и другие _ Взаимодействие модулей

Автор: comanche 29.03.2006 18:00

Имеются два модуля, в первом описан тип record и массив соответствующих записей. Во втором модуле- процедура, которая сортирует этот массив.

Чтобы использовать в первом модуле процедуру второго, нужно чтобы в процедуре имелся параметр-переменная массива записей из первого модуля. Верно?

Так вот, как я могу описать тип этого параметра во втором модуле? Если модуль использует другой модуль, возникает ошибка: "Cyclic uses list in interface part of unit Students", а так, второй модуль не знает что в первом модуле есть такой тип записей.

Автор: volvo 29.03.2006 18:05

Цитата
Если модуль использует другой модуль, возникает ошибка: "Cyclic uses list in interface part of unit Students"
Не совсем... Только, если оба модуля подключают друг друга директивой Uses в разделе Interface !!! Если хотя бы один модуль подключает другой в секции Implementation, то Cyclic Reference разрешается компилятором. Но в любом случае - присоедини сюда ОБА модуля.

Автор: comanche 29.03.2006 18:19

Заголовки в разделе int/imp не совпадают т.к. паскаль TMT, не расчитываю сюда код кидать.

Частичка первого модуля с описанным типом:

Код
Unit Students;

                                               Interface
Uses
  CRT;

Type

  TStudent = record
        Name: String[20];
    AverMark: Single;
     Address: String[20];
       Group: String[5];
  end;

  TStudents = Array [1..10] OF TStudent;

  TRecords = object
  private
    Records: TStudents;
    Size: Byte;
  end;
                                            Implementation

  // zdes xo4u ispolzovat' proceduru sortirovki, naprimer
Begin
    SearchByName(Records);
End.


Частичка модуля с процедурой:

Код
Unit SortSear;

Interface

  Uses
    CRT, Students;

Type

  TSortSear = object
    Procedure SearchByName(var RecordsToSort: TStudents);

  end;

Implementation

  Procedure TSortSear.SearchByName;
    var
      Name: String[20];
      i: Byte;
      SearchResult: Boolean;
      SearchCounter: Byte;
    begin
      SearchResult := False;
      SearchCounter := 0;
      TextColor(Black);
      For i := 4 To 6 Do
        begin
          GotoXy(1, i);
          ClrEOL;
        end;
      GotoXy(1, 4);
      WriteLn('þ Search by Name/Surname:');
      Name := ReadName(WhereX+1, WhereY+1, 20);
      TextColor(Black);
      Write('ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');
      For i := 1 To Size Do
        if Pos(UpperCase(Name), UpperCase(Records[i].Name)) > 0 Then
           begin
             inc(SearchCounter);
             SearchResult := True;
      {#}    Write(SearchCounter:3, ')');      {#}
      {#}    Write(Records[i].Name:21);        {#}
      {#}    Write(Records[i].Group:11);       {#}
      {#}    Write(Records[i].AverMark:11:1);  {#}
      {#}    WriteLn(Records[i].Address:25);
           end;
        if NOT SearchResult Then
          begin
            TextColor(Red);
            WriteLn('þ No results found!');
            TextColor(Black);
            Write('þ Press any key to continue...');
          end;
    ReadKey;
    end;

End.

Автор: volvo 29.03.2006 18:23

Ну, так я же написал, что делать:

Unit Students;
Interface
Uses
CRT;

Type

TStudent = record
Name: String[20];
AverMark: Single;
Address: String[20];
Group: String[5];
end;

TStudents = Array [1..10] OF TStudent;

TRecords = object
private
Records: TStudents;
Size: Byte;
end;

Implementation
// ИМЕННО в Inplementation !!!

Uses SortSear; // Описание процедуры сортировки уже доступно, и все по правилам...

Begin
SearchByName(Records);
End.

Автор: comanche 29.03.2006 18:36

Поместил один модуль в implementation другого и второй наоборот.

Идеально! Спасибо good.gif

Косяк в другом:

У процедуры
Procedure SearchByName(var RecordsToSearch: TStudents) имеется параметр-переменная.

И когда я её использую в первом модуле, она запускается без параметра

TSortSear.SearchByName;

Почему она не нуждается в переменной типа TStudents?
....
Students: TStudents;
....
TSortSear.SearchByName(Students);
....


? blink.gif

Автор: volvo 29.03.2006 20:19

Цитата
Почему она не нуждается в переменной типа TStudents?
Ну, это, наверное, у тебя спросить надо smile.gif ... Я, например, тоже не вижу, где в TSortSear.SearchByName используется TStudents...

Автор: comanche 29.03.2006 20:48

Но ведь в у SearchByName есть параметр-массив.
Тобишь он должен его получать.
А он без него запускает blink.gif

Автор: comanche 29.03.2006 21:04

Код
Unit SortSear;

Interface

  Uses
    CRT, Students, Strings;

Type

  TSortSear = object
  private
    RP: ^TRecords;
  public
    Constructor Init(var RecordsPointer: ^TRecords);
     Destructor Done;
      Procedure SearchByName(var RecordsToSearch: TStudents);

  end;

Implementation

  Constructor TSortSear.Init;
    begin
      RP := RecordsPointer;
    end;

  Destructor TSortSear.Done;
    begin
    end;

  Procedure TSortSear.SearchByName;
    var
      Name: String[20];
      i: Byte;
      SearchResult: Boolean;
      SearchCounter: Byte;
    begin
      SearchResult := False;
      SearchCounter := 0;
      TextColor(Black);
      For i := 4 To 6 Do
        begin
          GotoXy(1, i);
          ClrEOL;
        end;
      GotoXy(1, 4);
      WriteLn('þ Search by Name/Surname:');
      Name := RP^.ReadName(WhereX+1, WhereY+1, 20);
      TextColor(Black);
      Write('ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');
      For i := 1 To RP^.GetSize Do
        if Pos(UpperCase(Name), UpperCase(RecordsToSearch[i].Name)) > 0 Then
           begin
             inc(SearchCounter);
             SearchResult := True;
      {#}    Write(SearchCounter:3, ')');              {#}
      {#}    Write(RecordsToSearch[i].Name:21);        {#}
      {#}    Write(RecordsToSearch[i].Group:11);       {#}
      {#}    Write(RecordsToSearch[i].AverMark:11:1);  {#}
      {#}    WriteLn(RecordsToSearch[i].Address:25);
           end;
        if NOT SearchResult Then
          begin
            TextColor(Red);
            WriteLn('þ No results found!');
            TextColor(Black);
            Write('þ Press any key to continue...');
          end;
    ReadKey;
    end;

End.

Автор: volvo 29.03.2006 21:10

Ты ПРОГРАММУ полностью ПРИАТТАЧИТЬ (в архиве) можешь? Почему нужно, чтобы мы переписывали бОльшую часть программы заново, объясни мне? Это уже НЕ ТВОЯ программа получается. И у меня она работать не будет, а у тебя вдруг заработает!

Кстати, если у тебя вопрос связан с конкретным компилятором (а у тебя - связан, ибо TMT...) то создавай темы в соответствующем разделе. Хватит уже нарушать Правила.

Автор: comanche 29.03.2006 21:14

Учту wink.gif


Прикрепленные файлы
Прикрепленный файл  Ex_8_Forum.rar ( 31.43 килобайт ) Кол-во скачиваний: 241

Автор: volvo 29.03.2006 21:29

Ну, начнем с того, что твой проект у меня в TMT 3.90 просто не компилируется. Выдает ошибку в типе (тип нельзя конструировать прямо в заголовке процедуры/метода, нужно описывать его заранее) в файле sortsear.pas:

    Constructor Init(var RecordsPointer: ^TRecords);    


Кроме того, в файле GraphOps.pas (строка 297) - " ожидается ')' "

А ты говоришь, все работает? Не работает пока что...

Автор: comanche 29.03.2006 21:34

Странно, мой нормально компайлит. Там есть описанный тип PTRecords, можно использовать и его.

GraphOps.pas, строки 296, 297, 298:

Код
11: begin // DELETE DATABASE;
          TFileOps.DeleteDatabase;
      end;


меняем на

Код
11: begin // DELETE DATABASE;
      end;


Должно запуститься yes2.gif

Кстати! Здесь
Код
11: begin // DELETE DATABASE;
          TFileOps.DeleteDatabase;
      end;

та же фигня, метод DeleteDatabase описан с параметром, а при его использовании, параметр не нужен.

Автор: volvo 29.03.2006 22:35

Так... А вот теперь - вопрос на засыпку:
ГДЕ у тебя описана переменная Database, с которой ты пытался вызвать

TFileOps.DeleteDatabase(Database);
? Компилятор - то про нее НИЧЕГО НЕ СЛЫШАЛ!!!

Автор: comanche 29.03.2006 22:41

Была описана в модуле mainops как глобальная, строка №25.

Автор: volvo 29.03.2006 22:43

Хы... Правда? А ты что, в GraphOps где-то MainOps подключаешь? Тогда покажи, где!

Автор: comanche 29.03.2006 22:47

Допустим, я подключил MainOps в impementation GraphOps'ов, но проблема в том что процедура DeleteDatabase вообще не требует параметра, а он нужен для нормальной её работы dry.gif

Автор: volvo 29.03.2006 22:57

Знаешь, что я тебе скажу? После 10-минутного переключения между окнами в поисках описаний типов, оформленных в одном месте через описания, сделанные в других файлах, я могу посоветовать тебе только одно: переделывай программу (ВООБЩЕ С НУЛЯ!) или бросай программирование.

Больше ничего сказать не могу. Мне терпения открывать 10 раз один и тот же файл для того, чтобы добраться до корня описания типа или переменной просто не хватает. Также его не хватит тому, кто попытается поддерживать твои программы (если они будут писаться в таком ключе и дальше). Тогда СМЫСЛ их писать?

Автор: comanche 29.03.2006 23:06

Надо будет попробовать написать заного.

Всё равно спасибо good.gif

Автор: hardcase 30.03.2006 0:44

Вот тебе совет: объявляй типы в отдельном модуле. и назови его чемнить вроде MyTypes. А всё остальное будет ссылаться на него.