C如何使用带有比较器功能的快速排序

C如何使用带有比较器功能的快速排序,c,pointers,quicksort,qsort,C,Pointers,Quicksort,Qsort,我试图理解这个比较器函数的前几行发生了什么stringAsInt(const void*pLeft,const void*pRight) 所以这些参数是某些东西的常量指针。然后在接下来的两行中,我们将void转换为(const char**)为什么要转换为指针的指针?还有,这两行到底是怎么回事 在main()函数中调用qsort()时,为什么没有参数被传递到stringAsInt()?stringAsInt()如何知道pLeft和pRight是什么 为什么将a设置为指针的指针?一个标准数组不够吗

我试图理解这个比较器函数的前几行发生了什么
stringAsInt(const void*pLeft,const void*pRight)

  • 所以这些参数是某些东西的常量指针。然后在接下来的两行中,我们将void转换为
    (const char**)
    为什么要转换为指针的指针?还有,这两行到底是怎么回事
  • main()
    函数中调用
    qsort()
    时,为什么没有参数被传递到
    stringAsInt()
    stringAsInt()
    如何知道
    pLeft
    pRight
    是什么
  • 为什么将
    a
    设置为指针的指针?一个标准数组不够吗
  • -

    int-stringAsInt(const-void*pLeft,const-void*pRight){
    常量字符*左=*(常量字符**)左;
    常量字符*右=*(常量字符**)右;
    int leftLen=(int)strlen(左);
    int rightLen=(int)strlen(右);
    如果(leftLen!=rightLen){
    返回leftLen-rightLen;
    }否则{
    返回strcmp(左、右);
    }
    }
    int main(){
    int n;
    scanf(“%d”和“&n”);
    字符缓冲区[1000000+1];
    char**a=malloc(sizeof(char*)*(size\u t)n);
    对于(int i=0;i
    所以这些参数是某些东西的常量指针。然后在接下来的两行中,我们将把空转换为(const char**),为什么要将它转换为指针的指针?还有,这两行到底是怎么回事

    它是C中的类型擦除。qsort不知道数组元素有什么类型,它只知道它们的大小,并将单个元素作为类型擦除的指针传递给比较器以使其无效,期望比较器将指针强制转换为所需的类型。这正是在这两条线上发生的事情。字符串数组简单地组织为指向char的指针数组(字符串的传统C习惯用法)。数组的每个元素都是指向字符的指针(实际上,指向连续字符序列中的第一个)。qsort将类型擦除的指针传递给这些指针,comparator将它们向下转换回具体类型

    在main()函数中调用qsort()时,为什么没有参数传递给stringAsInt()?stringAsInt()如何知道pLeft和pRight是什么

    它是指向函数的指针。qsort的最后一个参数是函数指针。然后,它调用此函数来比较各个元素对,每次都为pLeft和pRight提供值

    为什么要将指针设置为指针的指针?一个标准数组不够吗


    如果您确实知道您的文件不是很大,那么可能是这样。如果它由数以百万计的字符串组成,由于该站点URI的二级域,程序可能会崩溃,因此他们决定将整个数组放在堆上。

    注释中的代码分解

    //
    //  main.c
    //
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    //Takes a pointer to any type.. (void *)
    int stringAsInt(const void *pLeft, const void *pRight) {
        //qsort calls this function with a pointer to each element. Since each element is a char* then pLeft is actually a char**.
        //For example, if sorting an array of ints (each element is of type: int), pLeft would be int*.
        //If sorting an array of strings (each element is of type: char*), pLeft would be char**.
        //So on and so forth.
    
    
        //Thus we cast the pLeft to its correct type (const char**) for pointer to string.. Then we dereference it to get the string itself (const char*).
        const char *left = *(const char**)pLeft;
        const char *right = *(const char**)pRight;
    
        int leftLen = (int)strlen(left);
        int rightLen = (int)strlen(right);
    
        //Compare the lengths of the strings.. If left is < right, we return negative. If they are the same, 0.. else positive..
        if (leftLen != rightLen) {
            return leftLen - rightLen;
        } else {
            return strcmp(left, right);  //Lengths are equal.. compare their contents..
        }
    }
    
    int main() {
        int n;
    
        //First the code takes an array count.. This is the amount of arrays to sort..
        printf("Enter number of strings: ");
        scanf("%d", &n);
    
        //It allocates a large buffer on the stack to hold entire sentences to sort..
        char buffer[1000000 + 1];
    
        //Allocates an array of strings..
        char **a = malloc(sizeof(char*) * (size_t)n);
    
        for (int i = 0; i < n; i++) {
            printf("Enter a string: ");
            scanf("%1000000s", buffer);
    
            //Store each string in the array..
            a[i] = malloc(sizeof(char) * (strlen(buffer) + 1));
            strcpy(a[i], buffer);
        }
    
        //Sort the array using stringAsInt comparator..
        //a is the array to sort.
        //n is the amount of elements in the array.
        //sizeof(a[0]) is the size of each element in the array. sizeof(char*).
        //stringAsInt is the comparator function (pointer to function)..
    
        qsort(a, (size_t)n, sizeof(a[0]), stringAsInt);
    
        //Print the sorted array and cleanup each element.
        for (int i = 0; i < n; i++) {
            printf("%s\n", a[i]);
            free(a[i]);
        }
    
        //Cleanup the array itself.
        free(a);
        return 0;
    }
    
    //
    //main.c
    //
    #包括
    #包括
    #包括
    //接受指向任何类型的指针。。(无效*)
    int stringAsInt(常量无效*pLeft,常量无效*pRight){
    //qsort使用指向每个元素的指针调用此函数。因为每个元素都是char*,所以pLeft实际上是char**。
    //例如,如果对int数组进行排序(每个元素的类型为:int),则pLeft将是int*。
    //如果对字符串数组进行排序(每个元素的类型为:char*),则pLeft将是char**。
    //诸如此类。
    //因此,我们将pLeft转换为指向字符串的指针的正确类型(const char**)。然后取消引用它以获得字符串本身(const char*)。
    常量字符*左=*(常量字符**)左;
    常量字符*右=*(常量字符**)右;
    int leftLen=(int)strlen(左);
    int rightLen=(int)strlen(右);
    //比较字符串的长度。如果left小于right,则返回负值。如果它们相同,则返回0。否则返回正值。。
    如果(leftLen!=rightLen){
    返回leftLen-rightLen;
    }否则{
    return strcmp(左、右);//长度相等..比较它们的内容。。
    }
    }
    int main(){
    int n;
    //首先,代码获取数组计数。这是要排序的数组数量。。
    printf(“输入字符串数:”);
    scanf(“%d”和“&n”);
    //它在堆栈上分配了一个大的缓冲区来保存整个句子进行排序。。
    字符缓冲区[1000000+1];
    //分配字符串数组。。
    char**a=malloc(sizeof(char*)*(size\u t)n);
    对于(int i=0;i
  • stringAsInt中的强制转换是因为qsort()使用const void*参数调用comparator函数。然而,为了进行比较,比较器需要引用它们所指向的实际结构,因此它将强制转换为正确类型的常量指针
  • 在本例中,正确的类型是指向char的指针,因为字符串是char*,而该字符串的地址是char**。qsort将对字符串数组进行排序

    C i
    //
    //  main.c
    //
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    //Takes a pointer to any type.. (void *)
    int stringAsInt(const void *pLeft, const void *pRight) {
        //qsort calls this function with a pointer to each element. Since each element is a char* then pLeft is actually a char**.
        //For example, if sorting an array of ints (each element is of type: int), pLeft would be int*.
        //If sorting an array of strings (each element is of type: char*), pLeft would be char**.
        //So on and so forth.
    
    
        //Thus we cast the pLeft to its correct type (const char**) for pointer to string.. Then we dereference it to get the string itself (const char*).
        const char *left = *(const char**)pLeft;
        const char *right = *(const char**)pRight;
    
        int leftLen = (int)strlen(left);
        int rightLen = (int)strlen(right);
    
        //Compare the lengths of the strings.. If left is < right, we return negative. If they are the same, 0.. else positive..
        if (leftLen != rightLen) {
            return leftLen - rightLen;
        } else {
            return strcmp(left, right);  //Lengths are equal.. compare their contents..
        }
    }
    
    int main() {
        int n;
    
        //First the code takes an array count.. This is the amount of arrays to sort..
        printf("Enter number of strings: ");
        scanf("%d", &n);
    
        //It allocates a large buffer on the stack to hold entire sentences to sort..
        char buffer[1000000 + 1];
    
        //Allocates an array of strings..
        char **a = malloc(sizeof(char*) * (size_t)n);
    
        for (int i = 0; i < n; i++) {
            printf("Enter a string: ");
            scanf("%1000000s", buffer);
    
            //Store each string in the array..
            a[i] = malloc(sizeof(char) * (strlen(buffer) + 1));
            strcpy(a[i], buffer);
        }
    
        //Sort the array using stringAsInt comparator..
        //a is the array to sort.
        //n is the amount of elements in the array.
        //sizeof(a[0]) is the size of each element in the array. sizeof(char*).
        //stringAsInt is the comparator function (pointer to function)..
    
        qsort(a, (size_t)n, sizeof(a[0]), stringAsInt);
    
        //Print the sorted array and cleanup each element.
        for (int i = 0; i < n; i++) {
            printf("%s\n", a[i]);
            free(a[i]);
        }
    
        //Cleanup the array itself.
        free(a);
        return 0;
    }
    
    0x0100 'f'
    0x0101 'o'
    0x0102 'o'
    0x0103 '\0'
    
    0x3127 'b'
    0x3128 'a'
    0x3129 'r'
    0x312a '\0'
    
    0x2522: 0x0100
    0x2524: 0x3127
    
    0x2522: 0x3127
    0x2524: 0x0100