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

How to use a #define statement in order to set an array of bytes?

本文关键字:字节 字节数 数组 设置 何使用 #define 语句      更新时间:2023-10-16

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

#define MAC_ARRAY { 0x43, 0xA3, 0xDA, 0x0D, 0xF5, 0xA5 }
void setup() {
  byte mac[] = MAC_ARRAY;
  if (Ethernet.begin(mac) == 0) {
    ...
  }
}

正如您在上面的代码中看到的,每次使用 MAC_ARRAY 值时,我都必须在整个源代码中声明byte mac[] = MAC_ARRAY;。但是,我想避免说明这一点(我也认为"在很长的路上"可能存在内存问题,因为mac[]变量被实例化(并以某种方式将正确的MAC_ARRAY直接传递给Ethernet.begin()函数。

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

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

但是,您的示例接近于解决方案。 mac全局(如果可能,则为常量(并删除定义:

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*),因此编译器将决定节省内存和时间的最佳方式。


使其全球化没有缺点。 定义将导致转换的操作码,如果优化,也可能是全局常量(见上文情况 2(。 但是常量将导致一个实例也是一个操作码器(在初始化 Mac 时(,其余的引用/别名(寻址值(。 行为由您的Ethernet的实现定义。