我在大多数情况下都是C ++程序员,但为了好玩,我试图在C中进行一些通用编程。特别是,我实现了一个通用的排序算法。我的功能的签名是
int sort(void *data,
size_t num_elems,
size_t elem_size,
int (*cmp)(const void*, const void*))
当我将其与标准库中的qsort()
进行比较时,我发现与我的函数不同,qsort()
没有返回值。由于对数组进行排序总是需要交换元素,因此实现需要大小为elem_size
的临时存储。由于C没有模板,因此在编译时不知道elem_size
,因此必须动态分配临时存储,这可能会失败。在这种情况下,qsort()
无法对数组进行排序,但它也无法报告错误,因此无法知道数组是否在返回时进行排序。
我在这里错过了什么吗?
答案 0 :(得分:4)
任何分区算法都需要能够交换两个元素,qsort
API意味着代码在编译时不知道它们有多大。但他们并不需要整体交换;它们可以一次交换一个字节。 (这实际上就是memcpy会做的事情。)
以下注释和宏位于Gnu libc实现中qsort.c
的开头。 (请注意,代码受LGPL约束)
/* Byte-wise swap two items of size SIZE. */
#define SWAP(a, b, size) \
do \
{ \
size_t __size = (size); \
char *__a = (a), *__b = (b); \
do \
{ \
char __tmp = *__a; \
*__a++ = *__b; \
*__b++ = __tmp; \
} while (--__size > 0); \
} while (0)
答案 1 :(得分:3)
函数不能失败 - 好吧,除非参数无效,在这种情况下它是未定义的行为,并且函数无论如何都无法可靠地检测到。
qsort
本身不分配任何内存。 (当然它可以做任何事情,但由于内存分配失败,它不允许失败,因此实现者必须考虑到这一点。)