用C实现通用列表

 

#include <stdio.h>

 

typedef void *QUEUE[2];

 

/* Private macros. */

#define QUEUE_NEXT(q)       (*(QUEUE **) &((*(q))[0]))

#define QUEUE_PREV(q)       (*(QUEUE **) &((*(q))[1]))

 

#define QUEUE_PREV_NEXT(q)  (QUEUE_NEXT(QUEUE_PREV(q)))

#define QUEUE_NEXT_PREV(q)  (QUEUE_PREV(QUEUE_NEXT(q)))

 

/* Public macros. */

#define QUEUE_DATA(ptr, type, field)                                          \

  ((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field)))

 

#define QUEUE_FOREACH(q, h)                                                   \

  for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))

 

#define QUEUE_EMPTY(q)                                                        \

  ((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q))

 

#define QUEUE_HEAD(q)                                                         \

  (QUEUE_NEXT(q))

 

#define QUEUE_INIT(q)                                                         \

  do {                                                                        \

    QUEUE_NEXT(q) = (q);                                                      \

    QUEUE_PREV(q) = (q);                                                      \

  }                                                                           \

  while (0)

 

#define QUEUE_ADD(h, n)                                                       \

  do {                                                                        \

    QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n);                                       \

    QUEUE_NEXT_PREV(n) = QUEUE_PREV(h);                                       \

    QUEUE_PREV(h) = QUEUE_PREV(n);                                            \

    QUEUE_PREV_NEXT(h) = (h);                                                 \

  }                                                                           \

  while (0)

 

#define QUEUE_SPLIT(h, q, n)                                                  \

  do {                                                                        \

    QUEUE_PREV(n) = QUEUE_PREV(h);                                            \

    QUEUE_PREV_NEXT(n) = (n);                                                 \

    QUEUE_NEXT(n) = (q);                                                      \

    QUEUE_PREV(h) = QUEUE_PREV(q);                                            \

    QUEUE_PREV_NEXT(h) = (h);                                                 \

    QUEUE_PREV(q) = (n);                                                      \

  }                                                                           \

  while (0)

 

#define QUEUE_INSERT_HEAD(h, q)                                               \

  do {                                                                        \

    QUEUE_NEXT(q) = QUEUE_NEXT(h);                                            \

    QUEUE_PREV(q) = (h);                                                      \

    QUEUE_NEXT_PREV(q) = (q);                                                 \

    QUEUE_NEXT(h) = (q);                                                      \

  }                                                                           \

  while (0)

 

#define QUEUE_INSERT_TAIL(h, q)                                               \

  do {                                                                        \

    QUEUE_NEXT(q) = (h);                                                      \

    QUEUE_PREV(q) = QUEUE_PREV(h);                                            \

    QUEUE_PREV_NEXT(q) = (q);                                                 \

    QUEUE_PREV(h) = (q);                                                      \

  }                                                                           \

  while (0)

 

#define QUEUE_REMOVE(q)                                                       \

  do {                                                                        \

    QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q);                                       \

    QUEUE_NEXT_PREV(q) = QUEUE_PREV(q);                                       \

  }                                                                           \

  while (0)

 

 

/**

* A pointer to a list node.

*/

static QUEUE* q;

 

/**

* Our circulary list.

*/

static QUEUE queue;

 

/**

* Our item struct we want to store in queue.

*/

struct user_s {

    int age;

    char* name;

 

    QUEUE node;

};

 

int main() {

    /**

    * This will be our user pointer.

    * It will point to the user we received from the queue.

    */

    struct user_s* user;

 

    /**

    * John is 44.

    */

    struct user_s john;

    john.name = "john";

    john.age = 44;

 

 

    /**

    * Henry is 32.

    */

    struct user_s henry;

    henry.name = "henry";

    henry.age = 32;

 

    /**

    * Willy is 99.

    */

    struct user_s willy;

    willy.name = "willy";

    willy.age = 99;

 

    /**

    * Initialize the queue of each user.

    */

    QUEUE_INIT(&queue);

    QUEUE_INIT(&john.node);

    QUEUE_INIT(&henry.node);

    QUEUE_INIT(&willy.node);

 

 

    /* hgb, why need this line ?

    ((*(&queue))[0]) = john.node;

    */

   

    printf(" sizeof(QUEUE)=%d \n", (int)(sizeof(QUEUE)) );

 

    (*(QUEUE **) &((*(&queue))[0])) = &john.node;

    /**

    * Lets insert each user to the tail of the list.

    */

    QUEUE_INSERT_TAIL(&queue, &john.node);

    QUEUE_INSERT_TAIL(&queue, &henry.node);

    QUEUE_INSERT_TAIL(&queue, &willy.node);

 

    /**

    * Retrieve a pointer to our first user john.

    */

    q = QUEUE_HEAD(&queue);

    printf("&queue=%p, queue[0]=%p, &q=%p \n", &queue, queue[0], q);

    //q = ((*(&queue))[0]) ;

    /**

    * Should retrieve the user behind the "q" pointer.

    */

    user = QUEUE_DATA(q, struct user_s, node);

 

    /**

    * Should output the name of john.

    */

    printf("Received first inserted user: %s who is %d.\n",

        user->name, user->age);

 

    /**

    * Now lets remove john from the queue.

    */

    QUEUE_REMOVE(q);

   

    printf("&queue=%p, queue[0]=%p \n", &queue, queue[0] );

 

    /**

    * Lets output the other two users through a for each loop.

    */

    QUEUE_FOREACH(q, &queue) {

       printf(" &q = %p, ", q);

        user = QUEUE_DATA(q, struct user_s, node);

 

        printf("Received rest inserted users: %s who is %d.\n",

            user->name, user->age);

    }

 

    return 0;

}

posted @ 2017-01-09 22:59  Andy.gbhu  阅读(326)  评论(0)    收藏  举报