1

我正在对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_ARRAYEthernet.begin()

可能吗?如果是这样,我应该如何更改#define MAC_ARRAY ...声明?

4

1 回答 1

0

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

但是,您的示例接近解决方案。使mac 全局const如果可能)并删除定义:

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。因此编译器可以对其进行优化并将该值直接合并到机器指令操作码中。因此,您必须使用优化标志进行编译。看这里

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

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


使其全球化没有任何缺点。一个定义将导致翻译的操作码,如果优化,也可能全局 const 将(见上面的案例 2)。但是一个 const 将导致一个实例也有一个 opcoder(在初始化 mac 时),其余的则在此实例的引用/别名中(寻址值)。行为由您的Ethernet.

于 2013-10-02T10:46:25.253 回答