Qsort处理指针

时间:2014-05-17 19:12:22

标签: c++ pointers qsort

我遇到qsort时遇到问题,如果有人可以帮助我,我真的很感激。

此外,我在询问之前已经搜索了很多,但没有成功。

以下是我的程序大致设置的方式:

〜.H〜

class playerClass{
    playerClass( ) { }
    ...
    double average;
};

class Stats{
    void update(...);
    ...
    playerClass *ar[1201];
};

〜的.cpp〜

void update(...){
    playerClass *p = new playerClass( );
    ...
    for (int i = 0; i < count; i++){
        ...
        ar[j]->average = (ar[j]->hits)/(ar[j]->atBats);
        cout << "Average: " << ar[j]->average << endl;

        /* Prints Averages correctly, but I need everything to be sorted by
           the Averages, and I am instructed to use qsort */

        qsort(*ar, count, sizeof(playerClass*), compare);
        cout << "Sorted average: " << ar[j]->average << endl;
    }
}

int compare (const void *a, const void *b){
    playerClass *x = (playerClass*)a;
    playerClass *y = (playerClass*)b;

    /* I believe that I'm not correctly accessing the Averages with
       the two statements above, I have tried many different variations
       of them, but I am not actually able to access the averages correct.
       Can someone please help me, so that way I can get over this obstacle
       and continue this assignment? */

    if (x < y) return -1;
    if (x > y) return 1;
    return 0;
}

2 个答案:

答案 0 :(得分:2)

您想在compare函数中替换这两行:

playerClass *x = (playerClass*)a;
playerClass *y = (playerClass*)b;

double x = ((playerClass*) a)->average;
double y = ((playerClass*) b)->average;

因为您使用xy来比较平均值,而不是进行交换。当您将指向类的指针分配给xy时,您将比较它们的指针 - 因此您的排序最终“按照它们放入内存的顺序” - 这不太可能是订购你想要的。

更新这是一个非常简单的程序,它创建一个类,该类的元素数组以及指向元素的指针数组。它使用指针数组调用qsort,它表明原始数组最终排序。

看看这对你有帮助吗......

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

class playerClass {
  public:
    double average;
};

// some values for initialization
double values[] = { 40, 10, 100, 90, 20, 25 };

int compare (const void * a, const void * b)
{
  return (((playerClass*)a)->average - ((playerClass*)b)->average);
}

int main ()
{
  int ii;
  playerClass b[6];  // create 6 elements of the "class"
  playerClass *a[6]; // create pointers to the elements
  for(ii=0; ii<6; ii++) {
    b[ii].average = values[ii]; // put values in the elements
    a[ii] = &b[ii]; // make the pointers point to sensible things
  }

  qsort (a[0], 6, sizeof(playerClass), compare); // perform qsort
  // and print results:
  for (ii=0; ii<6; ii++)
     printf ("%.0f ",b[ii].average);
  printf("\n");
  return 0;
}

这将输出已排序的值:

10 20 25 40 90 100 

PS我很抱歉,如果它看起来像C ......除了class定义之外。我可以使用struct这种(无函数)类,它可以以相同的方式工作。

PPS - 你可以做到

qsort(b, 6, sizeof(playerClass), compare);

它会同样有效。

我认为你的问题是你仍在尝试对一个像指针大小的东西进行排序,而它应该是整个类别对象的大小。

所以我认为

qsort(ar, count, sizeof(playerClass), compare);

是解决这个问题的方法(我刚刚注意到,在你的一个编辑中,你拿出了playerClass *ar[N]; ...

这一行。

旁注
如果您编辑问题以包含有关错误的建议,则很难回答答案。最好在下面添加更新 - 比如

  

“正如@JohnDoe指出的那样,我应该使用ar代替*ar。所以我将代码更改为...,现在问题是...对于人们谁会关注这个问题并试着帮助你找到答案,这真的很有帮助。

否则,我们必须查看编辑历史记录以确定发生了什么。有意义吗?

答案 1 :(得分:2)

除了@Floris回答之外,您应该将qsort移到循环之外。否则,您不必要地多次对数组进行排序。

您还必须提供ar的地址,而不是第一个元素

for (int i = 0; i < count; i++) {
    ...
}

qsort(ar, count, sizeof(ar[0]), compare);

另请注意,compare必须是自由函数或某类的静态成员。

更新

我将调用复制到qsort而没有关注sizeof部分。 qsort需要数组元素的大小,这是{em>指针到playerClass的大小。您可以提供第一个元素ar[0]

qsort(ar, count, sizeof(ar[0]), compare);

或正确的类型playerClass*

qsort(ar, count, sizeof(playerClass*), compare);

更新

第三次尝试,你想要对一组指针进行排序。这有两个含义

  • 如上所述,您必须为qsort
  • 的size参数提供sizeof(playerClass*)
  • 比较函数的参数是指向元素的指针,在本例中是指向playerClass指针的指针。这导致以下比较函数

    int compare(const void *a, const void *b)
    {
        playerClass *x = *(playerClass**)a;
        playerClass *y = *(playerClass**)b;
    
        if (x->average < y->average)
            return -1;
    
        if (x->average > y->average)
            return 1;
    
        return 0;
    }