Sanczo Napisano Listopad 28, 2005 Zgłoszenie Share Napisano Listopad 28, 2005 Witajcie! Chce stworzyć kolejkę w C, ale żeby była uniwersalna dla dowolnego typu danych jakie chce w niej przechowywać, tzn. raz mam ochotę przechować w niej węzeł taki: struct node { int pid; int ppid; char *name; char *cmdline; struct node* next; }; a raz taki: struct node { char *user; char *group; struct node* next; }; dla struct lista { int size; struct node *top; struct node *tail; }; Dodatkowo chce obie możliwości wykorzystać w jednym programie. Ogólnie chodzi o mniej złożoną implementację tego co jest w glibc czyli gqueue, na własną potrzebę. Jakieś sugestie? Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
m_zaleczny Napisano Listopad 28, 2005 Zgłoszenie Share Napisano Listopad 28, 2005 Moze tak: struct data1 { int pid; int ppid; char *name; char *cmdline; }; struct data2 { char *user; char *group; }; i teraz struct node { struct data1* d1; struct data2* d2; struct node* next; } dla struct lista { int size; struct node *top; struct node *tail; }; i jesli chcesz przechowywac pierwszy typ danych, to robisz xxx.d1 = new data1(); xxx.d2 = NULL; a jesli chcesz przechowywac drugi typ danych, to roibisz na odwrot: xxx.d1 = NULL; xxx.d2 = new data2(); Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Sanczo Napisano Listopad 28, 2005 Autor Zgłoszenie Share Napisano Listopad 28, 2005 struct node { struct data1* d1; struct data2* d2; struct node* next; } można prościej: typedef struct node { void *dane; struct node* next; } NODE; Z igły zrobiłem widły, problem nie był złożony Ale dziękuje za pomoc i pozdrawiam Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
m_zaleczny Napisano Listopad 30, 2005 Zgłoszenie Share Napisano Listopad 30, 2005 typedef struct node { void *dane; struct node* next; } NODE; W powyzszym przykladzie mozesz oczywiscie do pola dane przypisac zarowno wskaznik na pierwsza jak i na druga strukture, ale nie przechowujesz nigdzie informacji o tym jaki faktycznie wskaznik zostal utworzony. Dlatego w tym przypadku trzeba by jeszcze dodac dodatkowe pole typu, np. int typ; przyjmujacy wartosci: 0 - mamy wskaznik na pierwsza strukture, 1 - mamy wskaznik na druga strukture. Pozdrawiam, Marcin Załęczny Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Sanczo Napisano Listopad 30, 2005 Autor Zgłoszenie Share Napisano Listopad 30, 2005 m_zaleczny Pole dane jest wskaźnikiem do każdego typu danych, jednak jego przeznaczeniem jest wskazywanie na strukturę z danymi obecnego węzła. Natomiast next wskazuje na kolejny wezeł, wygląda to ok dla mnie i działa wyśmienicie. Dodawanie kolejnej zmiennej dla typu wydaje mi się zbedne, nie do końca rozumiem jego przeznaczenie bo całość jest czytelna pozdrawiam Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
!Ci Napisano Listopad 30, 2005 Zgłoszenie Share Napisano Listopad 30, 2005 przyjmujacy wartosci: 0 - mamy wskaznik na pierwsza strukture, 1 - mamy wskaznik na druga strukture. Chodzilo o to ze musisz sobie w strukturze dodac jeszcze jedna zmienna (flage) okreslajaca na jaki typ struktury wskazuje wskaznik czy na pierwszy czy na drugi. Ale tutaj mozna sie bez tego obejsc mozna by np. sprawdzac rozmiar wskazywanej struktury(sizeof) przez co okreslic na jaka wskazujemy... Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
m_zaleczny Napisano Grudzień 1, 2005 Zgłoszenie Share Napisano Grudzień 1, 2005 Tak jak pisze !Ci chodzilo mi wlasnie o taka dodatkowa flage pozwalajaca rozpoznac na jaka strukture faktycznie wskazuje wskaznik Otoz dla uproszczenia wyobrazmy sobie ponizsza tablice: stuct dane1; struct dane2; void *tab[4]; dane1 *d1; dane2 *d2; tab[0] = (void*)new dane1(); tab[1] = (void*)new dane2(); tab[2] = (void*)new dane1(); tab[3] = (void*)new dane2(); i teraz gdzies w kodzie chcemy przetworzyc wszystkie elementy tej tablicy: for (int i = 0; i < 4; i++) { // jesli nie mamy flagi okreslajacej typ danej w elemencie tab[i], to mamy problem... // tab[i] zawiera wskaznik nieokreslonego typu (void*) i nie wiemy czy rzutowac // na dane1 czy na dane2 }// for Nie wiem czy funkcja sizeof by pomogla, bo dla kazdego i sizeof zwroci 4: sizeof(tab) = 4, natomiast sizeof(*tab) powinno spowodowac bledy kompilacji. Ale moze sie myle a nie moge teraz tego sprawdzic. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
!Ci Napisano Grudzień 1, 2005 Zgłoszenie Share Napisano Grudzień 1, 2005 Nie wiem czy funkcja sizeof by pomogla, bo dla kazdego i sizeof zwroci 4: sizeof(tab) = 4, natomiast sizeof(*tab) powinno spowodowac bledy kompilacji. Hmmm nie jestem pewien czy wyrzuci bledy mysle ze nie powinien ale mozna to sprawdzic. To podalem czysto teoretycznie. Tylko juz dzisiaj tego nie zrobie czas nie pozwala... Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Sanczo Napisano Grudzień 1, 2005 Autor Zgłoszenie Share Napisano Grudzień 1, 2005 Dzięki ale taka zmienna/wskaźnik jest nie potrzebna. Sam nie mam kłopotów w połapaniu się w tym na jakim typie operuje w danej chwili, a jeśli ktoś będzie chciał zajżeć w kod, będą dla niego przygotowane komentarze oraz mam nadzieje wyczerpująca dokumentacja pozdrawiam Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
!Ci Napisano Grudzień 2, 2005 Zgłoszenie Share Napisano Grudzień 2, 2005 Dzięki ale taka zmienna/wskaźnik jest nie potrzebna. Sam nie mam kłopotów w połapaniu się w tym na jakim typie operuje w danej chwili, Tzn. jak to rozwiazales, bo chyba nie starasz sie zapamietac ktora nazwa zmiennej odpowiada danej strukturze. Jak w programie rozrozniasz te dwa typy danych?? Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Sanczo Napisano Grudzień 2, 2005 Autor Zgłoszenie Share Napisano Grudzień 2, 2005 !Ci Ok, po kolei: (pisze z głowy) 1. Potrzebuje 2 kolejki: - na użytkowników - na procesy int main() { LISTA *list_p=(LISTA*)malloc(sizeof(LISTA)); // dla procesów LISTA *list_u=(LISTA*)malloc(sizeof(LISTA)); // dla user'ów . . . } 2. Gdy do którejś listy chce dodać odpowiedni węzeł: mam funkcje: //ogólna void dodaj(LISTA *list,void *(*add)(void)) { NODE *n=(NODE*)malloc(sizeof(NODE)); n->data=add(); n->next=NULL; if(list->head==NULL) list->head=n; if(list->tail!=NULL) list->tail->next=n; list->tail=n; list->size++; } //dla N_USER N_USER* dodaj_u(void) { N_USER *n=(N_USER*)malloc(sizeof(N_USER)); n->user_name=NULL; n->term_type=NULL; n->type_log=0; return n; } //dla N_PROC N_PROC* dodaj_p(void) { N_PROC *n=(N_PROC*)malloc(sizeof(N_PROC)); n->pid=0; n->ppid=0; n->cmdline=NULL; n->name=NULL; n->uid=0; n->gid=0; n->state=NULL; n->dfn=0; return n; } Kolejka ta ma zastosowanie tylko w tym programie (takie jest założenie) więc dobrze by nie zawierała niepotrzebnych składowych Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
!Ci Napisano Grudzień 2, 2005 Zgłoszenie Share Napisano Grudzień 2, 2005 Ok ok... Rozumiem tylko ja caly czas zakladalem ze uzywasz tylko jednej kolejki do ktorej wrzucasz zarowno jeden jak i drugi typ struktury . Dlatego pisalem o dodatkowej fladze wtedy byloby takie rozwiazanie lub podobne potrzebne, aby podczas wykonywania jakis dzialan na elementach kolejki wiedziec jaki typ aktualnie "obrabiamy".... Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
m_zaleczny Napisano Grudzień 4, 2005 Zgłoszenie Share Napisano Grudzień 4, 2005 Właśnie sprawdziłem działanie sizeof. Otóż tak jak pisałem wcześniej kompilator nie przepuści instrukcji sizeof(*v), gdzie v jest typu void*. A oto przykladowy kod demonstrujący: #include <iostream> using namespace std; struct dane1 { int id; string nazwa; }; struct dane2 { int id; string nazwa; float dl; }; int main() { void *v1 = new dane1; void *v2 = new dane2; dane1 *d1 = new dane1; dane2 *d2 = new dane2; cout << "sizeof(dane1): " << sizeof(dane1) << endl; cout << "sizeof(dane2): " << sizeof(dane2) << endl; cout << "sizeof(v1): " << sizeof(v1) << endl; cout << "sizeof(v2): " << sizeof(v2) << endl; cout << "sizeof(d1): " << sizeof(d1) << endl; cout << "sizeof(d2): " << sizeof(d2) << endl; cout << "sizeof(*v1): " << sizeof(*(dane1*)v1) << endl; cout << "sizeof(*v2): " << sizeof(*(dane2*)v2) << endl; cout << "sizeof(*d1): " << sizeof(*d1) << endl; cout << "sizeof(*d2): " << sizeof(*d2) << endl; delete (dane1*)v1; delete (dane1*)v2; delete d1; delete d2; return 0; } po zamianie linijek cout << "sizeof(*v1): " << sizeof(*(dane1*)v1) << endl; cout << "sizeof(*v2): " << sizeof(*(dane2*)v2) << endl; na cout << "sizeof(*v1): " << sizeof(*v1) << endl; cout << "sizeof(*v2): " << sizeof(*v2) << endl; dostaniemy błędy kompilacji. Zatem sizeof nie przyda nam się do rozpoznawania typu wskazywanego obiektu. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
!Ci Napisano Grudzień 5, 2005 Zgłoszenie Share Napisano Grudzień 5, 2005 Czyli chcac wpisac wszystkie elementy do jednej kolejki potrzebna nam pewnie bedzie dodatkowa zmienna... no chyba ze ktos ma jeszcze jakis pomysl ?? Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Sanczo Napisano Grudzień 5, 2005 Autor Zgłoszenie Share Napisano Grudzień 5, 2005 m_zaleczny sizeof(*v), gdzie v jest typu void* Czy przypadkiem nie sprawdzasz tutaj rozmiaru adresu Bez rzutowania się nie obejdzie, na każdym kroku musisz dawać rzutowanie na odpowiedni typ np. (dane1*)->id... !Ci Chyba dodanie zmiennej to najlepsze co można zrobić... Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się