Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

Struktury w C

Guru
-
-
Posty:250
Rejestracja:30 cze 2003, o 13:26
Lokalizacja:Kraków
Struktury w C

Postautor: Guru » 22 sie 2006, o 15:56

Mam kilka struktur w których jedne zawierają poprzednie czasem nawet kilka poziomów w głąb odwołanie wówczas wygląda mniej więcej tak

Kod: Zaznacz cały

wynik = struktura1.struktura2.struktura3.element_str3;
Natomiast chciałbym struktura kolejna zawierała elementy poprzedniej, a nie całą strukturę.
czyli odwołanie ma wyglądać mniej więcej tak:

Kod: Zaznacz cały

wynik = struktura1.element_str3;
Próbowałem komendy #define, czyli chciałem zdefiniować zbiór deklaracji danych, który będzie automatyczne umieszczany w strukturze w której sobie tego zażyczę, ale nie zadziałało jeżeli ktoś ma jakiś pomysł to bardzo proszę o sugestie.

Awatar użytkownika
bis
-
-
Posty:134
Rejestracja:12 maja 2005, o 08:11
Lokalizacja:Warszawa

Postautor: bis » 25 sie 2006, o 14:38

Uzywasz bardzo dziwnego złożenia pojęć "kolejne", "poprzednie" i "zawieranie". jedne sugerują relację <kolejności> (I chyba odnoszą się do sposobu zapisu) a inne chyba związane są z konstrukcją obiektów języka w postaci struktur <zawieranych> przez inne struktury. Tak na wprost to Twój cel jest nieosiągalny w języku "C". jakimś pomocniczym rozwiązaniem było by użycie unii które pozwajają na zastosownie różnych form opisu w odniesieniu do tego samego obszaru danych. Wtedy musiał byś zdefiniować te strukture raz jako składającą się wyłącznie z pól o typach bazowych, a w innym przypadku (cześć lub wszystkie) te pola poumieszczać w strukturach. I z tych opisów zrobic unię. Wtedy mógł byś stosować zarówno krótszy jak i dłuższy zapis dla dostępu do tego samego elementu unii. Oczywiście kryje się tu wiele pułapek związanych z alokacją pamięci i optymalizacją dostępu do pól unii charakterystycznych dla konkretnych kompilatorów i ich parametrów.
bis

Guru
-
-
Posty:250
Rejestracja:30 cze 2003, o 13:26
Lokalizacja:Kraków

Postautor: Guru » 25 sie 2006, o 16:49

Jeżeli chodzi tutaj o semantykę to jeżeli pierwszą strukturę deklaruje [shadow=red]tutaj[/shadow] a drugą [shadow=green]tutaj [/shadow] to ta druga tak czy inaczej będzie kolejna i tutaj brawo za wniosek dotyczą sposobu zapisu lub też kolejności zapisu i nie bardzo wiem co w tym jest dziwnego.
Masz rację mogłem zapisać to tak strA, strB itd. jednakże i tu zdradziła by mnie kolejność alfabetyczna. Więc sorry za mój szczególnie osobliwy sposób opisu problemu, jednakże nie mogłem się oprzeć systematyzacji przekazywanej przeze mnie wiadomości.
A jeżeli chodzi o składnię C to przemyślałem to na wszystkie sposoby i rzeczywiście nie da się tego zrobić. Chyba żeby jakaś ciekawa dyrektywa postprocesora załatwiła ten problem, ale w manualu do SDCC nie znalazłem takiej.
A jeżeli chodzi o unię to takie rozwiązanie nie wchodzi w rachubę.

Awatar użytkownika
bis
-
-
Posty:134
Rejestracja:12 maja 2005, o 08:11
Lokalizacja:Warszawa

Postautor: bis » 25 sie 2006, o 17:43

No to jednak język naturalny może oszukać, albo wybitnie zamazac ideę. Jeżeli napisałeś
wynik = struktura1.struktura2.struktura3.element_str3;
to nijak nie jest to "tutaj" i "tutaj". Z twojego zapisu struktura1 zawiera conajmniej strukturę2, a ta zawiera strukturę3 której jednym z elementów jest element_str3. Jeżeli będziesz deklarował strukturę1 to zamim skończysz tę deklarację (właśnie tej struktury1) wymienisz, jako pole strukturę2 (zawieranie). W ten sposób niema "tutaj" i "tutaj" (kolejność), ale jest "w tym tutaj jest inne tutaj" czyli zawieranie. kolejność występuje wyłącznie przy zapisie odwołania do pola wewnątrz tej skomplikowanej struktury.
Inaczej mówiąc trudno mówić o pierwszej i drugiej i następnych. Zwróciłem na to uwagę bo zły model problemu czesto prowadzi do błędnych wniosków, albo uniemożliwia skuteczne przedstawienie go innym.
bis

Guru
-
-
Posty:250
Rejestracja:30 cze 2003, o 13:26
Lokalizacja:Kraków

Postautor: Guru » 26 sie 2006, o 09:59

Użyłem w przypadku mojego objaśnienia problemu pewnego skrótu myślowego, dla pełniejszego wyjaśnienia problemu dodam, że struktura3 zawiera się w strukturze2 ale także w innych strukturach, dla dodatkowej komplikacji tego problemy także struktura1 zawiera się w innych strukturach, bezpośrednio lub też pośrednio przez strukturę2 jak to zobrazowałem w przykładach. Częstokroś w programie muszę używać bardzo długich odwołań. I tak struktura1 zadeklarowana jest tu, następnie struktura2 zadeklarowana jest tu i zawiera strukturę1 oraz inne deklaracje, Natomiast struktura3 zawiera strukturę2 i inne deklaracje. Z koleii struktura2 zawiera się jeszcze w innych 2 strukturach w powiązaniu ze zmiennymi, które występują tylko w tych nowych strukturach.
W strukturze kolejnej (nazwijmy ją struktura4) potrzebuję elementów struktury2 i struktury3, ale bez typów danych które zawiera struktura1.
Czyli jak widzisz w struktura4 muszę jeszcze raz deklarować zmienne, które zawiera struktura3 i struktura2 ale z pominięciem zmiennych, które zawiera struktura1.
I tu objawia się cały problem.
Dodatkowo sprawa się komplikuje, gdy chcę uniknąć tak długich odwołań jak w przykładzie.
Podsumowywując nie można uniknąć sformułowania poprzednia i kolejna, bo nawet gdyby to i tak struktura4 jest kolejna(lub następna), w stosunku do struktury3, której to struktury nie zawiera (typy danych które są podobne jak w strukturze3).
No niestety będziemy musieli jeszcze przez pewien czas używać języka naturalnego, zanim przejdziemy do komunikacji w następujący sposób:

Kod: Zaznacz cały

if(czlowiek.mowie_czesc) { if(znam_go(czlowiek)) mowie_czes(czlowiek2); }
NO to cześć :) :) :), a mam nadzieję że nigdzie nie zapomniałem średników, bo będzie faux pas.

Awatar użytkownika
bis
-
-
Posty:134
Rejestracja:12 maja 2005, o 08:11
Lokalizacja:Warszawa

Postautor: bis » 28 sie 2006, o 14:13

Z tym językiem to nie całkiem mnie zrozumiałeś. Konsekwentnie używałeś słowa deklaracja. Deklaracje są jedynie opisem struktur ale nie tworzą żadnych zmiennych w programie. Każda taka deklaracja jest osobnym opisem i z natury rzeczy nie może być mowy o tym aby kolejne deklaracje struktur posiadały jakiekolwiek wspólne pola a już całkiem nie da sie mówić o wspólnych zmiennych. Jeżeli jednak chodziło tobie o definicje zmiennych będących strukturami i chciał byś z poziomu różnych zmiennych strukturalnych docierac do tej samej zmiennej składowej to można to zrobić na conajmniej dwa sposoby. Jeden to ta wcześniej opisana unia (wtedy problem jest załatwiany na poziomie opisu, ale każda struktura logiczna ma "nieużywane" pola), albo zdefiniować tę wewnętrzną zmienną strukturalną osobno a w pozostałych strukturach "wyższego poziomu" stosować wskaźnik do niej (to wymaga jednak odpowiedniej inicjalizacji programowej pól wskaźnikowych, w niektórych kompilatorach jest możliwa "statyczna" w kodzie). Jeżeli do dostępu do pól struktur użył byś wskażników to można częściowo rozwiązać ten problem definiując typy strukturalne dla struktury3 i struktury4 w ten sposób aby na końcu deklaracji struktury3 położyć deklaracje struktury2(i zawartej w niej struktury1) a w strukturze4 tę część zadeklarować na początku. Wtedy można zbudować pomocniczą deklarację struktury wynikającej ze złożenia struktury3 i struktury4 tak aby najpierw były nieistotne pola struktury3, potem pole typu struktura2, potem inne pola struktury4. definiując zmienną o typie struktury pomocniczej, oraz stosując wskażniki do typu struktury3, struktury4, inicjalizując je odpowiednio stosując rzutowanie uzyskasz oczekiwany rezultat...Uff !!!.
Co do komplikacji zapisu, aby nie stosować wielokrotnie długaśnych zapisów to może warto rozpatrzyć "makra" za pomocą #define.
i w miejsce:

Kod: Zaznacz cały

wynik = struktura3.struktura2.struktura1.element_str1;
zastosować

Kod: Zaznacz cały

#define getWażnaWspólnaZmienna(strx) \ strx.struktura2.struktura1.element_str1 #define setWażnaWspólnaZmienna(strx, val) \ strx.struktura2.struktura1.element_str1=val // przykład użycia, skopiowanie z jednej zmiennej do innej wynik = getWażnaWspólnaZmienna(struktura3); setWażnaWspólnaZmienna(struktura4, wynik);
przy konsekwentnym zapisie nazw pól deklaracji typów strukturalnych to zadziała dla każdej definicji nadrzędnej a program zyska na czytelności. Jeżeli zależy tobie na "jednoczesnym" uaktualnieniu podobnych pól w różnych zmiennych strukturalnych to wystarczy odpowiednio rozbudować zapis dla "set..()". Proponuje zapis "funkcyjny" tych makr bo z praktyki wynika że jest najbardziej naturalny dla C.

bis

Guru
-
-
Posty:250
Rejestracja:30 cze 2003, o 13:26
Lokalizacja:Kraków

Postautor: Guru » 30 sie 2006, o 06:52

Z tym makrem to całkiem niezły pomysł. Natomiast idealną sprawą było by gdyby postprocesor zbiór deklaracji określony tutaj:

Kod: Zaznacz cały

{ char dekl; int dekl2; itd. }
automatycznie niejako włożył do

Kod: Zaznacz cały

struktura1
lub też

Kod: Zaznacz cały

struktura100
, wówczas po zmianie ilości lub też typów zmiennych w zbiorze określonym wyżej, postprocesor dokona automatycznej zmiany we wszystkich strukturach, które zawierają powyższy zbiór.
Wiem, że ktoś może powiedzieć, że zostają powielone deklaracje pewnych zmiennych, ale tak ma być !
W obecnej chwili muszę pamiętać o tym wszystkim. Na razie widzę dwa rozwiązania: długaśne zapisy dostępu w kodzie (alternatywnie jak to zaproponował bis stosowanie makr) lub też w przypadku zmiany zbioru deklaracji zmianę we wszystkich strukturach, które zawierają dany zbiór.

Awatar użytkownika
bis
-
-
Posty:134
Rejestracja:12 maja 2005, o 08:11
Lokalizacja:Warszawa

Postautor: bis » 30 sie 2006, o 09:00

To jest najprostsze do zrobienia poprzez deklarowanie własnych typów używając "typedef"\

Kod: Zaznacz cały

typedef struct { char cRoman; } lpr_t; typedef struct { char cAndrzej; } samo_t; typedef struct { lpr_t Seta; samo_t Galareta; } przystawki_t; typedef struct{ int iLechu; int iJarek; przystawki_t Przystawki; } rzad_t; typedef struct { char cMarek; przystawki_t Przystawki; } sejm_t;
mamy teraz zadeklarowane kilka typów zmiennych strukturalnych, czas na definicje tych zmiennych

Kod: Zaznacz cały

rzad_t Rzad; sejm_t Sejm;
teraz za kazdym razem gdy zmienisz skład np. lpr_t, samo_t czy w przystawki_t to automatycznie zmienisz zawartość pozostałych struktur "nadrzędnych" w skład których one wchodzą. Czyli zmienia się Rzad i Sejm.
Czy o to chodziło?
bis

Wróć do „PLD/FPGA i inne zagadnienia techniki cyfrowej”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 87 gości