1、声明链表节点操作函数 linklist.h
#ifndef LINKLIST_H__
#define LINKLIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>//#define TAIL_ADD
#define HEAD_ADD
typedef int LinkDataType;
// 构造节点
struct LinkNode
{LinkDataType data;struct LinkNode* pre;struct LinkNode* next;
};
typedef struct LinkNode LinkNode;/**创建带头结点链表*/
LinkNode*  create_linklist();LinkNode*  get_link_node(LinkNode*  node);/**新增节点*/
int  insert_link_node(LinkNode*  link,LinkDataType data);/**修改节点*/
int  update_link_node(LinkNode*  link,LinkDataType data,int index);bool  is_end(LinkNode*  link,LinkNode*  node);void  show_link_node(LinkNode* node);/**节点查询*/
int   find_link_node(LinkNode* link,LinkDataType data);void  show_link(LinkNode* link);/**链表销毁*/
void  destory_link(LinkNode* link);int*  get_arr();#endif2、定函数实现linklist.c
#include "linklist.h"LinkNode*  create_linklist()
{LinkNode* link =  malloc(sizeof(LinkNode*));if(link == NULL){perror("create_linklist  fail");exit(0);}link->next = link;link->pre  = link;link->data = 0;return link;
}int  insert_link_node(LinkNode*  link,LinkDataType data)
{LinkNode* node =  malloc(sizeof(LinkNode*));if(node == NULL){perror("node  init  fail");exit(0);}node->data = data;/// 头插法#ifdef HEAD_ADDnode->pre = link;node->next = link->next;link->next->pre = node;link->next = node; #endif///尾插法#ifdef TAIL_ADDnode->next = link;node->pre =  link->pre;link->pre->next = node;link->pre = node;#endifreturn 0;
}LinkNode*  get_link_node(LinkNode*  node)
{LinkNode*  tmp = NULL;#ifdef HEAD_ADDtmp =  node->next;#endif#ifdef TAIL_ADDtmp =  node->pre;#endifreturn tmp;
}bool  is_end(LinkNode*  link,LinkNode*  node)
{#ifdef HEAD_ADDreturn node->next==link->pre;   #endif#ifdef TATL_ADDreturn node->pre==link->next#endif
}int  delete_link_node(LinkNode* link,LinkDataType data)
{LinkNode*  node = link;while (node){if(node->data == data){LinkNode*  next_tmp = get_link_node(node);node->pre->next = node->next;node->next->pre = node->pre;free(node);node = next_tmp;  }}return 0;  
}int  update_link_node(LinkNode*  link,LinkDataType data,int index)
{int c = 0;LinkNode*  node = link;while (node){if(c == index){node->data = data;return c;}node = get_link_node(node);if(is_end(link,node))break;}return -1;
}int  find_link_node(LinkNode* link,LinkDataType data)
{int  index =0;LinkNode*  node = link;while (node){if(node->data==data){return index;}node = get_link_node(node);index++;if(is_end(link,node))break;}return -1;
}void  show_link_node(LinkNode* node)
{int  pre_data = 0;int  next_data = 0;int  data = node->data;if(node->pre!=NULL){pre_data = node->pre->data;}if(node->next!=NULL){next_data = node->next->data;}printf("%d, %d, %d \n",pre_data,data,next_data);
}void show_link(LinkNode* link)
{LinkNode*  node = link;while (!is_end(link,node)){show_link_node(node);node = get_link_node(node);}
}void  destory_link(LinkNode* link)
{LinkNode*  node = link;while (node){LinkNode* tmp = get_link_node(node);free(node);node = tmp;if(is_end(link,node))break;}
}int*  get_arr()
{int len =10;int* arr = malloc(len*sizeof(int*));int i=0;for(;i<len;i++){arr[i]=i;}return arr;
}3、编写测试函数main.h main.c
main.h函数定义定义
#ifndef MAIN_H__
#define MAIN_H__
#include "linklist.h"void  test_double_link_list()
{LinkNode*  link = create_linklist();int* arr = get_arr();int i=0;for(;i<10;i++){insert_link_node(link,*(arr+i));  }show_link(link);free(link);free(arr);
};#endifmain.c调用测试
#include "main.h"int main()
{test_double_link_list();exit(0);
}
4、编写Makefile文件
#$^ 表示所有的依赖文件
#$@ 表示生成的目标文件
#$< 代表第一个依赖文件
#dapp: main.o
#	gcc main.o  -o dsapp
#main.o: main.c 
#	gcc -c  main.c  -o  main.o
#SRCS += $(wildcard *.c)
#INCS += $(wildcard *.h)BUILD_DIR = ./build
TARGET_COMPILE += $(BUILD_DIR)/main.o  $(BUILD_DIR)/linklist.o
TARGET_EXE  = dsapp.outall: msg $(TARGET_EXE)  clean  #输出环境变量
msg:@echo $(CC) @echo $(RM)#生成可执行文件
$(TARGET_EXE): $(TARGET_COMPILE)$(CC) -Wall  $^  -o  $@#执行编译
$(BUILD_DIR)/%.o: %.c$(CC) -Wall -c $^ -o $@#删除编译文件
clean: $(TARGET_COMPILE) $(RM) $(TARGET_COMPILE)