使用空指针交换函数
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).
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);
}
我想制作一个可以普遍用于任何数据类型的交换函数。我知道以下函数适用于整数:
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 tochar *
or to the pointer type you're trying to manipulate (but see also questions 4.5 and 16.7).
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 fromvoid *
's; these conversions cannot be performed if an attempt is made to indirect upon avoid **
value which points at a pointer type other thanvoid *
. When you make use of avoid **
pointer value (for instance, when you use the*
operator to access thevoid *
value to which thevoid **
points), the compiler has no way of knowing whether thatvoid *
value was once converted from some other pointer type. It must assume that it is nothing more than avoid *
; 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);
}