使用void指针交换函数

时间:2015-04-13 00:14:29

标签: c swap void-pointers

我想创建一个可以普遍用于任何数据类型的交换函数。我知道以下函数适用于整数:

void swap(void *a, void *b)
{
    int temp;
    temp = *(int*)a;
    *(int*)a = *(int*)b;
    *(int*)b = temp;
}

这适用于字符串:

void swap(void *a, void *b)
{
    void *temp;
    temp = *(void**)a;
    *(void**)a = *(void**)b;
    *(void**)b = temp;
}

3 个答案:

答案 0 :(得分:5)

如果你也传递了指针对象的大小(比如在qsort中),那么你可以这样做:

void swap(void * a, void * b, size_t len)
{
    unsigned char * p = a, * q = b, tmp;
    for (size_t i = 0; i != len; ++i)
    {
        tmp = p[i];
        p[i] = q[i];
        q[i] = tmp;
    }
}

用法:

struct Qux x, y;
swap(&x, &y, sizeof(Qux));

(您可能希望将restrict限定符添加到指针中,或者进行自我交换测试。)

答案 1 :(得分:0)

您应该至少阅读C FAQ list一次。随着时间的推移,很高兴看到人们在思考什么。

Why can't I perform arithmetic on a void * pointer? 与您的问题相关:

  

编译器不知道指向对象的大小。 (请记住,指针算法总是以指向的大小来表示;另请参阅问题4.4。)因此,不允许对void *进行算术运算(尽管某些编译器允许它作为扩展)。在执行算术运算之前,将指针转换为char *或指向您尝试操作的指针类型(但另请参阅问题4.5和16.7)。

同样相关的是Suppose I want to write a function that takes a generic pointer as an argument and I want to simulate passing it by reference. Can I give the formal parameter type void ** ...

  

C中没有通用指针到指针类型。void *仅作为通用指针使用,因为当其他指针类型分配到void *时,会自动应用转换(如果需要)的;如果尝试在指向void **以外的指针类型的void *值上进行间接尝试,则无法执行这些转换。当您使用void **指针值时(例如,当您使用*运算符访问void *指向的void **值时),编译器具有无法知道该void *值是否曾从其他指针类型转换过来。它必须假设它只不过是void *;它无法执行任何隐式转换。

答案 2 :(得分:-2)

这是另一个答案:

void swap(void *a, void *b, size_t width)
{
    void *temp = malloc(width);
    memcpy(temp, b, width);
    memcpy(b, a, width);
    memcpy(a, temp, width);
    free(temp);

}