C 语言实现泛型 swap 函数

由于C语言是强类型语言,所以通常我们在编写一些函数的时候就需要指定函数的类型。这就会导致同样的函数行为因为处理的类型不同,就可能需要为不同的类型编写不同的函数版本。

比如用于交换两个变量值的如swap函数:


void  swap(int  *v1, int  *v2)  {

    int *temp = v1;

    *v1 = *v2;

    *v2 = *temp;

}

上面的swap函数只能交换两个int类型的整数。

如果需要交换两个double类型的浮点数就需要再写一个double类型版本的swap函数:


void  swap(double  *v1, double  *v2)  {

    int *temp = v1;

    *v1 = *v2;

    *v2 = *temp;

}

所谓泛型swap函数就是一个swap函数就能够处理不同类型的交换工作。在C++有模版来实现泛型,但是C语言中没有模板,所以我们可以使用void类型的指针来实现泛型swap函数,任何类型的指针都可以赋值给void类型的指针。

泛型swap函数实现:


    void  swap(void  *v1, void  *v2, size_t  size)  {

    void *temp = malloc(size);

    assert(temp != NULL);

    memcpy(temp, v1, size);

    memcpy(v1, v2, size);

    memcpy(v2, temp, size);

    free(temp);

}

先对函数中出现的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类型变量的值:


int  main()  {

    int a = 123;

    int b = 321;

    printf("before swap: %d, %d\n", a, b);

    swap(&a, &b, sizeof(int));

    printf("after swap: %d, %d\n", a, b);

    return 0;

}

输出:


before swap: 123, 321

after swap: 321, 123

swap函数进行调用,交换两个double类型变量的值:


int  main()  {

    double a = 123;

    double b = 321;

    printf("before swap: %f, %f\n", a, b);

    swap(&a, &b, sizeof(double));

    printf("after swap: %f, %f\n", a, b);

    return 0;

}

输出:


before swap: 123.000000, 321.000000

after swap: 321.000000, 123.000000

运行实现中的完整代码还需要引入头文件:


#include  <stdio.h>

#include  <stdlib.h>

#include  <string.h>

#include  <assert.h>

以上就是泛型swap函数的具体实现,主要是运用了void指针和内存拷贝。可以借鉴实现思路来研究关于C语言实现泛型的更多例子。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!