我正在编程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()
声明?
答案 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进行一次实例化并重复使用它(没有内存问题)。
有一些可能性,具体取决于代码:
Ethernet.begin
定义为引用/指针作为参数。这意味着你只传递一个小于6字节(sizeof(mac))的引用。和mac只存储在内存中。
这里的mac必须声明为 const 。所以编译器可以优化它并将值直接合并到机器指令操作码中。因此你必须使用optimization-flags进行编译。见here
如果两者都不是一个案例,那么它仍然可以,因为mac仍然是一次性的,并且将通过堆栈内存的值(复制)传递。
最好的是...... byte const mac
和begin(byte const*)
,因此编译器会决定节省内存和时间的最佳方法。
使其全球化没有任何缺点。如果优化,定义将导致转换的操作码,也可能是全局const将(参见上述情况2)。但是const将导致一个实例也是一个操作码(初始化mac),其余部分引用该实例的引用/别名(寻址值)。行为由您Ethernet
。