我在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 * stridej * stride大于数组的总大小(sizeof(array))。指针算术在这里如何工作?

最佳答案

为了更好地理解,我将重新排列应答顺序:

2-arrayvoid类型的指针。在C语言中,可以将指针分配给类型void*的指针或从中分配指针。任何指向对象的指针都可以转换为void*类型而不会丢失信息。如果将结果转换回原始指针类型,则将恢复原始指针。

1-它对单个元素的工作方式不同,您没有可以分配给任何类型的泛型类型。因此,代码正在切换指向内存的内容。

3-n是数组中元素的数量,而size是数组中单个元素的大小。 stride = size * sizeof(char);表示stride等于size,因为sizeof(char)等于1。数组sizeof(array)的大小等于n * size-数组中元素的数量乘以元素的大小。由于ij都小于n,所以i * stridej * stride
将永远不会大于数组使用的内存。我不知道为什么据我所知stride总是使用此sizeof(char)始终为1。

07-24 09:46
查看更多