繁体   English   中英

奇怪的 qsort 行为,怎么了?

[英]Weird qsort behavior, what's wrong?

为什么下面的代码不对月份名称进行排序? 基地址正确,元素数量正确,每个元素的大小正确, cmp function 正确。 gcc -W -Wall -ansi -pedantic一点也不抱怨。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int by_name(const void *a, const void *b) {
    fprintf(stderr, "%p %p\n", a, b);
    return strcmp((const char *)a, (const char *)b);
}
int main(void) {
    char *months[] = {
        "January",
        "Februar",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December"
    };
    unsigned n;

    qsort(months, sizeof months / sizeof *months, sizeof *months,
        by_name);
    for (n = 0; n < sizeof months / sizeof *months; ++n) {
        fprintf(stderr, "%d %p %s\n", n, months[n], months[n]);
    }
    return 0;
}

我添加了一些代码来查看 qsort 实际上在做什么,这是结果。 我们看到 qsort 传递给比较器 function 的地址与数组数据的实际位置完全不同。 怎么了?

我已经多次使用 qsort ,主要是对各种结构进行排序,但从来没有像这样原始(我需要解码一些非常愚蠢的日期时间字符串)。

0x1ffeffffb8 0x1ffeffffc0
0x1ffeffffb0 0x1ffeffffb8
0x1ffeffffd0 0x1ffeffffd8
0x1ffeffffc8 0x1ffeffffd0
0x1ffeffffb0 0x1ffeffffc8
0x1ffeffffb8 0x1ffeffffc8
0x1ffeffffc0 0x1ffeffffc8
0x1ffeffffe8 0x1ffefffff0
0x1ffeffffe0 0x1ffeffffe8
0x1fff000000 0x1fff000008
0x1ffefffff8 0x1fff000000
0x1ffeffffe0 0x1ffefffff8
0x1ffeffffe8 0x1ffefffff8
0x1ffefffff0 0x1ffefffff8
0x1ffeffffb0 0x1ffeffffe0
0x1ffeffffb8 0x1ffeffffe0
0x1ffeffffc0 0x1ffeffffe0
0x1ffeffffc8 0x1ffeffffe0
0x1ffeffffd0 0x1ffeffffe0
0x1ffeffffd8 0x1ffeffffe0
0 0x10a00b January
1 0x10a013 Februar
2 0x10a01b March
3 0x10a021 April
4 0x10a027 May
5 0x10a02b June
6 0x10a030 July
7 0x10a035 August
8 0x10a03c September
9 0x10a046 October
10 0x10a04e November
11 0x10a057 December

在比较中使用function下面的return语句

return strcmp( *(const char ** )a, *(const char **)b );

比较 function 获得指向数组元素的指针,这些元素又具有指针类型。

还要注意无符号变量n你应该使用格式转换说明符%u

这是您更新的程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int by_name(const void *a, const void *b) {
    return strcmp(*(const char **)a, *(const char **)b);
}
int main(void) {
    char *months[] = {
        "January",
        "Februar",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December"
    };
    unsigned n;

    qsort(months, sizeof months / sizeof *months, sizeof *months,
        by_name);
    for (n = 0; n < sizeof months / sizeof *months; ++n) {
        printf("%u %p %s\n", n, months[n], months[n]);
    }
    return 0;
}

它的 output 可能看起来像

0 0x56490a5b001a April
1 0x56490a5b002e August
2 0x56490a5b0050 December
3 0x56490a5b000c Februar
4 0x56490a5b0004 January
5 0x56490a5b0029 July
6 0x56490a5b0024 June
7 0x56490a5b0014 March
8 0x56490a5b0020 May
9 0x56490a5b0047 November
10 0x56490a5b003f October
11 0x56490a5b0035 September

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM