使用空指针交换函数

Swap function using 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;
}

如果你也传递指针对象的大小(如 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 限定符,或者以其他方式测试自交换。)

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

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

The compiler doesn't know the size of the pointed-to objects. (Remember that pointer arithmetic is always in terms of the pointed-to size; see also question 4.4.) Therefore, arithmetic on void *'s is disallowed (though some compilers allow it as an extension). Before performing arithmetic, convert the pointer either to char * or to the pointer type you're trying to manipulate (but see also questions 4.5 and 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 ** ...:

There is no generic pointer-to-pointer type in C. void * acts as a generic pointer only because conversions (if necessary) are applied automatically when other pointer types are assigned to and from void *'s; these conversions cannot be performed if an attempt is made to indirect upon a void ** value which points at a pointer type other than void *. When you make use of a void ** pointer value (for instance, when you use the * operator to access the void * value to which the void ** points), the compiler has no way of knowing whether that void * value was once converted from some other pointer type. It must assume that it is nothing more than a void *; it cannot perform any implicit conversions.

这是另一个答案:

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);

}