C 語言實現泛型 swap 函式

codercat發表於2020-02-09

由於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 協議》,轉載必須註明作者和本文連結

相關文章