Wątek przeniesiony 2014-01-21 16:02 z C/C++ przez ŁF.

Listy jednokierunkowe w programie C

0

Witam.
Piszę projekt na zaliczenia w czystym C. Program analizuje kod Pascala i zapisuje go do pliku. Mam za sobą już całą prace na tekście teraz wyniki muszę zapisać do list. Czy może mi ktoś podpowiedzieć jak mądrze stworzyć listę jednokierunkową, która będzie przechowywać następujące dane:

Zmienne(nazwa i typ)
Stałe(nazwa)
Typy(nazwa i składowe)
Procedury(nazwa, lokalne zmienne, stałe i typy jak wyżej)
Funkcje(nazwa, typ, lokalne zmienne stałe i typy)

Poszczególne elementy różnią się ilością elementów składowych, a robienie pięciu list chyba nie jest tutaj najlepszym rozwiązaniem.
Proszę o pomoc i pozdrawiam :)

1

pięcioelementowa tablica list.

0

A jakie składowe list, bo np. stałe wymagają tylko zapamiętania nazwy a zmienne nazwy i typu.

1

Ja skorzystałbym tutaj z unii lub ew.po prostu struktury/rekordu zawierającej każde pole, będzie chyba najłatwiej (chociaż oczywiście nie najładniej :P).

0

Możesz mi pokazać jakiś schemat jakbyś to widział, sam o tym myślałem, ale to chyba dalej wiąże się z 5 listami, same listy MUSZĄ być, taki wymóg prowadzącej, potem muszę jeszcze elementy posortować alfabetycznie, ale z tym sobie już poradzę. Nie mam pomysłu na strukturę list.

0

Tak wyjdzie chyba najbanalniej (chociaż jak powiedziałem: nie najładniej):

Type TStructureType = (stVariable, stConstant, stType, stProcedure, stFunction);

Type TVariable =
Record
 Name: String;
 Typ: TType;
End;

Type TConstant =
Record
 Name: String;
End;

{ ... }

Type TStructure =
Record
 Typ: TStructureType;
 // tutaj ewentualnie można by zastosować unię, albo zostawić jak jest:
 sVariable: TVariable;
 sConstant: TConstant;
 sType: TType;
 sProcedure: TProcedure;
 sFunction: TFunction;
End;

Tylko jakoś to logiczniej ponazywaj, mi nic lepszego na myśl nie wpadło;

  • jak chcesz, możesz sobie przeanalizować ten plikczek z mojego kompilatora, tam jest trochę podobnie to zorganizowane (i działa! :P).
0
scrafter napisał(a)

Nie mam pomysłu na strukturę list.

Programujesz sobie uniwersalne funkcje operujące na wszystkich pięciu listach, a możesz to zrobić - wystarczy w każdym węźle listy przechowywać typ elementu (stała, zmienna, typ, procedura lub funkcja) oraz wskaźnik na strukturę danych o danym typie; Struktur z informacjami o danym elemencie deklarujesz sobie pięć - po jednej dla każdego typu; Do funkcji operującej na listach zamiast gołych danych podasz typ elementu i wskaźnik na strukturę informacji o tym elemencie;

Kodu w C nie podam, bo stronię od niego jak od trędowatych, ale swój pomysł mogę opisać kodem w Pascalu:

type
  // typ wyliczeniowy określający rodzaj elementu
  TElementKind = (kndConstant, kndVariable, kndType, kndProcedure, kndFunction);
 
type
  // typ struktury z informacjami o typie danych
  PTypeInfo = ^TTypeInfo;
  TTypeInfo = record
    Name: AnsiString;                // nazwa typu
    Components: array of AnsiString; // składowe typu
  end;

  // typ struktury z informacjami o stałej
  PConstInfo = ^TConstInfo;
  TConstInfo = record
    Name: AnsiString;  // nazwa stałej
  end;

  // typ struktury z informacjami o zmiennej
  PVarInfo = ^TVarInfo;
  TVarInfo = record
    Name: AnsiString;     // nazwa zmiennej
    DataType: PTypeInfo;  // typ danych zmiennej
  end;
 
  // typ struktury z informacjami o procedurze
  PPropInfo = ^TProcInfo;
  TProcInfo = record
    Name: AnsiString;                 // nazwa procedury
    LocalConst: array of PConstInfo;  // lokalne stałe
    LocalVar: array of PVarInfo;      // lokalne zmienne
    LocalTypes: array of PTypeInfo;   // lokalne typy
  end;
 
  // typ struktury z informacjami o funkcji
  PFuncInfo = ^TFuncInfo;
  TFuncInfo = record
    Name: AnsiString;                 // nazwa funkcji
    Return: PTypeInfo;                // typ danych rezultatu
    LocalConst: array of PConstInfo;  // lokalne stałe
    LocalVar: array of PVarInfo;      // lokalne zmienne
    LocalTypes: array of PTypeInfo;   // lokalne typy
  end;
 
type
  // struktura z informacjami pojedynczego węzła
  PNode = ^TNode;
  TNode = record
    Kind: TElementKind;  // rodzaj elementu
    Name: PAnsiChar;     // wskaźnik na nazwę elementu w strukturze z informacjami
    Info: Pointer;       // wskaźnik na strukturę z informacjami
    Next: PNode;         // wskaźnik na kolejny węzeł listy
  end;

To jest tylko zarys (kompilujący się) powiązania struktur z informacjami o pięciu elementach kodu Pascala; Kwiatuszkiem jest pole TNode.Name w strukturze węzła listy - podczas dodawania nowego węzła do listy trzeba by było przekazać utworzoną w pamięci strukturę z informacjami o danym elemencie, np. typu TVarInfo, a jako drugi parametr przekazać wskaźnik na pole TVarInfo.Name, aby wpisać go do pola Name w strukturze TNode;

Dzięki takiemu rozmieszczeniu struktur i ich powiązaniu można napisać uniwersalne funkcje do dodawania nowych węzłów do listy, a także dzięki zastosowaniu wskaźnika na nazwę dodawanego elementu będzie można także napisać uniwersalną funkcję sortującą listę, dlatego że bez względu na typ struktury zawartej w polu TNode.Info, w polu TNode.Name zawsze będzie wskaźnik na nazwę danego elementu;

Tak przynajmniej ja bym kombinował, choć podany wyżej przykład opracowany na szybko w głowie;

PS. Nie wiem co rozumiesz przez "składowe typu", dlatego nie wiedziałem jaki typ dla nich wybrać, stąd też pole TTypeInfo.Components jest macierzą łańcuchów, ale był to strzał.

1 użytkowników online, w tym zalogowanych: 0, gości: 1