qsort 不排序无符号长整型列表

qsort not sorting list of unsigned long ints

以下代码在尝试对一系列无符号长整数进行排序时会产生奇怪的结果。我不知道为什么。它编译无警告。问题出在我对 qsort 的使用上,但我已经对该行进行了几个小时的检查。我认为我的比较功能还可以。我已经尝试过半盲地尝试所有我能想到的排列,以确保我传递了正确的论点并且仍然没有骰子。任何帮助定位我的问题的帮助将不胜感激:

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

#define LENGTH 10

static int cmpfunc (const void *a, const void *b) {
    const unsigned long int x=*(const unsigned long int*)a, y=*(const unsigned long int*)b;
    printf("x=%lu ",x); printf("y=%lu ",y);
    if ( x==y ) {
        puts("returning 0..."); return 0;
    } else {
        if ( x>y ) {
            puts("returning 1..."); return 1;
        } else {
            puts("returning -1..."); return -1;
        }
    }
}

int main(void) {
    /* declare the storage for our "array". Using malloc instead of [] because in
       real program array size shall be dynamic */
    unsigned long int *mystorage=malloc(LENGTH*sizeof(unsigned long int)); /* check for NULL */

    /* fill up array with values in non-monotonic order and show the values */
    for(unsigned long int counter=0;counter<LENGTH;counter++) {
        *(mystorage+counter*sizeof(unsigned long int))=(unsigned long int)(counter*(LENGTH-counter));
        printf("value is %lu\n",*(mystorage+counter*sizeof(unsigned long int)));
    }

    /* sort array */
    qsort(mystorage, LENGTH, sizeof(unsigned long int), cmpfunc);

    /* print out array again to see if it changed */
    for(unsigned long int counter=0;counter<LENGTH;counter++) {
        printf("value is %lu\n",*(mystorage+counter*sizeof(unsigned long int)));
    }

    exit(EXIT_SUCCESS);
}
*(mystorage+counter*sizeof(unsigned long int))
     =
         (unsigned long int)(counter*(LENGTH-counter));

... 不正确。 (我稍微重新排列了你的空格。)它应该是

mystorage[counter] =
         counter*(LENGTH-counter); // the cast is redundant

下面三个是等价的:

mystorage[counter]
counter[mystorage]       // yes, this weird thing is equivalent
*(mystorage+counter)

将最后一行与您的代码进行比较。当您添加一个指针和一个整数时,编译器已经知道要移动正确的字节数。因为你包含了 sizeof 的东西,你有这两行等价的(与上面三行不同)

 *(mystorage + counter*sizeof(unsigned long int))
 mystorage[counter*sizeof(unsigned long int)]

应该清楚这两个将访问数组边界之外。

你的程序有部分错误

for(unsigned long int counter=0;counter<LENGTH;counter++) {
    *(mystorage+counter*sizeof(unsigned long int))=(unsigned long int)(counter*(LENGTH-counter));
    printf("value is %lu\n",*(mystorage+counter*sizeof(unsigned long int)));
}

当你向指针添加一些整数时,编译器会自动使用地址算法,所以你不应该使用*sizeof(unsigned long int)。打印循环中的相同错误。所以使用简单的索引 mystorage[counter]*(mystorage+counter)