C qsort奇怪的行为

时间:2017-05-01 18:00:52

标签: c sorting qsort

我试图执行以下操作:

  1. 为维度为7的数组分配内存
  2. 写下前4个职位
  3. 对这4个职位进行排序。
  4. 写下剩余的3个职位
  5. 对整个阵列进行排序。
  6. 我有数组(1,6,2,3),排序后变成(1,2,3,6)

    然后我写下剩余的位置,(1,2,3,6,1,5,1)

    排序后,我应该(1,1,1,2,3,5,6),但我得到了 (6,2,3,1,1,5,1)

    以下是代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int comp(const void* a, const void* b);
    
    typedef struct{
    
        int peso;
     }aresta_;
    
    int main(int argc, const char * argv[]) {
    
        aresta_* array /*struct array, has field peso of type int*/;
        int dim=7;
        int dim_aux=4;
        int i;
    
        array = (aresta_*) malloc(dim * sizeof(aresta_));
    
        array[0].peso=1;
        array[1].peso=6;
        array[2].peso=2;
        array[3].peso=3;
    
    
        printf("First sort:\n");
        for(i=0; i<dim_aux; i++)
            printf("%d ",array[i].peso);
    
        printf("\n");
    
    
        qsort(array, dim_aux, sizeof(array[0]), comp);
    
    
        for(i=0; i<dim_aux; i++)
            printf("%d ",array[i].peso);
    
        printf("\n\n");
    
        array[4].peso=1;
        array[5].peso=5;
        array[6].peso=1;
    
        printf("Second sort:\n");
    
    
        for(i=0; i<dim; i++)
            printf("%d ",array[i].peso);
    
        printf("\n");
    
        qsort(array, dim, sizeof(array[0]), comp);
    
        for(i=0; i<dim; i++)
            printf("%d ",array[i].peso);
    
    
    
    
        printf("\n");
    
    }
    

    我的comp功能:

    int comp(const void* a, const void* b)
    {
        aresta_* a1 = (aresta_*)a;
        aresta_* b1 = (aresta_*)b;
        return a1->peso > b1->peso;
    }
    

    输出:

    First sort:
    1 6 2 3 
    1 2 3 6 
    
    Second sort:
    1 2 3 6 1 5 1 
    6 2 3 1 1 5 1 
    Program ended with exit code: 0
    

    我哪里出错了?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:4)

OP的功能仅返回0和1. @Weather Vane

因为前4个值的OP“工作”是“运气”。

比较函数需要返回3个结果中的1个:负数,0或正数。

  

如果第一个参数被认为分别小于,等于或大于第二个参数,则该函数应返回小于,等于或大于零的整数。
  C11dr§7.22.5.23

char **

int comp(const void* a, const void* b) { const aresta_* a1 = (const aresta_*)a; const aresta_* b1 = (const aresta_*)b; // return a1->peso > b1->peso; return (a1->peso > b1->peso) - (a1->peso < b1->peso); } 优于return (a1->peso > b1->peso) - (a1->peso < b1->peso);。这个答案不会溢出。它对所有return a1->peso - b1->peso;对都有效且功能正确。各种编译器都认识到这个习惯用法并产生严密的代码。 int可能会溢出未定义的行为,UB。

答案 1 :(得分:0)

int comp(const void* a, const void* b)
{
    aresta_* a1 = (aresta_*)a;
    aresta_* b1 = (aresta_*)b;
    ---->   return a1->peso > b1->peso;  <---- Watch carefully out! What it does!
}

回程线只是检查更大或没有。如果

  • a1->peso更高,返回1
  • b1->peso更大,它返回0(它也不是正确的结果,因为零必须意味着相等
  • 值相等的相等情况怎么样?

您没有检查最后一个案例。要做,你可以写if-else案例,如

if(a1->peso > b1->peso) {
//  ....
} else if (a1->peso < b1->peso) {
// ....
} else {
// equality case....
}

或只是做return a1->peso - b1->peso给出预期的结果

  • > 0如此积极
  • < 0如此否定
  • == 0彼此如此相等

根据chux很好地提醒注意溢出点,可以处理溢出情况。

#include <limits.h>

if ((b1->peso > 0 && a1->peso < INT_MIN + b1->peso) ||
      (b1->peso < 0 && a1->peso > INT_MAX + b1->peso)) {
    /* Handle error */
} else {
    return a1->peso - b1->peso;
}