泛型编程(generic programming)是C++语言中的一个重要特性。基于C++和C语言之间的紧密关系,C语言中通过一定的技巧也可以实现泛型编程。

对于一个swap函数,C语言中一般用指针来实现:

void swap (int* ip1,int* ip2)
{
    int temp = *ip1;
    *ip1 = *ip2;
    *ip2 = temp;
}

对于相同类型的变量来说,其内在实现方式就是位模式(bit pattern)的拷贝。事实上,这个swap函数不仅仅对int类型的变量起作用,对于float类型(同样也是4字节)的变量也是可以正确进行交换的。进一步来说,哪怕对于struct结构体,只要它占的内存是4字节,这个函数总是能正确的起作用。

那么难道我们只能对4个字节类型的变量进行操作吗?当然不是。通过void指针,我们可以对任意大小的变量进行swap操作。对照上面的代码,我们可以写出:

void swap (void* vp1,void* vp2)
{
    void temp = *vp1;
    *vp1 = *vp2;
    *vp2 = temp;
}

等一下,这样做对吗?当然是错误的。首先,我们不能定义一个void类型的变量temp,因为void表示的类型就是无类型,编译器不知道它的大小也就无法分配内存。其次,对于void*指向的内存地址进行bit pattern的拷贝时,编译器也无法知道从起始地址开始究竟要拷贝多长的内存。

那么我们要怎么做呢?看下面的代码:

void swap (void* vp1,void* vp2,int size)
{
    char* buf = (char*)malloc(size);
    memcpy(buf,vp1,size);
    memcpy(vp1,vp2,size);
    memcpy(vp2,buf,size);
}

通过size参数传递要交换类型的大小,动态申请一段size大小的内存作为额外空间,利用memcpy函数进行bit pattern的拷贝,这样就完全符合我们的需求了。

本文固定链接: http://www.js-code.com/c/c_61827.html