使用Arduino 以太网服务器库,有什么区别:
server.write(data);
,
server.print(data);
, 和
server.println(data);
我知道printIn
添加了一个新行,而print
没有。我找不到任何示例server.write();
。
使用Arduino 以太网服务器库,有什么区别:
server.write(data);
,
server.print(data);
, 和
server.println(data);
我知道printIn
添加了一个新行,而print
没有。我找不到任何示例server.write();
。
(长答案,跳到TL;如果笨拙,请在底部 DR)
print()
_ write()
_要找出答案,我们可以查看源代码。 是在(仅选定的行)中定义Server
的类的实例EthernetServer
arduino/libraries/Ethernet/EthernetServer.h
#include "Server.h"
class EthernetClient;
class EthernetServer :
public Server {
private:
public:
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
using Print::write;
};
好的,所以它是一个Server
. Server
在 中定义/usr/share/arduino/hardware/arduino/cores/arduino/Server.h
,并且几乎没有:
class Server : public Print {
public:
virtual void begin() =0;
};
这意味着 server 是一个子类,Print
因此我们可以寻找它们之间的write()
差异print()
。
print()
和write()
参数我们看到这个类(即Print
)定义了许多重载print()
方法:
size_t print(const __FlashStringHelper *);
size_t print(const String &);
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);
和三个重载write()
方法:
virtual size_t write(uint8_t) = 0;
size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); }
virtual size_t write(const uint8_t *buffer, size_t size);
如您所见,C-stringwrite
使用块write
(第三种方法),而在默认实现中,块写入使用字节写入(第一种方法),这是纯虚方法:virtual size_t write(uint8_t) = 0;
. 它必须在派生自 的每个类中被覆盖Print
。此外,该块write()
也可以被覆盖,以便更有效地写入多字节数据。
所以,参数方面:
write()
: 在字节 ( uint8_t
)、字节缓冲区和 char 数组指针上(= 常规 C 字符串)print()
: Arduino String
s、int
s 和long
s(在任何基础上)、float
s 和任何从Printable
、 除了chars
和 C 字符串派生的类。write()
正如你所看到的,形式上,参数和take之间几乎没有重叠print()
。比如只write()
取uint8_t
,但只能print()
取一个char
。唯一重叠的区域是 C 风格的字符串:有print(const char[]);
和write(const char *str);
。然而,即使在像函数这样char
的情况下,也print()
只是简单地调用write(uint8_t)
:
size_t Print::print(char c)
{
return write(c);
}
对于print(char[])
write()
在`以太网服务器该类EthernetServer
引入了块写入方法
size_t EthernetServer::write(const uint8_t *buffer, size_t size)
并在EthernetServer
简单write(uint8_t)
的块中写入:
size_t EthernetServer::write(uint8_t b)
{
return write(&b, 1);
}
由于所有print()
调用和非uint8_t
write()
调用都使用write(uint8_t)
or write(uint8_t*, size_t)
,因此在EthernetServer
类中每个print
/write
调用都是使用块写入进行的。
print()
选择write()
thunkingprint()
函数(例如print(char c)
)很可能会被 gcc 编译器内联,但如果您担心这一点,您可以调用write()
而不是print()
.
您可能想要调用write()
而不是print()
保存几个时钟周期的一种情况是您持有byte
/uint8_t
并且您需要打印它。使用print()
您的数据需要转换为 4 字节值 ( int
),然后使用更多代码打印。在这种情况下write()
会快一点。
另一方面,代码一致性可能也很有价值。从这个角度来看,拨打所有电话可能是有意义的print()
。
然而,大多数时候,您的类型将决定调用该print()
函数:write 只能接受三种类型的输入。
TL; DR:那么你的问题的答案是,print()
除了write()
:
write()
方法(字节或块)是在任何情况下执行在某处发送字符的实际工作的方法。write()
可以将字节 ( uint8_t
)、字节缓冲区和 char 数组指针(= 常规 C 字符串)作为参数,而print()
将 Arduino String
s、int
s 和long
s(以任何基数)、 s 以及从、 除了和 C 字符串float
派生的任何类. 所以我们可以说它比 低级别,因为它只接受低级别的类型。Printable
chars
write()
print()
write()
用于打印byte
/uint8_t
类型,但print
在任何地方都使您的代码看起来稍微好一点恕我直言(主要是因为它不会引发print()
vswrite()
问题)。