【问题标题】:Warning while sorting a 2D array with qsort使用 qsort 对二维数组进行排序时出现警告
【发布时间】:2013-09-27 15:39:02
【问题描述】:

我正在尝试使用 qsort 对 C 中的二维数组进行排序。排序有效,但我收到警告:

warning: initialization discards 'const' qualifier from pointer target type [enabled by default]

如何修改我的比较函数以消除警告(鉴于qsort 需要参数const void *pa, const void *pb

int cmp (const void *pa, const void *pb ) {
  const int (*a)[2] = pa; // warning here
  const int (*b)[2] = pb; // warning here
  if ( (*a)[1] < (*b)[1] ) return 1;
  if ( (*a)[1] > (*b)[1] ) return -1;
  return 0;
}

我在 Stack Overflow 上阅读了 this post,但我仍然不确定应该如何更改比较函数。

我有一个如下所示的数组:

int letterCount[26][2] = {{0, 0},{1, 0},{2, 0},{3, 0},{4, 0},{5, 0},{6, 0},{7, 0},{8, 0},{9, 0},{10, 0},{11, 0},{12, 0},{13, 0},{14, 0},{15, 0},{16, 0},{17, 0},{18, 0},{19, 0},{20, 0},{21, 0},{22, 0},{23, 0},{24, 0},{25, 0}};

除了在第二列中,那些不是零,而是用其他数字填充。在填充 0 之后,我正在尝试按第二列对这个二维数组进行排序。

【问题讨论】:

    标签: c pointers qsort


    【解决方案1】:

    (*a)[2] 应该做什么? 您似乎在声明中取消引用指向数组的指针。 由于缺乏更好的事情可做,我写了自己的版本,希望对您有所帮助:

    #include <time.h>
    #include <stdio.h>
        void Qsort(int matrix[][2] , int lenght)
        {
            if(!lenght)
                    return;
            int temp = 0 , pivot , b = 0 , e = lenght - 1 , test = 0;
            const int MIN =0 , MAX = e;
            srand(time(NULL));
            test = (rand() % (MAX - MIN + 1)) + MIN;
            pivot = matrix[test][1];
            while(b < e)
            {
                while(matrix[b][1] < pivot)
                    b++;
                while(matrix[e][1] > pivot)
                    e--;
                temp = matrix[b][1];
                matrix[b][1] = matrix[e][1];
                matrix[e][1] = temp;
            }
            Qsort(matrix , b);
            Qsort(&(matrix)[b + 1] , lenght - 1 - b);
    
        }
    

    【讨论】:

    • 目标是按第二列对二维数组进行排序
    • 你想在这些行中做什么
    • 创建一个大小为 2 的数组,(因为我正在对一个二维数组进行排序),然后比较每个数组的第二个元素
    【解决方案2】:

    你可以玩弄decls,但最后我认为这对于你正在使用的比较器来说已经足够了:

    int cmp (const void *pa, const void *pb )
    {
        const int *a = pa;
        const int *b = pb;
        if (a[1] < b[1]) 
            return -1;
        return (b[1] < a[1]);
    }
    

    您的数据“项目”只不过是二维数组中的int[] 偏移量。如果这是一个 pointer 数组而不是真正的 2D 数组,这将有很大不同。 Grijesh 非常接近这一点,只缺少[1] 偏移量(和简单的数学运算),如果他取消删除他的答案来修复它,我会放弃这个。

    【讨论】:

    • 请注意,如果数组中的值非常大且符号相反,则使用这样的减法会有溢出和随之而来的未定义行为的风险。在实践中,这通常不是问题,但要小心。使用return (a[1] &gt; b[1]) - (b[1] &gt; a[1]); 或附近获得-1、0 或+1 有一个技巧。或者您可以使用等效但更清晰的方式:if (a[1] &gt; b[1]) return +1; else if (a[1] &lt; b[1]) return -1; else return 0;(它甚至可能更有效,因为它仅有条件地计算第二次比较)。
    • 为什么分配const int (*a)[2] = pa; 会发出警告?