C语言实现泛型函数
由于C语言是强类型语言,所以通常我们在编写一些函数的时候就需要指定函数的类型。这就会导致同样的函数行为因为处理的类型不同,就可能需要为不同的类型编写不同的函数版本。
比如用于交换两个变量值的如swap
函数:
1 | void swap(int *v1, int *v2) { |
上面的swap
函数只能交换两个int
类型的整数。
如果需要交换两个double
类型的浮点数就需要再写一个double
类型版本的swap
函数:
1 | void swap(double *v1, double *v2) { |
所谓
泛型swap函数
就是一个swap函数就能够处理不同类型的交换工作。在C++有模版
来实现泛型,但是C语言中没有模板
,所以我们可以使用void
类型的指针来实现泛型swap函数
,任何类型的指针都可以赋值给void
类型的指针。
泛型swap函数
实现:
1 | void swap(void *v1, void *v2, size_t size) { |
先对函数中出现的3个函数分别加以说明:
malloc
函数原型为
void *malloc(size_t __size)
。该函数用来向堆中动态申请一块内存。它会向堆中动态申请参数__size
个字节大小的内存空间,如果申请成功就返回申请到的空间首地址,申请失败就返回NULL
。memcpy
函数原型为
void *memcpy(void *dest, const void *src, size_t n)
。该函数用来实现内存拷贝,它把参数src
所指向的内存空间拷贝n
个字节到参数dest
所指向的内存空间中。free
函数原型为
void free(void *ptr)
,该函数用来释放动态申请的内存。它把参数ptr
所指向的动态申请的内存空间进行释放。
函数签名void swap(void *v1, void *v2, size_t size)
中的前两个参数使用了void
类型的指针,第三个参数size
表示需要交换的类型在内存中所占字节数量。
第2~3行代码是向堆中
申请size
个字节大小的空间,然后将空间首地址赋值给temp
指针,并断言内存是否申请成功。
第4~6行代码是通过内存拷贝
的方式来实现交换步骤。
第7行代码是把在第3行代码中动态申请到的size
个字节大小的内存空间进行释放,以免发生内存泄漏。
对swap
函数进行调用,交换两个int
类型变量的值:
1 | int main() { |
输出:
1 | before swap: 123, 321 |
对swap
函数进行调用,交换两个double
类型变量的值:
1 | int main() { |
输出:
1 | before swap: 123.000000, 321.000000 |
运行实现中的完整代码还需要引入头文件:
1 |
以上就是泛型swap
函数的具体实现,主要是运用了void
指针和内存拷贝
。可以借鉴实现思路来研究关于C语言实现泛型的更多例子。