【问题标题】:passing argument 4 of 'qsort' from incompatible pointer type从不兼容的指针类型传递“qsort”的参数 4
【发布时间】:2011-08-17 11:00:15
【问题描述】:

我在编写我们应该编写的函数时遇到了一些问题。据说,这是它应该如何工作的,但它给了我不兼容的指针类型错误,我不知道如何解决它。

问题在于引用 compare_last 函数的 qsort。

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

#define MAX_PERSONS 100

//person structure definition goes here
typedef struct{
    char last[32];
    char first[32];
    int year;
}Person;

//function declarations go here
int compare_last(Person * ptr1, Person * ptr2);

void main(void){//main function goes here
    char *infilename[20];
    char *outfilename[20];
    FILE * fptrin;
    FILE * fptrout;
    int i, j;
    Person musicians[MAX_PERSONS];
    printf("Enter input file name: ");
    scanf("%s", infilename);
    printf("Enter output file name: ");
    scanf("%s", outfilename);
    strcat(*outfilename, ".htm");
    fptrin = fopen(*infilename, "r");
    fptrout = fopen(*outfilename, "w");

    for(i = 0; i < MAX_PERSONS; i++)
    {
        fscanf(fptrin, "%s %s %i", musicians[i].last, musicians[i].first, &musicians[i].year);
    }

    qsort(musicians, i, sizeof(musicians[0]), compare_last);

    fprintf(fptrout, "<html>\n<body>\n<title>LAB14</title>\n");

    for(j = 0; j < i; j++)
    {
        fprintf(fptrout, "%s %s %i <br>", musicians[j].last, musicians[j].first, musicians[j].year);
    }

    fprintf(fptrout, "</body>\n</html>\n");
    fclose(fptrin);
    fclose(fptrout);

}//end main

//function definitions go here

int compare_last(Person * ptr1, Person * ptr2)
{
    int result = strcmp(ptr1 -> last, ptr2 -> last);
    if(result != 0)
        return result;
    else
        return strcmp(ptr1 -> first, ptr2 -> first); 
}

【问题讨论】:

  • 你写we are supposed to be writing - 这是否意味着这是家庭作业?

标签: c pointers


【解决方案1】:
int compare_last(Person * ptr1, Person * ptr2);

应该是

int compare_last(void * ptr1, void * ptr2);

那么你需要在compare_last内投射

【讨论】:

  • 好的,那么我该如何投射指针呢?我正在尝试的一切都不起作用,我找不到任何解决方案。
  • Person * personPtr1 = (Person *) ptr1;
  • 它仍然给我不兼容的指针类型错误....我使用 qsort 错误吗?我将代码更改为 int compare_last(void * ptr1, void * ptr2) { Person * personPtr1 = (Person *) ptr1;人 * personPtr2 = (人 *) ptr2; int result = strcmp(personPtr1 -> last, personPtr2 -> last);如果(结果!= 0)返回结果;否则返回 strcmp(personPtr1 -> first, personPtr2 -> first); }
  • @Sam:确保您也更改了compare_last() 的原型。
  • 其实回调函数的参数应该都是const void *
【解决方案2】:

@987654321@ 的原型是:

void qsort(void *base, size_t nmemb, size_t size,
           int(*compar)(const void *, const void *));

因此,您的排序函数需要匹配int(*compar)(const void *, const void *),或者您需要在调用 qsort() 时进行强制转换。

如果你想对Person*进行排序,最简单的方法是根据需要声明你的排序函数,然后在函数内部进行强制转换:

static int compare_last(const void *ptr1, const void *ptr2)
{
    const Person *p1 = ptr1, *p2 = ptr2;
    int result = strcmp(p1 -> last, p2 -> last);
    ...
}

那时根本不需要转换,因为const void * 可以很好地转换为const Person *

【讨论】:

  • 在此处转换不匹配的函数指针将调用未定义的行为,因为qsort 会使用错误的参数类型(const void * 而不是Person *)调用它。
  • @R.:好的,很高兴知道。我希望大多数编译器在那里生成一些有意义的东西,因为 const void * 和 Person * 很可能都以相同的方式表示,但不确定性当然值得避免。
  • 是的,在实践中(以及在 POSIX 上)所有指针都具有相同的表示形式,但如果您真的不需要,最好避免依赖它,并且还有另一种编写代码的方法清晰且 100% 符合要求。
猜你喜欢
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 2016-03-28
相关资源
最近更新 更多