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

标签 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) {
    ...
  }
}

正如您在上面的代码中看到的,每次使用 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 global(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。所以编译器可以优化它并将值直接合并到机器指令操作码中。因此你必须在打开优化标志的情况下进行编译。见here

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

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


让它成为全局性的没有缺点。一个 define 将导致翻译的操作码,如果优化的话,global const 也可能会(见上面的案例 2)。但是 const 将导致一个实例和一个操作码器(在初始化 mac 时),其余的将导致对该实例的引用/别名(寻址值)。该行为由您的 Ethernet 的实现定义。

关于c++ - 如何使用#define 语句来设置字节数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19134773/

相关文章:

c++ - 如何在 Arduino 中使用 C++ 成员函数作为中断处理程序?

c++ - 不抛出或异常?

python - 在 Python 中更改了对象

c# - Write() 和 Read() 来自 NetworkStream 的原始字节,数据在某些字节上存在差异

php - 如何将父菜单和子菜单类设置为事件

c - 如何连接两个整数变量并制作一个浮点变量?

c++ - ListView_GetItem() 宏 & LV_GETITEMTEXT 在获取另一个 APP ListView 项时返回空字符串

c++ - 没有运算符 "*"匹配这些操作数

c++ - 是否有比 boost::object_pool 更快的 C++ 堆分配/释放机制可用?

c - 使用C语言从Arduino串口获取数据时出错