С помощта на Arduino Ethernet Server Library, каква е разликата между:
server.write(data);
, server.print(data);
и server.println(data);
Знам, че printIn
добавя нов ред, където print
не. Не мога да намеря примери за server.write();
.
С помощта на Arduino Ethernet Server Library, каква е разликата между:
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;
};
Това означава, че сървърът е подклас на 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()
: върху байтове (uint8_t
), буфери за байтове и указатели на масив от знаци (= обикновени C низове)print()
: Arduino String
s, int
s и long
s (в каквато и да е база), float
s и всеки клас, получен от Printable
, в допълнение към 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[])
write()
в `EthernetServerКласът 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)
, или write(uint8_t*, size_t)
, в класа EthernetServer
всяко print
/write
повикване се прави с помощта на запис на блок.
print()
и write()
Функциите thunking print()
(като 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 array (= обикновени C низове) като параметри, докато print()
взема Arduino String
s, int
s и long
s (в каквато и да е база), float
s и всеки клас, извлечен от Printable
, в допълнение към chars
и C низове. Така че можем да кажем, че write()
е по-ниско ниво от print()
, предвид факта, че приема само типове от ниско ниво.write()
за отпечатване на byte
/uint8_t
типове, но print
навсякъде прави кода ви да изглежда малко по-добре IMHO (главно защото не повдига въпросите print()
срещу write()
).write()
? По-бързо ли е, ако вече използвате типа променлива, който поддържа?
- person Anonymous Penguin; 27.04.2013