你写这个的方式有很多问题
void dateTimeNode_insert(tDateTimeNode **_list)
{
bool found = false;
tDateTimeNode *list = (*_list);
while (list != NULL && !found)
{
printf("This code never runs!\n");
list = list->next;
}
if (list == NULL)
{
printf("This if is always executed!\n");
list = (tDateTimeNode *)malloc(sizeof(tDateTimeNode));
}
if (*_list == NULL)
{
printf("This if is also executed!\n");
_list = &list;
}
}
请注意found 始终为假并且可以删除,因为!false 始终为真,永远不会改变
_list是tDateTimeNode**所以应该在*_list中带入列表头的地址
当你写作时
_list = &list;
对列表的唯一引用已经永远消失了。也许你打算写*_list = list;以便在插入第一个元素时保存列表的新头部
命名也很混乱:list、_list。
请注意,列表是一个容器。您不应将列表与数据混在一起。你今天的清单是DateTimeNode,但它仍然只是一个清单。在你的下一个程序中,可能是一本书,一首播放列表中的歌曲,所有经典的列表练习。如果代码更通用,则创建列表很简单。各种列表
示例:一个列表和一个DateTimeNode
我将使用您的代码发布一个示例,但使用我上面写的内容
想象一个控制队列的工单列表。每个进入的客户都会获得一张带有序列号和时间戳的票,格式为yyyy-mm-dd hh:mm:ss。客户在队列末尾进入。
这是一张可能的票
typedef struct
{
char* ts; // time stamp
unsigned USN; // sequence number
} Ticket;
可能的Node 获取这些票的列表
typedef struct _Node
{
Ticket* tk;
struct _Node* next;
} Node;
正如预期的那样,列表中的每个节点都指向一张票。列表只是一个容器。
列表本身可以是
typedef struct
{
Node* head; // first node if any
unsigned size; // actual Node count
} List;
这些方式更容易理解:列表有节点,每个节点指向一些数据。数据有编号,便于测试。并有时间戳。当然,计算机速度很快,时间戳分辨率是秒,所以我们需要数千个节点才能看到不同的时间戳......
最小的函数集
List* create();
List* destroy(List*);
int insert(Ticket*, List*);
int show(List*, const char*);
show() 接受消息的可选字符串,destroy() 返回 NULL 作为礼貌,因此我们可以在销毁列表的同一行中使列表指针无效。
一个测试
int main(void)
{
Ticket ticket;
List* one = create();
for (int i = 1; i <= 10; i += 1)
{
ticket.USN = i;
ticket.ts = get_ts();
insert(&ticket, one);
};
show(one, "After 10 tickets inserted...\n");
one = destroy(one); // destroys list, invalidate pointer
return 0;
}
代码创建一个包含 10 张票的列表,显示它们并删除该列表。
输出
After 10 tickets inserted...
List has 10 elements:
1 2021-11-15 14:12:06
2 2021-11-15 14:12:06
3 2021-11-15 14:12:06
4 2021-11-15 14:12:06
5 2021-11-15 14:12:06
6 2021-11-15 14:12:06
7 2021-11-15 14:12:06
8 2021-11-15 14:12:06
9 2021-11-15 14:12:06
10 2021-11-15 14:12:06
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct
{
char* ts; // time stamp
unsigned USN; // sequence number
} Ticket;
typedef struct _Node
{
Ticket* tk;
struct _Node* next;
} Node;
typedef struct
{
Node* head; // first node if any
unsigned size; // actual Node count
} List;
// List stuff
List* create();
List* destroy(List*);
int insert(Ticket*, List*);
int show(List*, const char*);
// helpers
char* get_ts(); // get time in format "yyyy-mm-dd hh:mm:ss"
int main(void)
{
Ticket ticket;
List* one = create();
for (int i = 1; i <= 10; i += 1)
{
ticket.USN = i;
ticket.ts = get_ts();
insert(&ticket, one);
};
show(one, "After 10 tickets inserted...\n");
one = destroy(one); // destroys list, invalidate pointer
return 0;
}; // main()
List* create()
{
List* list = (List*)malloc(sizeof(List));
if (list == NULL) return NULL;
list->head = NULL;
list->size = 0;
return list;
}
List* destroy(List* list)
{
if (list == NULL) return NULL;
Node* tmp = list->head->next;
Node* p = list->head;
for (unsigned i = 0; i < list->size - 1; i += 1)
{ // delete ticket and node at p
free(p->tk);
free(p);
p = tmp;
tmp = p->next;
}
// p now points to last
free(p->tk);
free(p);
free(list); // the List itself
return NULL;
}
int insert(Ticket* tk, List* L)
{ // insert tk into list L, at the end
if (L == NULL) return -1;
if (tk == NULL) return -2;
// get a new ticket
Ticket* nt = (Ticket*)malloc(sizeof(Ticket));
*nt = *tk;
// now creates a new Node for this ticket
Node* nnd = (Node*)malloc(sizeof(Node));
nnd->next = NULL;
nnd->tk = nt;
// list is empty?
if (L->size == 0)
{
L->head = nnd;
L->size = 1;
return 0; // ok
}
// search List end
Node* p = L->head;
while (p->next != NULL) p = p->next;
p->next = nnd; // last now points to new
L->size += 1;
return 0; // ok
}
int show(List* L, const char* msg)
{
if (msg != NULL) printf("\n%s\n", msg);
if (L == NULL)
{
printf("There is no list: nothing to display");
return -1;
}
printf(" List has %d elements:\n\n", L->size);
Node* p = L->head;
for (unsigned i = 0; i < L->size; i += 1)
{
printf("%5u %s\n", p->tk->USN, p->tk->ts);
p = p->next;
}
printf("\n\n");
return L->size;
}
char* get_ts()
{ // return string in format: "yyyy-mm-dd hh:mm:ss"
time_t moment;
time(&moment); // get time
// convert time to struct tm
struct tm* t_info = localtime(&moment);
char* time_stamp = (char*)malloc(20);
// format time stamp and return to caller
strftime(time_stamp, 20, "%Y-%m-%d %H:%M:%S", t_info);
return time_stamp;
}