Функция сортировки структуры

это наш долг - помогать людям (с)

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

Наш колхоз,
Наш колхоз -
Выполнил план
По надою коз

:wink:
Нотного шрифта у меня на этом компе нет, так что так:
соль ми до-, ля фа до-, си, соль си ля, соль фа соль, ми до–.

В целом реминисценция ясна.

Если я ничего не напутал, то пробуй это:

struct commandLine {
  uint16_t timeFromStart;
  uint8_t deviceName;
  boolean onDevice;
  uint16_t timeDeviceOn;
};

int compare(const void *i, const void *j);

void setup() {
  Serial.begin(9600);

  commandLine Formovka[] = {
    (commandLine){ 17, 2, 1, 170 },
    (commandLine){ 8, 3, 1, 88 },
    (commandLine){ 5, 2, 1, 55 },
    (commandLine){ 10, 3, 1, 100 },
    (commandLine){ 21, 2, 1, 210 },
    (commandLine) { 13, 3, 1, 130 }
  };

  int arrayLength = sizeof(Formovka) / sizeof(Formovka[0]);

  qsort(Formovka, arrayLength, sizeof(commandLine), compare);

  for (int i = 0; i < arrayLength; i++) {
    Serial.print(i);
    Serial.print(" - ");
    Serial.println(Formovka[i].timeFromStart);
  }
}

void loop() { }

int compare(const void *i, const void *j) {
  return *(uint16_t *)j - *(uint16_t *)i;
}

неправильную ты длину берешь, дядяфёдор.

Upd. Разобрался, всё правильно.

Вот же ты упорный - компилятор же тебе толкует, что бессмысленно здесь typedef ставить, а ты все ставишь )))

Это со вчера осталось ))
Поправил.

Дык длину в байтах типа массива нужно передавать, не?

размер одного элемента массива

А нахрена она там нужна?

Upd. Да, это я старый дурак, нужна она там, позабыл чота. Вопрос снимается.

1 лайк

Вы оба меня запутали.

Всё правильно.

Параметры

base
Начало целевого массива.

number
Размер массива в элементах.

width
Размер элементов в байтах.

compare
Указатель на пользовательскую подпрограмму, которая сравнивает два элемента массива и возвращает значение, показывающее, как соотносятся их значения.

Что я сделал не так, не пойму? )))

Да всё так, я уже разобрался, это не ты дурак, а я. :slight_smile:

1 лайк

Зачем тут из рандомного значения другое вычитать?
В compare д.б. описано, как сравниваются экземпляры структуры: по значению одного поля, по совокупности значений разных полей или как-то иначе.
void* i,j приводятся к нужному типу и алга.

1 лайк

Вот, значит накосячил…
Нужно поля элементов массива сравнивать же… Точно!

Только “завис” как это сделать :smiley:

Что-то такое?

int compare(const void *i, const void *j) {
  return *(commandLine *)j.timeFromStart - *(commandLine *)i.timeFromStart;
}
...(void *_i, void *_j) {
myStruct*  i=(muStruct*) _i,
      j=(muStruct*) _j;

if (i->width > j->width && ...) { return 1; }
...
return 0;
}

Примерно так.

Побежал за грибом, не ждите.

Я честно пытался покурить на эту тему. Но пока квалификации не хватает, видимо. Но и до этого дойду

Наоборот сортирует. Большее сверху. Сам поправлю, конечно, но нескоро - в указателях и ссылках я пока даже не плаваю)

Для того, чтобы это поправить не нужны никакие указатели и ссылки, достаточно поменять местами уменьшаемое и вычитаемое в строке №36:

Дополнение: а ведь наврал, не заметил, что там к uint преобразовывается, тогда вычитать вообще нельзя - отрицательного результата никогда не будет!

Вы, похоже, совсем не поняли как работает функция qsort на пальцах, простыми словами.

Попытаться объяснить или сами хотите разбираться?