我正在编程 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 实例化一次并重新使用它(没有内存问题)。
有一些可能性,取决于代码:
Ethernet.begin
是使用引用/指针作为参数定义的。这意味着您传递的只是一个通常小于 6 字节 (sizeof(mac)) 的引用。而 mac 只在内存中存储一次。此处 mac 必须声明为 const。所以编译器可以优化它并将值直接合并到机器指令操作码中。因此你必须在打开优化标志的情况下进行编译。见here
如果两者都不是,那么它仍然可以,因为 mac 仍然被实例化一次,并将通过堆栈内存按值(复制)传递。
最好的是... byte const mac
和 begin(byte const*)
,因此编译器将决定节省内存和时间的最佳方式。
让它成为全局性的没有缺点。一个 define 将导致翻译的操作码,如果优化的话,global const 也可能会(见上面的案例 2)。但是 const 将导致一个实例和一个操作码器(在初始化 mac 时),其余的将导致对该实例的引用/别名(寻址值)。该行为由您的 Ethernet
的实现定义。
关于c++ - 如何使用#define 语句来设置字节数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19134773/