使用Arduino以太网屏蔽,`write()`,`print()`和`printIn()`之间有什么区别?

时间:2013-04-26 22:15:13

标签: arduino ethernet

使用Arduino Ethernet Server Library之间有什么区别:

server.write(data);server.print(data);,和 server.println(data);

我知道printIn添加了一个新行,其中print没有。我找不到server.write();的任何示例。

1 个答案:

答案 0 :(得分:4)

(很长的答案,如果笨拙的话,跳到 TL; DR 在底部)

print()write()来自

要了解,我们可以查看来源。 ServerEthernetServer中定义的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;
};

好的,所以它是ServerServer中定义了/usr/share/arduino/hardware/arduino/cores/arduino/Server.h,而且几乎没有:

class Server : public Print {
public:
  virtual void begin() =0;
};

这意味着服务器是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字符串write使用块write(第三种方法),在默认实现中,块写使用字节写(第一种方法),是纯虚方法:virtual size_t write(uint8_t) = 0;。必须在从Print派生的每个类中重写它。此外,块write()也可以被覆盖,以便更有效地写入多字节数据。

所以,参数方式:

  • write():on bytes(uint8_t),字节缓冲区和char数组指针(=常规C字符串)
  • print():Arduino String s,int s和long s(无论基数为何),float s以及从{{Printable派生的任何类1}},除chars和C字符串外。

正如您所看到的,正式地,参数write()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[])

也是如此 `EthernetServer 中的

write()

EthernetServer类引入了块写入方法

size_t EthernetServer::write(const uint8_t *buffer, size_t size) 

并在EthernetServerwrite(uint8_t)只是向块写入:

size_t EthernetServer::write(uint8_t b) 
{
  return write(&b, 1);
}

由于所有print()来电和非uint8_t write()来电均使用write(uint8_t)write(uint8_t*, size_t),因此EthernetServerprint使用块写入进行{1}} / write调用。

效果并在print()write()

之间进行选择

汇总print()函数(例如print(char c))最有可能被gcc编译器内联,但如果你担心这一点,你可以调用write()而不是{ {1}}。

可能想要拨打print()而不是write()以保存几个时钟周期的一种情况是您持有print() / { {1}}你需要打印出来。使用byte您的数据需要转换为4字节值(uint8_t),然后使用更多代码打印。在这种情况下,print()会更快一点。

另一方面,代码一致性也可能是值得的。从这个角度来看,进行所有int次呼叫可能是有意义的。

但是,大多数情况下,您的类型将指示调用write()函数:write只能采用三种类型的输入。


TL; DR :您的问题的答案是print()print()之间没有太大差异,除了:

  • print()方法(字节或块)是在每种情况下执行在某处发送字符的实际工作的方法。
  • write()可以将字节(write()),字节缓冲区和字符数组指针(=常规C字符串)作为参数,而write()采用Arduino uint8_t s,除了print()和C字符串之外,Stringint s(无论基数为何),long以及从float派生的任何类。因此,我们可以说Printable的级别低于chars,因为它只需要低级别类型。
  • 大多数情况下,您的输出类型将决定使用哪一种。要使最快的代码使用write()打印print() / write()类型,但byte到处都会使您的代码看起来好一点恕我直言(主要是因为它没有提高uint8_tprint问题。