这个 C 语法是什么意思?
这是来自我正在使用的“神奇”数组库。
void
sort(magic_list *l, int (*compare)(const void **a, const void **b))
{
qsort(l->list, l->num_used, sizeof(void*),
(int (*)(const void *,const void *))compare);
}
我的问题是: qsort 的最后一个参数到底在做什么?
(int (*)(const void *, const void*))compare)
qsort 采用 int (*comp_fn)(const void *,const void *)
因为它是比较器参数,但此排序函数采用带有双指针的比较器。不知何故,上面的行将双指针版本转换为单指针版本。有人可以帮忙解释一下吗?
This is from a 'magic' array library that I'm using.
void
sort(magic_list *l, int (*compare)(const void **a, const void **b))
{
qsort(l->list, l->num_used, sizeof(void*),
(int (*)(const void *,const void *))compare);
}
My question is: what on earth is the last argument to qsort doing?
(int (*)(const void *, const void*))compare)
qsort takes int (*comp_fn)(const void *,const void *)
as it's comparator argument, but this sort function takes a comparator with double pointers. Somehow, the line above converts the double pointer version to a single pointer version. Can someone help explain?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这正是您引用的强制转换的作用:它将类型的指针转换
为类型的指针,
后者是
qsort
所期望的。在质量较差的代码中经常会遇到类似的情况。例如,当有人想要对
int
数组进行排序时,他们通常会编写一个比较函数来接受指向int *
的指针,并且当需要实际调用
>qsort
他们强制将其转换为正确的类型以抑制编译器的抱怨这是一种“黑客”,会导致未定义的行为。显然,这是一种不好的做法。您在示例中看到的只是同一“黑客”的不太直接的版本。
在这种情况下,正确的方法是将比较函数声明为
,然后在不进行任何强制转换的情况下使用它。
一般来说,如果希望将它们的比较函数用作 qsort(以及类似函数)中的比较器,应该使用 const void * 参数来实现它们。
That's exactly what the cast you quoted does: it converts a pointer of type
to a pointer of type
The latter is what is expected by
qsort
.Thing like this are encountered rather often in bad quality code. For example, when someone wants to sort an array of
int
s, they often write a comparison function that accepts pointers toint *
and when the time comes to actually call
qsort
they forcefully cast it to the proper type to suppress the compiler's complaintsThis is a "hack", which leads to undefined behavior. It is, obviously, a bad practice. What you see in your example is just a less direct version of the same "hack".
The proper approach in such cases would be to declare the comparison function as
and then use it without any casts
In general, if one expects their comparison functions to be used as comparators in
qsort
(and similar functions), one should implemnent them withconst void *
parameters.qsort 的最后一个参数是将采用双指针的函数指针转换为采用 qsort 将接受的单指针的函数指针。这只是一个演员阵容。
The last argument to qsort is casting a function pointer taking double pointers, to one taking single pointers that qsort will accept. It's simply a cast.
在大多数硬件上,您可以假设指针在硬件级别上看起来都是相同的。例如,在具有平面 64 位寻址指针的系统中,指针将始终是 64 位整数。对于指针到指针或指针到指针到指针的指针也是如此。
因此,无论使用什么方法来调用带有两个指针的函数,都适用于任何带有两个指针的函数。指针的具体类型并不重要。
qsort
一般地对待指针,就好像每个指针都是不透明的一样。所以它不知道也不关心它们是如何取消引用的。它知道它们当前的顺序,并使用比较参数来计算出它们应该采用的顺序。您使用的库大概保留了指向指针的指针列表。它有一个比较函数,可以比较两个指针与指针。因此它会将其传递给 qsort。它只是在语法上比例如更好
On most hardware you can assume that pointers all look the same at the hardware level. For example, in a system with flat 64bit addressing pointers will always be a 64bit integer quantity. The same is true of pointers to pointers or pointers to pointers to pointers to pointers.
Therefore, whatever method is used to invoke a function with two pointers will work with any function that takes two pointers. The specific type of the pointers doesn't matter.
qsort
treats pointers generically, as though each is opaque. So it doesn't know or care how they're dereferenced. It knows what order they're currently in and uses the compare argument to work out what order they should be in.The library you're using presumably keeps lists of pointers to pointers about. It has a compare function that can compare two pointers to pointers. So it casts that across to pass to qsort. It's just syntactically nicer than, e.g.
它正在转换一个函数指针。我想原因是比较可以应用于取消引用的指针,而不是它们指向的任何指针。
It is casting a function pointer. I imagine that the reason is so that compare can be applied to the pointers that are dereferenced rather than whatever they are pointing to.
(int (*)(const void *,const void *))compare
是一种 C 风格转换,用于将函数指针compare
转换为具有两个的函数指针const void *
参数。(int (*)(const void *,const void *))compare
is a C style cast to cast the function pointercompare
to a function pointer with twoconst void *
args.最后一个参数是函数指针。它指定它接受一个指向返回 int 的函数的指针,并接受两个 const void ** 参数。
The last argument is a function pointer. It specifies that it takes a pointer to a function that returns an int and takes two
const void **
arguments.