struktúrára mutató pointer átadása cím szerint / ANSI C

Fórumok

Légyszi segítsen valaki, ha van egy struktúrám:


struct queue_raw{
        int ui_element;
        struct queue_raw *next;
};

typedef struct queue_raw queue_;

egy függvény ami a listába egy elemet betenne:


put_queue(queue_ **q,int x){
        if (*q){
                printf ("nem ures\n");

        }else{
                printf ("ures\n");
//                *q=malloc(sizeof(queue_));
//                *q->ui_element=x;
        }
        if (*q){
                printf ("nem ures\n");
        }

}

egy main rész:


int
main(void){
        queue_ *q = NULL;


        put_queue(&q,1);
        if (q){
                printf ("nem ures\n");

        }else{
                printf ("ures\n");
        }

}

akkor hogyan tudok a main részben úgy deklarálni egy mutatót amit aztán cím szerint tudok átadni a függvénynek és amikor visszatér a vezérlés a main következő sorához akkor tényleg benne legyen a sorban az elem?
a láncolást egyelőre nem csináltam meg most nem is az a lényeg, hanem az, hogy ha a mainban megcsinálom a q változót így:


queue_ *g = NULL;

akkor ezt cím szerint így tudom átadni a függvényemnek?


   put_queue(&q,1);

A függvényfejnek meg így kell kinéznie?


   put_queue(queue_ **q,int x)

Ha ez jó, akkor hogyan látok bele a struktúrába? csak mert ahogyan próbáltam az nem jó:


   *q=malloc(sizeof(queue_));
   *q->ui_element=x;

Hozzászólások

Maga't a put_queue() fv-t teljesen felesleges egy plusz indirekcioval definialnod, eleg igy:


put_queue(queue_ *q,int x){
        if (q){
                printf ("nem ures\n");

        }else{
                printf ("ures\n");
//                q=malloc(sizeof(queue_));
//                q->ui_element=x;
        }
        if (q){
                printf ("nem ures\n");
        }

}

akkor van/lenne ertelme annak, hogyha *q = ... ertekadas is van! a q-> ertekadas az mar eleve egyszeresen indirekt, tehat valoban ha csinalsz egy


queue *q;
q=malloc(sizeof(queue));
put_queue(q,137);

hivast, akkor ez ugyanugy feltolti a q objektumot, de statikusan is lehet csinalni:


queue q;
put_queue(&q,137);

a lenyeg ugyanaz.

Es pont emiatt a main()-edben levo" ize is nagyon felreertheto", hasznald valamelyik megoldast a fenti ketto" kozul. Szerintem legalabbis.

szerk: bocs, a kikommentezett reszt ignoraltam, ott van *q ertekadas. ettol fuggetlenul nezd meg, hogy a te problemadra nem-e egyszerubb egy indirekcioval kevesebb, akkor azert konnyebben atlathato' a dolog.

A.

Az a baj, hogy ha úgy csinálom ahogy mondtad és a mainban:
queue_ q;
put_queue(&q,1);
akkor a függvény amikor megkapja akkor nem lesz üres a lista, hiszen a q-ban van valami szemét és nem NULL az értéke

ha:
queue_ *q;
q=malloc....
put_queue(q,1)

akkor pedig a függvény nem cím szerint veszi át a mainból a q-t, vagyis ha visszatérek a main-ba ott a q lista üres.

A teljes problemara (elore-hatra lancolt lista) en a kovetkezo"t szoktam csinalni:

van egy struct, ami igy vagyon definialva:


typedef struct  child   child;

struct child
 {      child           *prev,*next;    /* list chain pointers               */
        int             id;             /* internal child identifier         */
        int             pid;            /* PID of the child                  */
        remoteshell     *rs;            /* remote shell pointer              */
        int             fdstdout;       /* standard output pipe if collected */
        linebuffer      lout;           /* stdout line buffer if reformatted */
        int             fdstderr;       /* standard error pipe, if collected */
        linebuffer      lerr;           /* stderr line buffer if reformatted */
 };

(a lenyeg a *prev meg a *next)

illetve van ez a ke't makro':


#define         list_insert_first(firstpointer,object) \
 do \
  {     (object)->next=(firstpointer); \
        (object)->prev=NULL; \
        if ( (firstpointer) != NULL )   (firstpointer)->prev=(object); \
        firstpointer=(object); \
  } while ( 0 )

#define         list_remove(firstpointer,object) \
 do \
  {     if ( (object)->next != NULL )   (object)->next->prev=(object)->prev; \
        if ( (object)->prev != NULL )   (object)->prev->next=(object)->next; \
        else                            firstpointer=(object)->next; \
  } while ( 0 )

Ekkor a lista maga egyetlen


...
 child                  *childlist=NULL;
...

ertekadassal inicializalhato', majd uj elem beszurasa:


 child   *cc;
 cc=(child *)malloc(sizeof(child));
 list_insert_first(childlist,cc);
 cc->... = ... ;  /* a lenyeg feltoltese */

illetve egy elem torolheto":


...
list_remove(childlist,cc);
free(cc);
...

Az elso" makro a lista elejere szurja be az elemet, igy ez ordo(1) ido" alatt megvan, illetve a torles is, ertelemszeruen ennyi ido".

A fo gondolat az egesz problemaban az, hogy annak ellener hogy 1/ csak a lista elejere szursz be elemeket 2/ csak elorefele akarsz vegigrohanni a listan; ennek ellenere hogy a torles meg a beszuras is ordo(1) ido alatt lemenjen, kell a hatrafele lancolas is (*prev).

A.

a -> operator precedenciaja magasabb, mint a dereference-e...


(*q)->ui_element=x

wooo!! te egy zseni vagy! szeretlek :-)


#include <stdio.h>
#include <stdlib.h>

struct queue_raw{
        int ui_element;
        struct queue_raw *next;
};

typedef struct queue_raw queue;

put_queue(queue** q,int x){
        queue *temp;
        if (*q) {
                printf("nem ures\n");
                temp = malloc(sizeof(queue));
                temp->ui_element = x;
                temp->next = (*q);
                (*q) = temp;

        }else{
                printf("ures\n");
                (*q)=malloc(sizeof(queue));
                (*q)->ui_element = x;
                (*q)->next = NULL;

        }
}

int
main(void){
        queue *q=NULL;

        put_queue(&q,100);
        put_queue(&q,101);
        while (q) {
                printf("%d\n",q->ui_element);
                q = q->next;
        }
}

./pointer
ures
nem ures
101
100