C 通过将数组中的任何指针转换为 void 指针来交换它们 K&R

标签 c pointers

我发现了很多与此相关的线索,但没有一个回复能够阐明我的具体问题。

因此,K&R 标题为“函数指针”的部分讨论了将任意指针数组转换为 void* 指针数组,然后将此数组传递给 qsort ,以便能够对通用项目数组进行排序。

qsort 使用名为 swap 的函数,该函数交换其中两个 void* 指针,从而有效地交换数组中将指向的位置在。

它通过通用实现这一点

void* tmp = v[i];
v[i] = v[j];
v[j] = tmp;

这是我的问题。假设传入的 v 是一个整数指针数组,并且假设它们是 4 个字节。在 swap 中,该数组表示为 void* 指针数组。当函数执行 v[i] = ... 时,它会将 v 第一个元素的位置偏移 i*sizeof(void*) 并获取此内存位置中的元素。正确的?但是如果 sizeof(void*)sizeof(int*) 不同怎么办?那么 v[i] 将无法获得包含原始 int* 的整个内存位置,而且我什至无法假设将返回什么。 那么 swap 是如何解释这一点的呢? 提前致谢

最佳答案

it offsets the location of the first element of v by i*sizeof(void*) and gets the element in this memory location. Correct?

是的,它根据通常的指针算术使用元素的大小(在本例中为 void*)获取索引元素的位置。

But what if sizeof(void*) is not the same as sizeof(int*)? Then v[i] will not get the the whole memory location containing the original int* and I am afraid to even postulate what will be returned.

事实上,sizeof(void*) 不需要与 sizeof(int*) 相同(尽管通常是这样),并且如果大小不同同样,迟早你可能会遇到未定义的行为。

So how does swap account for this?

事实并非如此。 stdlib 的 qsort然而,不同的是:

void qsort(void *base, size_t nmemb, size_t size,
       int (*compar)(const void *, const void *));

size 参数通过指定每个元素的大小来处理这个问题,允许对非指针类型进行排序,并将可以正确转换回原始类型的 void 指针传递给 compare()函数。

您可以自己编写一个类似的 swap() ,它接受元素的大小作为参数,计算正确的位置,并使用 memcpy() 交换它们。

关于C 通过将数组中的任何指针转换为 void 指针来交换它们 K&R,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32830613/

相关文章:

c - 运行 udev 时挂起

c - 用C语言制作主要算法/伪代码

c++ - 计算斯特林数的动态规划方法

c++ - 无法从 'int *' 转换为 'int []'?

c++ - 内存重新对齐后重新对齐指针

c++ - SSL_CTX_set_cipher_list() 没有影响

c - 使用重定向运算符 < 后检索标准输入

c++ - 处理 IDispatch 参数和 COM

C - 指针内存分配

C - 尝试创建一个 LinkedList 指针数组