【编程范式】C语言泛型

C语言中使用void *指针实现泛型编程

1.swap函数——实现交换任意类型的两个元素
2.lsearch函数——线性查找数组中的元素

swap函数——实现交换任意类型的两个元素

void swap(void *vp1, void *vp2, int size)
{
char buffer[size];
memcpy(buffer, vp1, size);
memcpy(vp1, vp2, size);
memcpy(vp2, buffer, size);
}
注:通用的C编译器,不能给数组指定一个变量,可用动态内存分配malloc解决
swap的测试用例

void Test()
{
int x = 17, y = 37;
swap(&x, &y, sizeof(int));//正确

double d = 3.1415 e = 1.12121
swap(&d, &e, sizeof(int));//错误,只交换了8字节的前四个字节

int i = 44;
short s = 5;
swap(&i, &s, sizeof(short));//错误,大端结果为5*2的16次方,加上44,小端结果略有不同
}
注:使用swap时交换要注意不能"越界"(字符串的交换容易出错,对缓存大小、字符串长度也有要求,往往用c++中的string类型实现)

lsearch函数——线性查找数组中的元素

void *lsearch(void *key, void *base, int n, int elemSzie, int (*cmpfn)(void *, void *))
{
for (int i = 0; i < n; i++) {
void *elemAddr = (char *)base + i*elemSize;//void* 技巧,使指针算数运算和平常的运算效果相同
if (cmpfn(key, elemAddr) == 0)
return elemAddr;
}
return NULL;
}
注:void *型指针做偏移时,强转为char *型(c语言中常称为void *技巧)

比较函数

int IntCmp(void *elem1, void *elem2)
{
int *ip1 = elem1;
int *ip2 = elem2;
return *ip1 - *ip2;
}

int StrCmp(void *vp1, viod *vp2)
{
char *s1 = *(char **)vp1;
char *s2 = *(char **)vp2;
return strcmp(s1, s2);//strcmp()为库函数
}

lsearch的测试用例

char *strs[]={"Ag", "Fb", "B", "Gb", "D"};
char *foundStr = "Eb";
char **found = lsearch(&foundStr, strs, 5, sizeof(char *), StrCmp);

你可能感兴趣的:(编程范式)