Почему Serial.print(1) требует на 228 байт больше программной памяти по сравнению с Serial.print((char)(48+1))?
Только что обнаружил это. Когда я привожу int к char внутри оператора Serial.print, это требует меньше памяти для программы. Я не уверен, почему. Может ли кто-нибудь объяснить это мне? В следующем примере разница составляет 228 байт!
Serial.print(1); // 1676 байт памяти для хранения программ. 184 байта динамической памяти.
Serial.print((char) (48 + 1)); // 1448 байт памяти для хранения программ. 184 байта динамической памяти.
EDIT: Добавление из разных комментариев:
Serial.print('1'); // Sketch использует 1448 байт программной памяти, 184 байт динамической памяти
Serial.write(48 + 1); // Sketch использует 1448 байт программной памяти, 184 байт динамической памяти
EDIT: для int > 9, добавление кавычек в следующем примере экономит 218 байт памяти программы, но добавляет 4 байта к использованию динамической памяти.
Serial.print(123); // 1676/184 байта
Serial.print("123"); // 1458/188 байт
Serial.print(String(123)); // 2772/194 байта
EDIT2: максимальное количество цифр в Arduino-uno int равно 5(?). Вы экономите 80 байт, преобразовывая его в массив символов, по сравнению с простой печатью целого числа:
Serial.print(12345); // 1676/184 байта
char digits[5];
int number = 12345;
for (int i = 4; i >= 0; i--) {
digits[i] = (number %10) + 48;
number /= 10;
}
Serial.print(digits); // 1596/184 байта
Проверить самостоятельно, раскомментировав одно или другое:
void setup() {
// поместите сюда код установки для однократного запуска:
Serial.begin(9600);
Serial.print(1); // использует 1676/184 байта
//. Serial.print((char) (48 + 1)); // использует 1448/184 байта
// Serial.print('1'); // использует 1448/184 байта
// Serial.write(48 + 1); // 1448/184 байта
// Serial.print(123); // 1676/184 байта
// Serial.print("123"); // 1458/188 байт
// Serial.print(String(123)); // 2772/194 байта
// Serial.print(12345); // 1676/184 байта | 1676/184
// Serial.print("12345"); // 1458/188 байт | 1460/190
// символьный бафф[5];
// itoa(12345, buff, 10);
// Serial.print(buff); // 1604/184 байта
char digits[5];
int number = 12345;
for (int i = 4; i >= 0; i--) {
digits[i] = (number %10) + 48;
number /= 10;
}
Serial.print(digits); // 1596/184 байта
}
void loop() {
// поместите сюда ваш основной код для многократного запуска:
}
EDIT: Второй вопрос: не следует ли это как-то оптимизировать? Или я должен всегда сам об этом заботиться? И почему/как? ;)
*символы 0–9 имеют десятичное значение 48–57 в таблице Ascii, поэтому (char)(48 + 0–9) печатает 0–9
@Gaai, 👍1
Обсуждение1 ответ
Разница вот в чем:
- Напечатать этот символ
и
- Интерпретируйте это целое число как последовательность цифр, вычислите символы ASCII, представляющие каждую цифру по очереди, и распечатайте их.
Как видите, даже простое написание того, что делает второй, занимает больше слов. Печать целого числа требует гораздо больше работы, чем просто печать одного символа. Подумайте о том, что нужно, чтобы напечатать значение 2034578, и как бы вы это сделали, учитывая, что вы можете выводить только отдельные числа 0-9, а данные хранятся не как числа 0-9, а как последовательность только 0 и 1. .
Это требует работы. Много работы.
Так почему бы тогда не перевести его на символ в фоновом режиме. Так как это требует меньше работы, много меньше работы;), @Gaai
@Gaai, потому что это не то, что делает перегрузка int
.print()
в общем случае. Вы не можете правильно напечатать .print(123);
с помощью одного приведения и сложения. Вы используете механизм, который позволяет правильно напечатать «123», даже если вы запрашиваете только «1», и поэтому вы платите за это. Ответ правильный., @timemage
print — это удобная функция для простой печати различных типов в виде текста ASCII. Если все, что вам нужно, это напечатать один символ, то вам следует использовать не печать, а запись. Вы сами должны выбрать правильный инструмент для своей работы, @chrisl
@chrisl Ах да. Это имеет смысл. Это следует добавить к ответу! Serial.write(1) стоит столько же, сколько печать одного символа., @Gaai
@Majenko, возможно, вы можете включить в свои ответы параметр Serial.write для отдельных символов / цифр? Тогда никакой разницы в памяти., @Gaai
@Gaai Первый пункт списка «напечатать этот символ» — это единственный символ, на который вы не согласны., @Majenko
@Gaai Относительно Serial.write(1)
<- .write()
избавит вас от «опасности» случайного вызова перегрузки print()
, которая печатает многозначные числа и, возможно, лучше выражает намерение , но это все, что он делает. Он не отправляет 1 как цифру. Таким образом, .write(1)
в вашем комментарии выше отправляет управляющий символ, а не цифру. Другими словами, вам по-прежнему нужен + 48
, вам просто не нужно приведение (char)
к .write()
так, как вы делали print()
., @timemage
Ну, мой вопрос касался одной цифры int. Это один символ, а также целое число. Но по-прежнему print обрабатывает его как любой int. Используя больше памяти, чем могло бы быть, рассматривая его как char., @Gaai
@timemage конечно ты прав!, @Gaai
Я только что добавил использование памяти Serial.print(123) и Serial.print("123") для полноты картины., @Gaai
Написание моего собственного преобразования по-прежнему экономит 80 байт. Вероятно, вы получите еще больше, если сделаете это умнее. Странно, если вы спросите меня., @Gaai
- avrdude ser_open() can't set com-state
- Как отправить команду AT на sim800l с помощью SoftwareSerial
- Глобальные переменные занимают много места в динамической памяти.
- Ведомое устройство Arduino с двумя мастерами, использующими одну и ту же шину I2C?
- Arduino Uno: avrdude: stk500_recv(): программатор не отвечает
- В чем разница между delay() и delaymicroseconds()
- Программирование Arduino на Паскале?
- Нужна помощь с библиотекой U8GLIB
короткий ответ: это не та же функция печати. вы также можете попробовать
.print('1')
и.print((char) 1)
, @Juraj@Juraj Вы правы, я тестировал всегда печатать целое число в сочетании с приведенными выше примерами. И использование памяти в какой-то момент выравнивается. Я предполагаю, что компилятор оптимизирует функцию печати int, если вы печатаете только символы/строки. Наоборот. Что было бы, когда они вызывают разные функции., @Gaai