C语言学习C语言学习
首先是类型声明:
点击(此处)折叠或打开typedef union tag_elmt {
char *header;
int n;
}ELMT;
typedef struct tag_node
{
ELMT *elem;
struct tag_node *next;
}NODE, *SLINK;
操作函数:
1)
node_generate ()
点击(此处)折叠或打开NODE *node_generate (void) {
ELMT *new_elem = malloc (sizeo...
C语言学习
首先是类型声明:
点击(此处)折叠或打开typedef union tag_elmt {
char *header;
int n;
}ELMT;
typedef struct tag_node
{
ELMT *elem;
struct tag_node *next;
}NODE, *SLINK;
操作函数:
1)
node_generate ()
点击(此处)折叠或打开NODE *node_generate (void) {
ELMT *new_elem = malloc (sizeof (ELMT)); memset (new_elem, 0, sizeof (ELMT));
NODE *new_node = malloc (sizeof (NODE)); memset (new_node, 0, sizeof (NODE));
new_node->elem = new_elem;
return new_node;
}用于生成节点。
每产生一新的节点,意味着有新的空间开销,所以必须对节点分配空间。若节点元素为结构体或者共用体(本例中为共用体),则应由内向外,逐层分配。
一个选手可以注册多个ID,一块内存空间也可以被多个指针指向。声明一指针,指向一已知内存空间,不需要为其
分配空间。
2)
header_generate ()
点击(此处)折叠或打开SLINK header_generate (void) {
NODE *header = node_generate (); header->elem->header = "header"; header->next = NULL;
return header;
}生成头节点,链
初始化。
3)
locate ()
点击(此处)折叠或打开SLINK locate (SLINK list, int pos) //为便于操作,返回pos所在节点的前驱
{
NODE *prev = list;
NODE *cur = list->next;
for (;NULL != cur->next && pos != cur->elem->n; prev = prev->next, cur = cur->next)
;
return prev;
}由给定节点元素值定位节点。为便于调用,locate返回给定节点前驱。此处用空for循环实现,注意分号。
4)
node_insert ()
节点插入。
点击(此处)折叠或打开SLINK node_insert (SLINK list, int add, int *pos)
{
NODE *new_node = node_generate (); NODE *prev = NULL;
new_node->elem->n = add; if (NULL == pos)
{
new_node->next = list->next; list->next = new_node;
}
else
{
prev = locate (list, *pos);
new_node->next = prev->next; prev->next = new_node;
}
return list;
}指针pos为位置标签。当pos = NULL时,表头插入。否则,插到*pos所在节点之前。
5)
node_delete ()
点击(此处)折叠或打开SLINK node_delete (SLINK list, int del) {
NODE *prev = locate (list, del);
NODE *target = prev->next;
prev->next = target->next;
free (target);
return list;
}节点删除,勿忘free。
6)
dump_list ()
点击(此处)折叠或打开SLINK dump_list (SLINK list) { list = list->next; //跳过头节点 // for (int node_num = 0; NULL != list->next; list = list->next) //会造成最后一节点丢失 for (int node_num = 0; NULL != list; list = list->next) { node_num++; if (1 == node_num %
10 && 11 != node_num) { printf ("The %dst element
is %d.\n", node_num, list->elem->n); } else if (2 == node_num % 10 && 12 != node_num) { printf ("The %dnd element is %d.\n", node_num, list->elem->n); } else if (3 == node_num % 10 && 13 != node_num) { printf ("The %drd element is %d.\n", node_num,
list->elem->n); } else { printf ("The %dth element is %d.\n", node_num,
list->elem->n); } } return list; }遍历链表。首
先要跳过头节点。注意for循环控制语句。
7)reverse
_list ()
点击(此处)折叠或打开void reverse_list (SLINK list)
{
SLINK tmp = list->next;
//SLINK tmp;
NODE *cur = NULL;
list->next = NULL;
//for (tmp = tmp->next; NULL != tmp->next; )
//for (tmp = tmp->next; NULL != tmp; )
for (; NULL != tmp;)//while (tmp)
{
cur = tmp;
tmp = tmp->next;
cur->next = list->next;
list->next = cur;
}
}倒置链表。
当for控制语句为
for (tmp = tmp->next; NULL != tmp->next;) 时,在最后一次循环总,tmp = tmp->next已经使得tmp指向NULL,再执行控制语句 NULL != tmp->next时,会产生段错误。
当控制语句为 for (tmp = tmp->next; NULL != tmp;)时,会产生段错误,不知何故,留待认知。
此处用while循环更合适。while (tmp)。
8)
clear_list ()
点击(此处)折叠或打开SLINK clear_list (SLINK list) {
NODE *cur = NULL;
for (list = list->next; NULL != list->next;)
{
cur = list;
list = list->next;
free (cur);
}
return list;
}清空链表,执行后list->next指向NULL, 头节点仍在。
9)
destroy_list ()
点击(此处)折叠或打开void destroy_list (SLINK *list) {
NODE *cur = NULL;
for (*list = (*list)->next; NULL != (*list)->next;)
{
cur = *list;
*list = (*list)->next;
free (cur);
}
}销毁链表,执行后list指向NULL,头节点不再。若destroy_list后执行clear_list,会导致段错误。
clear_list和destroy_list参数不同,导致结果不同。clear传入参数为链表指针,clear
执行后链表指针执行
本文档为【C语言学习】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。