一、内核链表
以创建一个学生工程为例
linklist.h
#ifndef __KERLIST_H__
#define __KERLIST_H__
/* 链表节点类型 */
typedef struct node
{
struct node *pnext; //链表下一个节点的地址
}LinkNode;
extern LinkNode *CreateKerList(void);
extern int InsertHeadKerList(LinkNode *pHead, void *pNewNode);
extern int InsertTailKerList(LinkNode *pHead, void *pNewNode);
extern int ForeachKerList(LinkNode *pHead, int (*pfun)(void *pTmpNode));
extern void *SearchKerList(LinkNode *pHead, int (*pcmpfun)(void *pTmpNode));
extern int DestroyKerList(LinkNode **pHead);
#endif
linklist.c
#include "kerlist.h"
#include <stdlib.h>
/*******************************************************
*函数名: CreateKerList
*功 能:
* 创建一个空内核链表
*参 数:
* 缺省
*返回值:
* 成功返回表头地址
* 失败返回NULL
******************************************************/
LinkNode *CreateKerList(void)
{
LinkNode *pTmpNode = NULL;
pTmpNode = malloc(sizeof(LinkNode));
if (NULL == pTmpNode)
{
return NULL;
}
pTmpNode->pnext = NULL;
return pTmpNode;
}
/*******************************************************
*函数名: InsertHeadKerList
*功 能:
* 头插法插入节点
*参 数:
* pHead:链表头节点地址
* pNewNode:要插入的数据节点地址
*返回值:
* 成功返回0
* 失败返回-1
******************************************************/
int InsertHeadKerList(LinkNode *pHead, void *pNewNode)
{
if (NULL == pNewNode || NULL == pHead)
{
return -1;
}
((LinkNode *)pNewNode)->pnext = pHead->pnext;
pHead->pnext = pNewNode;
return 0;
}
/*******************************************************
*函数名: InsertTailKerList
*功 能:
* 尾插法插入节点
*参 数:
* pHead:链表头节点地址
* pNewNode:要插入的数据节点地址
*返回值:
* 成功返回0
* 失败返回-1
******************************************************/
int InsertTailKerList(LinkNode *pHead, void *pNewNode)
{
LinkNode *pTmpNode = NULL;
if (NULL == pNewNode || NULL == pHead)
{
return -1;
}
pTmpNode = pHead;
while (pTmpNode->pnext != NULL)
{
pTmpNode = pTmpNode->pnext;
}
((LinkNode *)pNewNode)->pnext = NULL;
pTmpNode->pnext = pNewNode;
return 0;
}
/*******************************************************
*函数名: ForeachKerList
*功 能:
* 遍历链表中每个节点元素
*参 数:
* pHead:链表头节点地址
* pfun:对每个链表节点所做的操作
*返回值:
* 成功返回0
* 失败返回-1
******************************************************/
int ForeachKerList(LinkNode *pHead, int (*pfun)(void *pTmpNode))
{
LinkNode *pTmpNode = NULL;
int ret = 0;
pTmpNode = pHead->pnext;
while (pTmpNode != NULL)
{
ret = pfun(pTmpNode);
if (-1 == ret)
{
return -1;
}
pTmpNode = pTmpNode->pnext;
}
return 0;
}
/*******************************************************
*函数名: SearchKerList
*功 能:
* 查找链表中的元素
*参 数:
* pHead:链表头节点地址
* pcmpfun:匹配条件
*返回值:
* 成功返回找到节点的地址
* 失败返回NULL
******************************************************/
void *SearchKerList(LinkNode *pHead, int (*pcmpfun)(void *pTmpNode))
{
LinkNode *pTmpNode = NULL;
pTmpNode = pHead->pnext;
while (pTmpNode != NULL)
{
if (pcmpfun(pTmpNode))
{
return (void *)pTmpNode;
}
pTmpNode = pTmpNode->pnext;
}
return NULL;
}
/*******************************************************
*函数名: DestroyKerList
*功 能:
* 销毁内核链表
*参 数:
* pHead:链表头节点地址
*返回值:
* 成功返回0
* 失败返回-1
******************************************************/
int DestroyKerList(LinkNode **pHead)
{
if (*pHead != NULL)
{
free(*pHead);
}
*pHead = NULL;
return 0;
}
main.c
#include "kerlist.h"
#include <stdio.h>
typedef struct student
{
LinkNode node;
char name[32];
char sex;
int age;
int score;
}stu_t;
int PrintStuInfo(void *pdata)
{
stu_t *ptmp = pdata;
printf("姓名:%s\n", ptmp->name);
printf("性别:%c\n", ptmp->sex);
printf("年龄:%d\n", ptmp->age);
printf("成绩:%d\n", ptmp->score);
return 0;
}
int compare(void *pnode)
{
stu_t *pstu = pnode;
if (pstu->score > 90)
{
return 1;
}
return 0;
}
int main(void)
{
stu_t a = {{NULL}, "zhangsan", 'm', 19, 100};
stu_t b = {{NULL}, "lisi", 'm', 19, 70};
stu_t c = {{NULL}, "wanger", 'f', 19, 90};
LinkNode *pHead = NULL;
LinkNode *pTmpNode = NULL;
pHead = CreateKerList();
InsertTailKerList(pHead, &a);
InsertTailKerList(pHead, &b);
InsertTailKerList(pHead, &c);
ForeachKerList(pHead, PrintStuInfo);
pTmpNode = SearchKerList(pHead, compare);
printf("%s\n", ((stu_t *)pTmpNode)->name);
DestroyKerList(&pHead);
return 0;
}
二、总结
今天是2024年7月29日,学习的第16天。今天也是结束了第一阶段的C语言学习。总的来说,在难点在于指针与数组以及后面的内核链表。
加油。