Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C qsort()比较结构数组:非常奇怪的行为_C_Arrays_Struct_Qsort - Fatal编程技术网

C qsort()比较结构数组:非常奇怪的行为

C qsort()比较结构数组:非常奇怪的行为,c,arrays,struct,qsort,C,Arrays,Struct,Qsort,我试图通过增加一个字段(双倍数字)对结构数组进行排序,但qsort()似乎以某种方式破坏了该数组中的数据(在调用显示字段中填充了一些随机值后打印出数组)。此外,如果我将comparator更改为按后代顺序对数组进行排序,qsort不会再破坏数据,但也不会对数组进行排序—在调用之后,一切都是一样的。 这个小程序演示了这个问题: #include <stdio.h> #include <stdlib.h> #include <math.h> #include &l

我试图通过增加一个字段(双倍数字)对结构数组进行排序,但qsort()似乎以某种方式破坏了该数组中的数据(在调用显示字段中填充了一些随机值后打印出数组)。此外,如果我将comparator更改为按后代顺序对数组进行排序,qsort不会再破坏数据,但也不会对数组进行排序—在调用之后,一切都是一样的。 这个小程序演示了这个问题:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

/* Macro for comparing floats. */
#define CMP_PREC 0.000001
#define dbl_eq(x, y) (fabs((x) - (y)) < CMP_PREC)

/* Structure for testing. */
struct level {
    double alt;
    double volume;
    double area;
};

/* Create array of levels with random alts. 
 * (Other fields are unimportant for this demo). */
struct level *create_random_arr(size_t size) {
    size_t i;
    struct level *lev = NULL;
    lev = calloc(sizeof(*lev), size);
    srand(time(NULL));
    for (i = 0; i < size; i++) {
        lev[i].alt = (double) rand() / 1000.0;
        lev[i].volume = lev[i].area = 0.0;
    }
    return lev;
}

/* Prints array in format:
 * [index]: alt=[alt], volume=[volume], area=[area]\n */
void print_levels(struct level *lev, int lev_cnt) {
    int i;
    for (i = 0; i < lev_cnt; i++) {
        printf("%d: alt=%g, volume=%g, area=%g\n",
            i, lev[i].alt, lev[i].volume, lev[i].area);
    }
}

/* Comparator for sorting by increasing of alt. */
static int levels_compar(const void *a, const void *b) {
    const struct level *al = (const struct level *) a;
    const struct level *bl = (const struct level *) b;
    if dbl_eq(al->alt, bl->alt) {
        return 0;
    } else if (al->alt < bl->alt) {
        return -1;
    } else {
        return 1;
    }
}

int main(void) {
    int size = 10;
    struct level *lev = NULL;
    lev = create_random_arr(size);
    /* Print generated array. */
    print_levels(lev, size);
    /* Sort array by increase. */
    qsort(lev, sizeof(*lev), size, levels_compar);
    /* Print result... very surprising, isn't it? */
    printf("----------\n");
    print_levels(lev, size);
    free(lev);
    return 0;
}
#包括
#包括
#包括
#包括
/*用于比较浮动的宏*/
#定义CMP_PREC 0.000001
#定义dbl_eq(x,y)(晶圆厂((x)-(y))alt,bl->alt){
返回0;
}否则如果(al->altalt){
返回-1;
}否则{
返回1;
}
}
内部主(空){
int size=10;
结构级别*lev=NULL;
lev=创建随机数组(大小);
/*打印生成的数组*/
打印水平(水平、大小);
/*按递增对数组进行排序*/
qsort(lev,sizeof(*lev),大小,级别\u比较);
/*打印结果…非常令人惊讶,不是吗*/
printf(“------------\n”);
打印水平(水平、大小);
免费(lev);
返回0;
}
#定义dbl_等式(x,y)((x)-(y)
我认为这不是正确的比较方法。绝对值应按如下方式进行比较:

#define dbl_eq(x, y) (fabs((x) - (y)) < CMP_PREC)
定义dbl_eq(x,y)(晶圆厂((x)-(y))
您已经将元素的数量和元素参数的大小混合到
qsort
。它的工作原理如下:

qsort(lev, size, sizeof(*lev), levels_compar);

如上所述,您还应该在比较宏中使用
fabs
。我真的不认为你需要排序的容忍度比较,但是,因为你不是真的在寻找平等,而是一个升序。我只想使用
=
并将其作为最后一个分支,因为它实际上从未发生过。

您在qsort中切换的参数应该是:

 qsort(lev, size , sizeof(struct level) , levels_compar);

我将
*lev
替换为
struct-level
,因为我认为它更利于代码的可读性。

当然可以。我在准备问题代码时犯了这个错误。我现在将更改问题中的代码,但问题仍然存在。在检查计算结果是否相等时,不应将浮点值与
=
进行比较。在本例中,我们不是检查相等性,而是检查序列。当数组中的值应该被切换时,带有公差的检查实际上会使值稍微偏离顺序,因为一个值比另一个值小,但在公差范围内,但由于两个值被认为相等,所以不会被切换。一般来说,将浮动与公差进行比较是一个很好的建议,但我认为这是一个误导。(而且,这个建议往往会导致从空气中抽离公差。)我不同意你的更换
sizeof*lev
与lev
所指向的类型无关,并且在类型的更改中具有健壮性。如果类型发生更改,并且编译器无法自动为您诊断,则对类型进行硬编码将导致严重的破坏(与OP所经历的情况相当)。@R.使用struct,您可以通过编译器错误立即看到您刚刚破坏了多少代码(在什么范围内)。现在,字符串查找/替换不是很难。可读性>懒散不,你没有。有了struct,您就不会出现任何错误,而且在运行时也不会出现错误。使用我推荐的OP版本(订单固定),代码会自动运行。@R。。如果代码正确,当然会出现错误。同样,懒惰也会带来运行时问题。如果将
lev
的类型从
struct-level*
更改为
struct-level\u-ex*
,您的代码仍会编译得非常好,没有任何警告或错误,但在运行时会严重崩溃(通过调用未定义的行为)。
 qsort(lev, size , sizeof(struct level) , levels_compar);