C语言之回调函数
先来看下函数指针的的基础知识,函数指针,顾名思义,就是指向函数的指针,声明方法如下:
int func(int); //函数原型
int (*pfunc)(int) = & func; //创建函数指针pfunc,并指向函数func
这里的&操作符可有可无,因为函数名本身就是一个地址。
回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。在我们想通过一个统一接口实现不同的内容时,用回调函数非常合适。
例如:有如下用于不同设备的显示函数
Void A_show(); Void B_show(); Void C_show();
Void show(void (*ptr)());
使用时我们就可以将函数作为参数
show(A_show);
再举一个经典的例子,实现在一个单链表中查找一个值。
Node *
Search_list(Node *node,int const value)
{
While(node!=NULL){
if(node->value == value)
break;
node = node->link;
}
return node;
}
这个函数只适用于值为整形的链表,因为value的值为int型,如果此时你需要在一个字符串链表中查找,需要编写另外的函数来实现。这时就用到了回调函数,使查找函数与类型无关,这样就能用于任何类型的值的链表。
Node *
Search_list(Node *node,void const value,
int (*compare)(void const * ,void const *))
{
While(node!=NULL){
if(compare(&node->value,value)==0)
break;
node = node->link;
}
return node;
}
int compare_ints(void const *a, void const *b)
{
if(*(int*)a == *(int *)b)
return 0;
else
return 1;
}
我们在使用Search_list函数时,你已经知道要查找数据的数据类型了。用法如下:
Desired_node = Search_list(root, &desired_value,compare_ints);
那如果你要在一个字符串链表中查找呢?首先你要在定义用于比较字符串一个函数:
int compare_chars(void const *a, void const *b)
{
if(*(char*)a == *(char *)b)
return 0;
else
return 1;
}
当然你不必这样来写,因为C语言函数库里面有这样的函数
strcmp( const char *string1, const char *string2 );
所以你就可以直接使用下面的代码来实现在字符串链表中查找字符值的功能
Desired_node = Search_list(root, &desired_value, strcmp);
这样,可以不必修改Search_list函数,而使得Search_list函数的功能更加通用。
C语言之面向对象
我们经常说C语言是面向过程的语言,而C++、JAVA是面向对象的,但是面向对象并不是C++、JAVA的专利,C语言里面也有面向对象的思想,比如我们经常使用的结构体。
struct student
{
char name[256];
int age;
};
学生的姓名和年龄,就是学生自身的属性,和C++里面的成员变量是一样的概念,但是这个结构体里面并没有体现出方法的使用。在面向对象中有封装的概念,结构体中的成员我们不应该直接访问,而应该通过方法访问,我们可以添加访问结构体成员变量的方法。
char* get_name(student * self);//获取学生姓名
void set_name(student * self, char* name);//设置学生姓名
char* get_name(student * self)
{
return self->name;
}
void set_name(student * self, char* name)
{
strncpy(self->name, name, sizeof(self->name));
}
此处省略age的设置和获取功能。
现在类的数据、方法都有了,下一步就是要使用类创建、初始化、析构、销毁对象,在C++中有new、delete操作符负责创建和销毁,使用C语言实现如下:
student * student _create(void);// 对象创建和初始化
void student _destroy(student * self);// 对象析构和销毁
student * student _create(void)
{
student * self = malloc(sizeof(student));
memset(self->name, 0x00, sizeof(self->name));
self->age = 0;
return self;
}
void student _destroy(student * self)
{
free(self);
}
至此,我们就可以采用面向对象的方式来编写代码了。
student * student1= NULL;
student1 = student _create();//创建对象
set_name(student1, "mary");//初始化student1的名字为mary
set_age(student1, 20); //初始化student1的年龄为20
get_name(student1);//获取student1的姓名
student _destroy(student1);//销毁对象
当然C语言还有很多强大的功能,比如可变参数的函数设计,无一例外都要借助于指针来实现。以上内容参考于网络资源,如有错误之处,恳请指正。