学习笔记
《深入理解C指针》
http://www.ituring.com.cn/book/1147
第6章 指针与结构体
本文结构
- 函数模板:自定义的一个雇员结构体
- 单链表实现:头部增加结点
addHead
、尾部增加结点addTail
、获取指定结点getNode
、删除指定结点deleteN
、比较函数(函数指针)、显示函数(函数指针)- 完整源码:C语言 实现 单链表
函数模板
- 一个雇员结构体
typedef struct _employee{
char name[32];
unsigned char age;
} Employee;
- 基于雇员名字的比较函数
int compareEmployee(Employee *e1, Employee *e2) {
return strcmp(e1->name, e2->name);
}
- 显示函数
void displayEmployee(Employee* employee) {
printf("%s\t%d\n", employee->name, employee->age);
}
- 两个函数指针
typedef void(*DISPLAY)(void*);
typedef int(*COMPARE)(void*, void*);
DISPLAY
函数指针表示一个接受void*
参数并返回void
的函数,目的是显示数据
COMPARE
函数比较两个指针引用的数据,它的返回值是0
、-1
或1
单链表
结点的定义
typedef struct _node {
void *data;
struct _node *next;
} Node;
void * data
意味着可以是任意的指针,即可以是普通的数据类型指针(比如int *
),也可以是结构体指针(比如Employee *
)
- 结点结构体定义
void * data;
- 函数的形式参数
void addHead(LinkedList *list, void* data) {}
- 实际代码传入的参数,是一个结构体指针
Employee *samuel = (Employee*) malloc(sizeof(Employee));
addHead(&linkedList, samuel);
void * data
比较函数的函数指针
比较函数的函数指针
- 只要传入参数是两个
void *
,就是COMPARE类型的函数
typedef int(*COMPARE)(void*, void*);
- 函数类型是COMPARE,函数名是
compare
Node *getNode(LinkedList *list,
COMPARE compare , void* data) {
. . .
if (compare(node->data, data) == 0) { }
. . .
}
compare
函数说明了如何在运行时用函数指针来决定用哪个函数执行比较操作,这样会给链表的实现增加可观的灵活性,因为我们不需要在getNode
函数中硬编码比较函数的名字。
显示函数的函数指针
显示函数 的 调用关系 示意图-
定义函数类型
typedef void(*DISPLAY)(void*);
只要输入参数是void*
并且返回void
的函数就可以被叫做 DISPLAY类型 -
传入函数指针,调用时直接写
display(. . .);
void displayLinkedList( LinkedList *list,
DISPLAY display) {
. . .
display(current->data);
. . .
}
- 具体地实现一个以
Employee *
作为输入参数并且返回void
的函数
void displayEmployee ( Employee* employee ) {
printf("%s\t%d\n", employee->name, employee->age);
}
- 把全部的东西整合起来,在main函数里面定义一切
displayLinkedList( &linkedList, (DISPLAY)displayEmployee );
运行结果
运行结果完整源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef void(*DISPLAY)(void*);
typedef int(*COMPARE)(void*, void*);
typedef struct _employee{
char name[32];
unsigned char age;
} Employee;
int compareEmployee(Employee *e1, Employee *e2) {
return strcmp(e1->name, e2->name);
}
void displayEmployee(Employee* employee) {
printf("%s\t%d\n", employee->name, employee->age);
}
typedef struct _node {
void *data;
struct _node *next;
} Node;
typedef struct _linkedList {
Node *head;
Node *tail;
Node *current;
} LinkedList;
void initializeList(LinkedList *list) {
list->head = NULL;
list->tail = NULL;
list->current = NULL;
}
void addHead(LinkedList *list, void* data) {
Node *node = (Node*) malloc(sizeof(Node));
node->data = data;
if (list->head == NULL) {
list->tail = node;
node->next = NULL;
} else {
node->next = list->head;
}
list->head = node;
}
void addTail(LinkedList *list, void* data) {
Node *node = (Node*) malloc(sizeof(Node));
node->data = data;
node->next = NULL;
if (list->head == NULL) {
list->head = node;
} else {
list->tail->next = node;
}
list->tail = node;
}
Node *getNode(LinkedList *list, COMPARE compare , void* data) {
Node *node = list->head;
while (node != NULL) {
if (compare(node->data, data) == 0) {
return node;
}
node = node->next;
}
return NULL;
}
void deleteN(LinkedList *list, Node *node) {
if (node == list->head) {
if (list->head->next == NULL) {
list->head = list->tail = NULL;
} else {
list->head = list->head->next;
}
} else {
Node *tmp = list->head;
while (tmp != NULL && tmp->next != node) {
tmp = tmp->next;
}
if (tmp != NULL) {
tmp->next = node->next;
}
}
free(node);
}
void displayLinkedList(LinkedList *list, DISPLAY display) {
printf("\nLinked List\n");
Node *current = list->head;
while (current != NULL) {
display(current->data);
current = current->next;
}
}
int main()
{
LinkedList linkedList;
Employee *samuel = (Employee*) malloc(sizeof(Employee));
strcpy(samuel->name, "Samuel");
samuel->age = 32;
Employee *sally = (Employee*) malloc(sizeof(Employee));
strcpy(sally->name, "Sally");
sally->age = 28;
Employee *susan = (Employee*) malloc(sizeof(Employee));
strcpy(susan->name, "Susan");
susan->age = 45;
initializeList(&linkedList);
addHead(&linkedList, samuel);
addHead(&linkedList, sally);
addHead(&linkedList, susan);
Node *node = getNode(&linkedList,
(int (*)(void*, void*))compareEmployee , sally);
displayLinkedList(&linkedList, (DISPLAY)displayEmployee);
printf("Message:Delete Sally.\n");
deleteN(&linkedList, node);
displayLinkedList(&linkedList, (DISPLAY)displayEmployee);
}
网友评论