C语言 你能对数组的一部分进行qsort吗?

hgb9j2n6  于 2023-04-05  发布在  其他
关注(0)|答案(2)|浏览(195)

我想qsort一个整数数组的前100个元素,其余的元素保持不变。
我目前正在尝试通过以下调用来实现这一点:

int cmpfunc(const void *a, const void *b)
{
  int xi = *(const int *) a;
  int yi = *(const int *) b;
  
  return (xi - yi);
}

int my_array[100+some_size];
memset(my_array, 0, sizeof(my_array));
qsort(my_array, 100, sizeof(int), cmpfunc);

然而,我得到了一个分段错误。在C中对数组的第一个x值进行排序可能吗?

63lcw9qa

63lcw9qa1#

qsort函数的Angular 来看,在前100个元素之后是否有更多的数组元素没有区别,因为它只获得指向数组开始的指针,以及开始指针之后的元素数量。
所以,是的,假设可以对一个有100个元素的数组进行排序,也可以对一个更大的数组的前100个元素进行排序。

c0vxltue

c0vxltue2#

您可以对数组的任何部分进行排序,该数组正确地提供指向元素排序范围的初始元素的指针以及该范围中的元素数。
至于你的问题,那么它的原因可能是整数溢出,导致未定义的行为产生的比较函数

int cmpfunc(const void *a, const void *b)
{
  int xi = *(const int *) a;
  int yi = *(const int *) b;
  
  return (xi - yi);
}

在return语句中。
下面是一个简单的例子。假设xi等于INT_MAXyi等于-1。那么表达式xi - yi会导致整数溢出,例如它的值可能是负值,而实际上函数应该返回一个正数,因为xi大于yi
也就是说,在任何情况下,比较函数都是错误的。
您应该按以下方式重写比较函数

int cmpfunc(const void *a, const void *b)
{
  int xi = *(const int *) a;
  int yi = *(const int *) b;
  
  return ( yi < xi ) - ( xi < yi );;
}

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int cmpfunc(const void *a, const void *b)
{
  int xi = *(const int *) a;
  int yi = *(const int *) b;
  
  return ( yi < xi ) - ( xi < yi );;
}

int main( void ) 
{
    int a[] = { INT_MAX, INT_MAX - 1, INT_MAX - 2, -1, -2, 10, 9, 8, 7, 6 };
    const size_t N = sizeof( a ) / sizeof( *a );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    size_t n = N / 2;
    qsort( a, n, sizeof( int ), cmpfunc );

    for ( size_t i = 0; i < n; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    qsort( a + n, N - n, sizeof( int ), cmpfunc );

    for ( size_t i = n; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
}

程序输出为

2147483647 2147483646 2147483645 -1 -2 10 9 8 7 6 
-2 -1 2147483645 2147483646 2147483647 
6 7 8 9 10 
-2 -1 2147483645 2147483646 2147483647 6 7 8 9 10

如果你尝试在演示程序中使用你的比较函数,那么至少你会得到一个不正确的结果。
例如,使用内联编译器,我得到以下输出

2147483647 2147483646 2147483645 -1 -2 10 9 8 7 6 
2147483646 2147483647 -2 -1 2147483645 
6 7 8 9 10 
2147483646 2147483647 -2 -1 2147483645 6 7 8 9 10

正如你所看到的,数组的第一部分排序不正确。

相关问题