Reputation: 32755
Say I have this struct:
struct MyStruct {
int iID;
int iMyNumber;
};
Then I define an array of MyStructs:
struct MyStruct msTest[3];
I'm doing a sorting operation on a struct similar to this one by looking at the ID. Now, as soon as I find out which records should be swapped to sort the array I have to do the actual swapping. I tried this:
if (iSmallest != iCntr) {
stPTmp = &stXDB[iCntr];
&stXDB[iCntr] = &stXDB[iSmallest];
&stXDB[iSmallest] = &stPTmp;
}
stPTmp is defined as void *stPTmp;
and iCntr
and iSmallest
contain the indices of the records to be swapped. My code doesn't work, but how do I fix it?
Upvotes: 2
Views: 12262
Reputation: 96111
John has already answered your question, but to sort your struct
s, you can use the standard library qsort()
function:
#include <stdlib.h>
#include <stdio.h>
struct MyStruct {
int iID;
int iMyNumber;
};
/* comparison function, should return < 0, > 0 or == 0
if a < b, a > b or a == b respectively. Used by qsort */
static int comp_mystruct(const void *a, const void *b);
/* utility function to print an array of our struct */
static void print_mystruct(const void *start, size_t n);
int main(void)
{
/* some data */
struct MyStruct data[] = {
{ 1, 10 },
{ 5, 50 },
{ 2, 20 },
{ -3, 100 }
};
size_t ndata = sizeof data / sizeof data[0];
/* before sorting */
print_mystruct(data, ndata);
putchar('\n');
/* sort the array now */
qsort(data, ndata, sizeof data[0], comp_mystruct);
/* after sorting */
print_mystruct(data, ndata);
return 0;
}
static void print_mystruct(const void *start, size_t n)
{
size_t i;
const struct MyStruct *s = start;
for (i=0; i < n; ++i) {
printf("% 3d % 3d\n", s[i].iID, s[i].iMyNumber);
}
}
static int comp_mystruct(const void *a, const void *b)
{
const struct MyStruct *sa = a;
const struct MyStruct *sb = b;
if (sa->iID > sb->iID) {
return 1;
} else if (sa->iID < sb->iID) {
return -1;
} else {
return 0;
}
}
The output of the program is:
1 10
5 50
2 20
-3 100
-3 100
1 10
2 20
5 50
The advantage is that qsort()
is standard, and you can use it to sort anything.
Upvotes: 3
Reputation: 399753
You could just let someone else think about this, i.e. use qsort()
:
#include <stdlib.h>
int compare_struct(const void *a, const void *b)
{
const struct MyStruct *sa = a, *sb = b;
return (sa->iID < sb->iID) ? -1 : sa->iId > sb->iId;
}
qsort(msTest, sizeof msTest / sizeof *msTest, sizeof *msTest, compare_struct);
Note that this totally removed the need to write the swapping function. Under the hood, this might be a bit more costly (could use malloc()
, almost certainly uses memcpy()
), but it's way easier to write and much easier to maintain.
Upvotes: 3
Reputation: 34128
You need to swap elements, not pointers,
struct MyStruct stTmp;
if (iSmallest != iCntr) {
stTmp = stXDB[iCntr];
stXDB[iCntr] = stXDB[iSmallest];
stXDB[iSmallest] = stTmp;
}
Not terribly efficient, but your structs are small, so its only a bit more expensive than swapping pointers.
Upvotes: 4