2013-09-23 153 views
2

这是我的问题: 我有一个结构:如何将结构成员数组作为参数传递给函数?

struct point 
{ 
    int x; 
    int y; 
}; 

,然后我有一个数组:

for (int i = 0;i < n;i++) 
{ 
    arr[i].x=rand() % n + 1; 
} 

我所定义的quicksort功能如下:

void quicksort(int *a, int left, int right); 

和我想通过X坐标来排序点,所以我打电话给quicksort

quicksort(arr.x, 0, n-1); 

这是错误消息:

error: request for member 'x' in 'arr', which is of non-class type 'point [(((unsigned int)(((int)n) + -0x000000001)) + 1)]'

很抱歉,如果这个问题是太愚蠢或先天存在缺陷的,事实是我是一个新手,我很愿意学习尽可能多尽可能,我会非常感谢你的帮助!

+1

[避免使用'rand'。(http ://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful) – chris

+5

你应该使用'std :: sort',并且定义一个自定义的比较器。 –

+1

你不能用这种方式来切片结构(即使你可以,你不会想要的,因为那样会对x坐标进行排序,并将它们与随机的y坐标进行排序,而不是与原来配对的y坐标。) –

回答

0
quicksort(arr,0,n-1); 

然后内quicksort,尝试比较arr[i].x

0

有你的代码的几个问题。
1.快速排序接受INT *,但你尝试通过int值X
2.您尝试通过INT但实际上你调用一个未定义的变量arr.x

你需要做的是在以语音电话形式为& arr [i] .x,但为了完成您想要的任务,您可能希望将整个结构作为指针传递。

0

您需要通过arr作为参数,因为这是要排序的数组。 arr.x是没有意义的。您没有传递字符串"arr.x"作为参数,它可以以某种方式被解释为在x字段上进行排序 - 当编译器看到此字符时,它正在查找的元素arr,该元素不存在,如错误消息所示 - 只有arr(例如arr[0])的元素具有x元素(作为arr[0].x访问)。

3

如果你总是希望通过x进行排序,那么你可以硬编码到排序功能,只是传递一个指针数组进行排序:

void quicksort(point * arr, int left, int right) { 
    // test points with 
    // if (arr[i].x < arr[j].x) {/* i sorts before j */} 
} 

quicksort(arr, 0, n-1); 

要指定一个类成员排序你需要一个指向成员的指针,而不是指针;是这样的:

void quicksort(point * arr, int point::*member, int left, int right){ 
    // test points with 
    // if (arr[i].*member < arr[j].*member) {/* i sorts before j */} 
} 

quicksort(arr, &point::x, 0, n-1); 

更一般地,你可以遵循的std::sort榜样,接受任何比较函子:

template <typename RandIter, typename Compare> 
void quicksort(RandIter begin, RandIter end, Compare compare) { 
    // test points with 
    // if (compare(*it1, *it2)) {/* *it1 sorts before *it2 */} 
} 

quicksort(arr, arr+n, 
    [](point const &lhs, point const &rhs) {return lhs.x < rhs.x;}); 

当然,除非你正在学习如何实现一个排序算法,只是使用std::sort

+0

的值是多少有利于为'point'实现'operator'' – greyfade

+0

@greyfade:如果你使用'std :: sort'或者一个默认为'std :: less'的比较器,并且你总是想要sam比较,你不介意在其他情况下定义的(<可能误导性的)<<的含义,那么也许。 –

+0

非常感谢!你刚刚救了我很多痛苦)),一旦我获得了15的声望,我会投票支持这个答案。这帮了我很多! :) –

0

假设这是为学术目的(?那你干嘛要声明的,而不是使用已与一个自定义比较实施子里的一个自己的排序算法),你可以做到这一点的几种方法:

阵列

std::array<point, 10> myArray; // declares an array of size 10 for points 
template<size_t N> 
void quicksort(std::array<point, N>& arr, ...) 
{ 
    // implement sort operating on arr 
} 

矢量

std::vector<point> myVector; // declares a dynamic array/vector of points 
void quicksort(std::vector<point>& arr, ...) 
{ 
    // implement sort operating on arr 
} 

如果由于某种神可怕的原因,你要保持它在C:

传统

const size_t SIZE = 10; 
point arr[SIZE]; // declare an array of 10 points 
void quicksort(point* p, const size_t n, ...) 
{ 
    // implement sort operating on elements in p passing in SIZE for n 
} 
0

我宁愿定义的功能为:

void quicksort(void *a,int left,int right, size_t size, int (*fp)(void*,void*)); 

size是数组的一个元素的大小和fp是一个比较函数,如果两个参数相等则返回true。现在,您可以通过调用该函数为:

quicksort(arr,0,n-1,sizeof(arr)/sizeof(arr[0]), compare); 

其中功能比较是这样的:

函数执行的
int compare(void* a, void* b) { return *((int*)a) >= *((int*)b); } 

其余的是微不足道的,我认为。

+0

我的方法太C'ish。请原谅我。 –

0

(几乎)当你真的想传递一个指向对象的指针时,不要试图通过向成员传递指针来愚弄系统。按照Grijesh的建议。传递成员会导致可怕的副作用。例如,快速排序会将所有整数排序在一起,而不管它们中哪些是X的,哪些是Y的。在较温和的情况下,您可能会得到错误的比较标准,并且通常难以调试诸如不正确的指针优化等效果。如果你需要传递一个对象指针,只需要诚实地对待编译器并传递对象指针。这里有很少的例外,主要是在低级系统编程中,函数调用的“另一方”将无法处理对象。

相关问题