我在this thread上发现了以下用于改组任何类型的数据类型的函数:
#define NELEMS(x) (sizeof(x) / sizeof(x[0]))
/* arrange the N elements of ARRAY in random order.
* Only effective if N is much smaller than RAND_MAX;
* if this may not be the case, use a better random
* number generator. */
static void shuffle(void *array, size_t n, size_t size) {
char tmp[size];
char *arr = array;
size_t stride = size * sizeof(char);
if (n > 1) {
size_t i;
for (i = 0; i < n - 1; ++i) {
size_t rnd = (size_t) rand();
size_t j = i + rnd / (RAND_MAX / (n - i) + 1);
memcpy(tmp, arr + j * stride, size);
memcpy(arr + j * stride, arr + i * stride, size);
memcpy(arr + i * stride, tmp, size);
}
}
}
我一直在测试,它似乎可以正常工作,但是我很难理解它的工作方式和原因。
它如何以及为什么不直接在
array
上交换数组的元素如何将数组分配给char *:
char *arr = array;
memcpy函数中的偏移量
i * stride
或j * stride
大于数组的总大小(sizeof(array)
)。指针算术在这里如何工作? 最佳答案
为了更好地理解,我将重新排列应答顺序:
2-array
是void
类型的指针。在C语言中,可以将指针分配给类型void*
的指针或从中分配指针。任何指向对象的指针都可以转换为void*
类型而不会丢失信息。如果将结果转换回原始指针类型,则将恢复原始指针。
1-它对单个元素的工作方式不同,您没有可以分配给任何类型的泛型类型。因此,代码正在切换指向内存的内容。
3-n
是数组中元素的数量,而size
是数组中单个元素的大小。 stride = size * sizeof(char);
表示stride
等于size
,因为sizeof(char)
等于1。数组sizeof(array)
的大小等于n * size
-数组中元素的数量乘以元素的大小。由于i
和j
都小于n
,所以i * stride
和j * stride
将永远不会大于数组使用的内存。我不知道为什么据我所知stride
总是使用此sizeof(char)
始终为1。