如何使用#define语句来设置字节数组?

时间:2013-10-02 10:22:22

标签: c++ arrays arduino macros

我正在编程Arduino,我想使用#define语句来设置要传递给Ethernet.begin()函数的字节数组。这时我正在使用以下代码,并且所有工作都按预期工作:

#define MAC_ARRAY { 0x43, 0xA3, 0xDA, 0x0D, 0xF5, 0xA5 }

void setup() {
  byte mac[] = MAC_ARRAY;

  if (Ethernet.begin(mac) == 0) {
    ...
  }
}

正如您在上面的代码中所看到的,每次使用byte mac[] = MAC_ARRAY;值时,我都必须在源代码中声明MAC_ARRAY。但是我想避免说明(我认为“在很长的路上”可能会因为mac[]变量被实例化而存在内存问题)并且正确地将MAC_ARRAY直接传递给{ {1}}功能。

有可能吗?如果是这样,我应该如何更改Ethernet.begin()声明?

1 个答案:

答案 0 :(得分:0)

正如joachim Pileborg已经提到的,如果你有一个c ++ 11兼容的编译器,可以将一个文字数组传递给一个函数,而函数(Ethernet.begin)有一个begin(std::initializer_list)变体。

但是,您的示例接近解决方案。 make mac global (如果可能, const )并删除define:

uint8_t const mac[] = { 0x43, 0xA3, 0xDA, 0x0D, 0xF5, 0xA5 };
   //^^^^^ -> if begin isn't able to handle const, remove the const here.

void setup() {
  if (Ethernet.begin(mac) == 0) {
    ...
  }
}

这将只对mac进行一次实例化并重复使用它(没有内存问题)。

有一些可能性,具体取决于代码:

  1. Ethernet.begin定义为引用/指针作为参数。这意味着你只传递一个小于6字节(sizeof(mac))的引用。和mac只存储在内存中。

  2. 这里的mac必须声明为 const 。所以编译器可以优化它并将值直接合并到机器指令操作码中。因此你必须使用optimization-flags进行编译。见here

  3. 如果两者都不是一个案例,那么它仍然可以,因为mac仍然是一次性的,并且将通过堆栈内存的值(复制)传递。

  4. 最好的是...... byte const macbegin(byte const*),因此编译器会决定节省内存和时间的最佳方法。


    使其全球化没有任何缺点。如果优化,定义将导致转换的操作码,也可能是全局const将(参见上述情况2)。但是const将导致一个实例也是一个操作码(初始化mac),其余部分引用该实例的引用/别名(寻址值)。行为由您Ethernet

    的实施定义