Avoid *
在链表中有点麻烦,因为您必须单独管理它对链表本身的分配。我过去使用的一种方法是具有“可变大小”结构,例如:
typedef struct _tNode {
struct _tNode *prev;
struct _tNode *next;
int payloadType;
char payload[1]; // or use different type for alignment.
} tNode;
现在我意识到这看起来不是可变大小,但让我们分配一个结构:
typedef struct {
char Name[30];
char Addr[50];
} tPerson;
tNode *node = malloc (sizeof (tNode) - 1 + sizeof (tPerson));
现在,您有一个节点,从所有意图和目的来看,它看起来像这样:
typedef struct _tNode {
struct _tNode *prev;
struct _tNode *next;
int payloadType;
char Name[30];
char Addr[50];
} tNode;
或者,以图形形式(其中[n]
表示n
字节):
+----------------+
| prev[4] |
+----------------+
| next[4] |
+----------------+
| payloadType[4] |
+----------------+ +----------+
| payload[1] | <- overlap -> | Name[30] |
+----------------+ +----------+
| Addr[50] |
+----------+
也就是说,假设您知道如何正确处理有效负载。这可以按如下方式完成:
node->prev = NULL;
node->next = NULL;
node->payloadType = PLTYP_PERSON;
tPerson *person = &(node->payload); // cast for easy changes to payload.
strcpy (person->Name, "Bob Smith");
strcpy (person->Addr, "7 Station St");
该转换行只是将payload
字符的地址(在tNode
类型中)转换为实际tPerson
有效负载类型的地址。
使用这种方法,您可以在节点中携带任何您想要的有效负载类型,甚至每个节点中都可以携带不同的有效负载类型,而不会浪费联合的空间。这种浪费可以通过以下方式看到:
union {
int x;
char y[100];
} u;
每次在列表中存储整数类型时都会浪费 96 个字节(对于 4 字节整数)。
中的有效负载类型tNode
允许您轻松检测此节点承载的有效负载类型,因此您的代码可以决定如何处理它。您可以使用以下内容:
#define PAYLOAD_UNKNOWN 0
#define PAYLOAD_MANAGER 1
#define PAYLOAD_EMPLOYEE 2
#define PAYLOAD_CONTRACTOR 3
或(可能更好):
typedef enum {
PAYLOAD_UNKNOWN,
PAYLOAD_MANAGER,
PAYLOAD_EMPLOYEE,
PAYLOAD_CONTRACTOR
} tPayLoad;