C-函数指针

C中函数指针最重要的两个用途:

(1)作为另一个函数的参数

(2)转换表(jump table)


C语言中,()的优先级大于*,因此函数int *f()与int (*f)(),前者返回值为int型的指针,后者f为指向函数的指针。


编写一个简单的链表测试用例,测试函数指针作为另一个函数的参数的用途。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

typedef struct node{
	void *data;
	struct node *next;
}Node;

typedef struct list{
	Node *head;
	Node *tail;
	int list_len;
}List;

typedef struct test{
	char *dest_addr;
	char *local_addr;
	int link_quality;
}Test;

int compare_str(const void *s1, const void *s2)
{
	Test *a, *b;
	a = (Test *)s1;
	b = (Test *)s2;

	if (!memcmp(a, b, sizeof(Test))){
		return 0;
	}

	return 1;
}

void handle(void * data)
{
	Test *n;
	n = (Test *)data;
	printf("dest_addr: %s\n", n->dest_addr);
	printf("local_addr: %s\n", n->local_addr);
	printf("link_quality: %d\n\n", n->link_quality);
}

void list_init(List *list)
{
	list->head = NULL;
	list->tail = NULL;
	list->list_len = 0;
}

void list_destroy(List *list, void(*destroy)(void *))
{
	list->list_len = 0;
	Node *n, *tmp;
	n = list->head;

	while (n){
		tmp = n->next;
		if (destroy){
			destroy(n->data);
		}
		free(n);
		n = tmp;
	}
}

void list_traverse(List *list, void(*handle)(void *))
{
	Node *p;

	p = list->head;
	while (p){
		handle(p->data);
		p = p->next;
	}
}

Node* make_node(void *data)
{
	Node *n;

	n = malloc(sizeof(struct node));
	assert(n != NULL);

	n->next = NULL;
	n->data = data;

	return n;
}

void list_insert(List *list, void *data)
{
	Node *n;
	n = make_node(data);

	if (list->head == NULL){
		list->head = n;
		list->tail = n;
		n->next = NULL;
	}
	else{
		list->tail->next = n;
		list->tail = n;
		n->next = NULL;
	}
	list->list_len++;
}

void* list_search(List *list, void *key, int(*compare)(const void *, const void *))
{
	int i = 1;
	Node *n;
	n = list->head;

	while (n){
		if (!compare(n->data, key)){
			printf("List Node Number: %d\n", i);
			return n->data;
		}
		n = n->next;
		i++;
	}

	return NULL;
}

void main()
{
	Node *n;
	List *list;
	list = (List *)malloc(sizeof(List));

	list_init(list);

	Test n1 = { "192.168.5.10", "192.168.5.12", 1};
	Test n2 = { "192.168.5.20", "192.168.5.22", 2 };
	Test n3 = { "192.168.5.30", "192.168.5.32", 3 };

	Test nt = { "192.168.5.20", "192.168.5.22", 2 };

	list_insert(list, &n1);
	list_insert(list, &n2);
	list_insert(list, &n3);
	printf("list_length: %d\n", list->list_len);

	list_traverse(list, handle);
	n = list_search(list, &nt, compare_str);
	if (n != NULL){
		printf("Find List Node \n");
	}

	list_destroy(list, 0);

	system("pause");
}


程序运行结果为:



使用到的函数指针有两个:void (*handle)(void *)和int (*compare)(const void *, const void *)

分别用于遍历时的数据处理以及结点数据比较。


第二种转移表的用途主要用于取代switch,定义int (*func[])(int, int)。其意义为元素函数指针的数组。



转载于:https://my.oschina.net/u/2510891/blog/669499

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值