Обмен элементов в массиве структур - PullRequest
1 голос
/ 26 января 2010

Скажите, у меня есть такая структура:

struct MyStruct {
  int iID;
  int iMyNumber;
};

Затем я определяю массив MyStructs:

struct MyStruct msTest[3];

Я делаю операцию сортировки структуры, похожей на эту, просматривая идентификатор. Теперь, как только я узнаю, какие записи нужно поменять местами для сортировки массива, я должен выполнить фактическую замену. Я попробовал это:

if (iSmallest != iCntr) {
    stPTmp = &stXDB[iCntr];
    &stXDB[iCntr] = &stXDB[iSmallest];
    &stXDB[iSmallest] = &stPTmp;
}

stPTmp определяется как void *stPTmp;, а iCntr и iSmallest содержат индексы записей, подлежащих обмену. Мой код не работает, но как мне это исправить?

Ответы [ 3 ]

4 голосов
/ 26 января 2010

Вам нужно поменять местами элементы, а не указатели,

struct MyStruct stTmp;

if (iSmallest != iCntr) {
    stTmp = stXDB[iCntr];
    stXDB[iCntr] = stXDB[iSmallest];
    stXDB[iSmallest] = stTmp;
}

Не очень эффективно, но ваши структуры маленькие, так что это только немного дороже, чем замена указателей.

3 голосов
/ 26 января 2010

Джон уже ответил на ваш вопрос, но для сортировки ваших struct s вы можете использовать стандартную библиотеку qsort():

#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;
    }
}

Вывод программы:

  1  10
  5  50
  2  20
 -3  100

 -3  100
  1  10
  2  20
  5  50

Преимущество в том, что qsort() является стандартным, и вы можете использовать его для сортировки чего угодно.

3 голосов
/ 26 января 2010

Вы можете просто позволить кому-то еще подумать об этом, то есть использовать <a href="http://linux.die.net/man/3/qsort" rel="nofollow noreferrer">qsort()</a>:

#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);

Обратите внимание, что это полностью избавило от необходимости писать функцию подкачки. Под капотом это может быть немного дороже (может использовать malloc(), почти наверняка использует memcpy()), но его легче написать и гораздо проще в обслуживании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...