gpt4 book ai didi

c - 与 qsort 相比,可重入 qsort_r 函数的可移植性如何?

转载 作者:太空狗 更新时间:2023-10-29 16:51:57 26 4
gpt4 key购买 nike

qsort_r()qsort() 的可重入版本,它带有一个额外的“thunk”参数并将其传递给比较函数,我想能够在可移植的 C 代码中使用它。 qsort() 是 POSIX 并且无处不在,但 qsort_r() 似乎是 BSD 扩展。作为一个具体问题,这在 Windows C 运行时中是否存在或具有等效项?

最佳答案

我尝试编写一个可移植版本的 qsort_r/qsort_s(称为 sort_r),并附有示例。我还将此代码放入 git repo ( https://github.com/noporpoise/sort_r )

struct sort_r_data
{
void *arg;
int (*compar)(const void *a1, const void *a2, void *aarg);
};

int sort_r_arg_swap(void *s, const void *aa, const void *bb)
{
struct sort_r_data *ss = (struct sort_r_data*)s;
return (ss->compar)(aa, bb, ss->arg);
}

void sort_r(void *base, size_t nel, size_t width,
int (*compar)(const void *a1, const void *a2, void *aarg), void *arg)
{
#if (defined _GNU_SOURCE || defined __GNU__ || defined __linux__)

qsort_r(base, nel, width, compar, arg);

#elif (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || \
defined __FREEBSD__ || defined __BSD__ || \
defined OpenBSD3_1 || defined OpenBSD3_9)

struct sort_r_data tmp;
tmp.arg = arg;
tmp.compar = compar;
qsort_r(base, nel, width, &tmp, &sort_r_arg_swap);

#elif (defined _WIN32 || defined _WIN64 || defined __WINDOWS__)

struct sort_r_data tmp = {arg, compar};
qsort_s(*base, nel, width, &sort_r_arg_swap, &tmp);

#else
#error Cannot detect operating system
#endif
}

示例用法:

#include <stdio.h>

/* comparison function to sort an array of int, inverting a given region
`arg` should be of type int[2], with the elements
representing the start and end of the region to invert (inclusive) */
int sort_r_cmp(const void *aa, const void *bb, void *arg)
{
const int *a = aa, *b = bb, *p = arg;
int cmp = *a - *b;
int inv_start = p[0], inv_end = p[1];
char norm = (*a < inv_start || *a > inv_end || *b < inv_start || *b > inv_end);
return norm ? cmp : -cmp;
}

int main()
{
/* sort 1..19, 30..20, 30..100 */
int arr[18] = {1, 5, 28, 4, 3, 2, 10, 20, 18, 25, 21, 29, 34, 35, 14, 100, 27, 19};
/* Region to invert: 20-30 (inclusive) */
int p[] = {20, 30};
sort_r(arr, 18, sizeof(int), sort_r_cmp, p);

int i;
for(i = 0; i < 18; i++) printf(" %i", arr[i]);
printf("\n");
}

编译/运行/输出:

$ gcc -Wall -Wextra -pedantic -o sort_r sort_r.c
$ ./sort_r
1 2 3 4 5 10 14 18 19 29 28 27 25 21 20 34 35 100

我已经在 mac 和 linux 上测试过。如果您发现错误/改进,请更新此代码。您可以随意使用此代码。

关于c - 与 qsort 相比,可重入 qsort_r 函数的可移植性如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4300896/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com