0

我为儿子编写了一个 Arduino 项目,并在此过程中了解了 C。一切正常,但是在将代码分成十个文件并将变量分组到每个文件中的结构之后,我无法解决一个清晰的愿望。我们需要凭经验确定用于存储和平均端口读取的数组的最佳大小,所以这就是我想要的:

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 hack 示例都要求声明 struct 并稍后初始化 struct 变量。我希望不要复制结构。

我考虑过拆分结构,但这很容易出错,而且还有另一个编译错误:

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 中使用 struct hack 或一些类似的解决方案来实现第一个示例?

4

1 回答 1

0

结构的大小必须在编译时知道。结构中的 const 数据类型可以根据结构的每个实例进行更改,这就是为什么在尝试初始化数组时无效使用非静态数据成员 'Alarms::num_of_reads' 的原因。解决这个问题的最好方法是拥有一个init_alarmdestroy_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

于 2018-12-20T21:31:00.090 回答