Arduino поддерживает взлом структуры или подобное решение вместо гибких элементов массива? - PullRequest
0 голосов
/ 20 декабря 2018

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

struct Alarms {
  // Configurable parameters
    const unsigned int number_of_reads = 24;
  // State variables
    int reads[number_of_reads]; // Error: invalid use of non-static data member 'Alarms::num_of_reads'
};

Это просто, но не работает.Я пробовал гибкие члены массива, пока не обнаружил, что эта функция не поддерживается в C ++.Arduino компилируется с C ++.Я пробовал много примеров «взлома структуры», но все они возвращали ошибки, подобные этой:

struct Alarms {
  // Configurable parameters
    int number_of_reads = 24;
  // State variables
    int reads[];
} ar;

void setup_alarm() {
    ar.reads = malloc(sizeof(int) * ar.number_of_reads);  // Error: incompatible types in assignment of 'void*' to 'int [0]'
}

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

Я подумал о разбиении структуры, но это может привести к ошибкам и, ну, еще одна ошибка компиляции:

struct Alarms2 {
    int reads[ar.num_of_reads];  // Error: array bound is not an integer constant before ']' token
} ar2;

Альтернативой является определение размерамассив и получить размер позже, но это требует объяснения:

struct Alarms {
  // Configurable parameters
    int reads[ 24 ];  // Put number of reads to average between brackets
  // State variables
    int number_of_reads;
};

void setup_alarm() {
    ar.number_of_reads = sizeof(ar.reads) / sizeof(ar.reads[0]);  // this works
}

Есть ли способ работать взломать структуру или какое-то подобное решение в Arduino, чтобы достичь первого примера?

1 Ответ

0 голосов
/ 21 декабря 2018

Размер структуры должен быть известен во время компиляции.Типы данных const в структурах могут меняться в зависимости от экземпляра структуры, поэтому вы получаете недопустимое использование не статического члена данных 'Alarms :: num_of_reads' при попытке инициализировать ваш массив.Лучший способ решить эту проблему - использовать функции init_alarm и destroy_alarm.Примерно так ...

#include <stdio.h>
#include <stdlib.h>

#define DEFAULT_NUM_OF_READS (24)

struct alarm {
    // Configurable parameters
    const int number_of_reads;
    // State variables
    int *reads;
};

void init_alarm(struct alarm *alarm)
{
    alarm->reads = (int *) malloc(alarm->number_of_reads * sizeof(int));
}

void destroy_alarm(struct alarm *alarm)
{
    free(alarm->reads);
}

int main(int argc, char **argv)
{
  // When we create our struct, set number_of_reads to default
  struct alarm alarm = {.number_of_reads = DEFAULT_NUM_OF_READS, .reads = NULL};

  init_alarm(&alarm);

  alarm.reads[0] = 13;
  alarm.reads[23] = 100;

  printf("alarm.reads[0] = %d, alarm.reads[23] = %d\n", alarm.reads[0], alarm.reads[23]);

  destroy_alarm(&alarm);

  return 0;
}

Примечание: чтобы использовать назначенный инициализатор для инициализации структуры, вы должны скомпилировать с ANSI (C99), например так:

gcc --std=c99 test.c -o test

...