在 btrlib 上使用 qsort()/qsort_r() 无效
Using qsort()/qsort_r() on btrlib didn't work
我正在尝试使用 C 标准库 qsort()
函数对一个
bstring 的数组并没有工作,
根据 bstrlib:
typedef struct tagbstring * bstring;
typedef const struct tagbstring * const_bstring;
我的比较器回调是:
int cmp_bstring(const void *a, const void *b, void *unused) {
(void)unused;
return bstrcmp((const_bstring)a, (const bstring)b);
}
```c
then i setup some simple code to test, call `qsort\_r()` on this data and the array
remains unsorted:
```c
bstring strings[] = {
bfromcstr("Three"),
bfromcstr("One"),
bfromcstr("Two"),
};
printf("-- Unordered Array --\n");
print_array(strings, SizeArray(strings));
qsort_r(strings, SizeArray(strings), sizeof(bstring), cmp_bstring, NULL);
printf("\n-- Ordered Array --\n");
print_array(strings, SizeArray(strings));
}
完整代码为:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include "bstrlib.h"
#define SizeArray(arr) (sizeof((arr)) / sizeof((arr)[0]))
int cmp_bstring(const void *a, const void *b, void *unused) {
(void)unused;
return bstrcmp((const_bstring)a, (const bstring)b);
}
void print_array(bstring array[], unsigned array_len) {
for (unsigned i=0; i < array_len; i++)
printf("[%d] = %s\n", i, array[i]->data);
}
int main(void) {
bstring strings[] = {
bfromcstr("Three"),
bfromcstr("One"),
bfromcstr("Two"),
};
printf("-- Unordered Array --\n");
print_array(strings, SizeArray(strings));
qsort_r(strings, SizeArray(strings), sizeof(bstring), cmp_bstring, NULL);
printf("\n-- Ordered Array --\n");
print_array(strings, SizeArray(strings));
}
预期输出为:
-- Unordered Array --
[0] = Three
[1] = One
[2] = Two
-- Ordered Array --
[0] = One
[2] = Three
[3] = Two
但我得到:
-- Unordered Array --
[0] = Three
[1] = One
[2] = Two
-- Ordered Array --
[0] = Three
[1] = One
[2] = Two
顺便说一句,为什么 SizeArray
宏在我将它用于 print_array()
时不起作用
函数 (returns 1),并从 main()
returns 正确的数组大小?
在 Linux
上使用 GCC 构建
您对间接级别感到困惑。假装你不知道bstring
的定义,尤其是你不知道它是一个指针类型。那么您认为将指针转换为 bstring
s 有意义吗?
qsort()
的比较函数接收 指向 被比较值的指针,而不是值本身。因此,您似乎在寻找这种变体:
int cmp_bstring(const void *a, const void *b, void *unused) {
(void)unused;
return bstrcmp(*(const_bstring *)a, *(const bstring *)b);
}
我正在尝试使用 C 标准库 qsort()
函数对一个
bstring 的数组并没有工作,
根据 bstrlib:
typedef struct tagbstring * bstring;
typedef const struct tagbstring * const_bstring;
我的比较器回调是:
int cmp_bstring(const void *a, const void *b, void *unused) {
(void)unused;
return bstrcmp((const_bstring)a, (const bstring)b);
}
```c
then i setup some simple code to test, call `qsort\_r()` on this data and the array
remains unsorted:
```c
bstring strings[] = {
bfromcstr("Three"),
bfromcstr("One"),
bfromcstr("Two"),
};
printf("-- Unordered Array --\n");
print_array(strings, SizeArray(strings));
qsort_r(strings, SizeArray(strings), sizeof(bstring), cmp_bstring, NULL);
printf("\n-- Ordered Array --\n");
print_array(strings, SizeArray(strings));
}
完整代码为:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include "bstrlib.h"
#define SizeArray(arr) (sizeof((arr)) / sizeof((arr)[0]))
int cmp_bstring(const void *a, const void *b, void *unused) {
(void)unused;
return bstrcmp((const_bstring)a, (const bstring)b);
}
void print_array(bstring array[], unsigned array_len) {
for (unsigned i=0; i < array_len; i++)
printf("[%d] = %s\n", i, array[i]->data);
}
int main(void) {
bstring strings[] = {
bfromcstr("Three"),
bfromcstr("One"),
bfromcstr("Two"),
};
printf("-- Unordered Array --\n");
print_array(strings, SizeArray(strings));
qsort_r(strings, SizeArray(strings), sizeof(bstring), cmp_bstring, NULL);
printf("\n-- Ordered Array --\n");
print_array(strings, SizeArray(strings));
}
预期输出为:
-- Unordered Array --
[0] = Three
[1] = One
[2] = Two
-- Ordered Array --
[0] = One
[2] = Three
[3] = Two
但我得到:
-- Unordered Array --
[0] = Three
[1] = One
[2] = Two
-- Ordered Array --
[0] = Three
[1] = One
[2] = Two
顺便说一句,为什么 SizeArray
宏在我将它用于 print_array()
时不起作用
函数 (returns 1),并从 main()
returns 正确的数组大小?
在 Linux
上使用 GCC 构建您对间接级别感到困惑。假装你不知道bstring
的定义,尤其是你不知道它是一个指针类型。那么您认为将指针转换为 bstring
s 有意义吗?
qsort()
的比较函数接收 指向 被比较值的指针,而不是值本身。因此,您似乎在寻找这种变体:
int cmp_bstring(const void *a, const void *b, void *unused) {
(void)unused;
return bstrcmp(*(const_bstring *)a, *(const bstring *)b);
}