Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.chainon-marquant.org!nntpfeed.proxad.net!proxad.net!feeder1-2.proxad.net!74.125.46.80.MISMATCH!postnews.google.com!news2.google.com!Xl.tags.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local2.nntp.dca.giganews.com!nntp.earthlink.com!news.earthlink.com.POSTED!not-for-mail NNTP-Posting-Date: Sat, 07 Jan 2012 19:50:32 -0600 Message-ID: <4F08F66B.4899@mindspring.com> Date: Sat, 07 Jan 2012 20:50:35 -0500 From: pete Reply-To: pfiland@mindspring.com Organization: PF X-Mailer: Mozilla 3.04Gold (WinNT; I) MIME-Version: 1.0 Newsgroups: comp.lang.c Subject: Re: Is there any way to refer to another array in qsort's compare function? References: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Lines: 118 X-Usenet-Provider: http://www.giganews.com NNTP-Posting-Host: 4.154.223.94 X-Trace: sv3-GykIiUew6xKEAfTWAxPj5uKJl0eiJ8htbeRfJpYpxeb2zkCzMb8Q21/N2KM+8F6DxrE/z8Hcf5maLo3!sgBA8krwdb5lR9rE9w/NfvkraFJvoF3J6E1mUenX//w9gT9bPVO/azLM3m8pc3sXJHrHUHuVt+wp!JR5adqe/yw== X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.40 X-Original-Bytes: 4671 Xref: x330-a1.tempe.blueboxinc.net comp.lang.c:15564 Stone wrote: > > Here's the problem. > > I wrote a function 'int my_compare(const void *, const void *);' and > passed it to qsort() of stdlib.h, in order to sort an array named > *ptr* which contains indices of another array *data*. By that I > intended to sort elements of *ptr* (i.e. ptr[i]) using data[ptr[i]] as > the key value. > > However, the *data* array was defined as static in main(), and seemed > not easy to access in my_compare(). Is there any way to achieve this? If you have for parameters in a function: a pointer to the first element of data[] the number of elements in data[] the size of the elements in data[] then you can derive an array of pointers to the elements of data[] and you can sort them using qsort and you can derive a sorted array of indexes from the sorted array of pointers. /* BEGIN output from index_sort_test.c */ Array elements: Indexed by string length: Printed by string length: data[0] is zero ptr[0] is 1 data[ptr[0]] is one data[1] is one ptr[1] is 2 data[ptr[1]] is two data[2] is two ptr[2] is 6 data[ptr[2]] is six data[3] is three ptr[3] is 5 data[ptr[3]] is five data[4] is four ptr[4] is 4 data[ptr[4]] is four data[5] is five ptr[5] is 0 data[ptr[5]] is zero data[6] is six ptr[6] is 9 data[ptr[6]] is nine data[7] is seven ptr[7] is 8 data[ptr[7]] is eight data[8] is eight ptr[8] is 7 data[ptr[8]] is seven data[9] is nine ptr[9] is 3 data[ptr[9]] is three /* END output from index_sort_test.c */ /* BEGIN index_sort_test.c */ #include #include #include #define NMEMB(A) (sizeof (A) / sizeof *(A)) int my_compare(const void *a, const void *b) { const char (**const aa)[sizeof "three"] = a; const char (**const bb)[sizeof "three"] = b; const size_t len_a = strlen(**aa); const size_t len_b = strlen(**bb); return len_b > len_a ? -1 : len_b != len_a; } void index_sort(size_t *index, char **pointer, void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { size_t n; char *const array = base; pointer[0] = array; for (n = 1; nmemb > n; ++n) { pointer[n] = pointer[n - 1] + size; } qsort(pointer, nmemb, sizeof *pointer, compar); for (n = 0; n != nmemb; ++n) { index[n] = (pointer[n] - array) / size; } } int main(void) { unsigned n; static char data[][sizeof "three"] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; size_t ptr[NMEMB(data)]; char *pointer[NMEMB(data)]; index_sort( ptr, pointer, data, NMEMB(data), sizeof *data, my_compare ); puts("\n/* BEGIN output from index_sort_test.c */\n"); puts("Array elements: Indexed by string length: " "Printed by string length:\n"); for (n = 0; n != NMEMB(data); ++n) { printf("data[%u] is %-7s ", n, data[n]); printf("ptr[%u] is %-15u ", n, (unsigned)ptr[n]); printf("data[ptr[%u]] is %s\n", n, data[ptr[n]]); } puts("\n/* END output from index_sort_test.c */"); return 0; } /* END index_sort_test.c */ -- pete