Ну и до кучи - чтобы все варианты были и чтобы было из чего выбирать.
Ведь критерии могут быть разными - если действительно нужно максимальное быстродейстиве (ascii протоколы, например) или минимальный код - тогда лучше всего асм-вариант с умножениями, приведенный Rst7 либо вычитания степеней 10 (где-то я уже приводил свой вариант "без восстановления остатка", когда вычитаются десятки тысяч, потом добавляются единицы тысяч, потом вычитаются сотни и добавляются десятки - каждый раз порогом есть переход через 0 и после этого назад вычитаемое не добавляется - код ещё немного короче и немного быстрее).
Если в программе деление всё равно нужно в других местах (уже линкуется и ещё одно использование на размер не влияет) и преобразование нужно только для пользовательского интерфейса (медленного по сути), то itoa по коду не проигрывает (а то и выигрывает), а его тормознутость не мешает.
Ну а если кроме "лишних полтора килобайта не жалко" (если без плавающих форматов и переменных ширин полей и прочих режко используемых возможностей, про которые не все и знают, то fprintf тянет где-то столько), не хочется компоновать вывод, вручную соображая форматирование - от перемешивания строк и чисел и включая усечение вывода приведенных вариантов до, скажем, 3 знаков, то printf ничем не хуже.
Причём в зависимости от инструмента sprintf (требующий опять таки врукопашную выделять буфер и потом его копировать куда надо) можно отложить и использовать fprintf
avr-gcc
Код
#include <stdio.h>
#include <lcd.h>
int lcd_file_putc(char ch, FILE * stream)
{
(void) stream;
lcd_putchar(ch);
return 0;
}
FILE lcd_file = FDEV_SETUP_STREAM(lcd_file_putc, 0, _FDEV_SETUP_WRITE);
#define flcd (&lcd_file)
...
// тут и с гашением, и без гашения, и с фиксированной шириной поля, и с переменной
// - как угодно
fprintf_P( flcd, PSTR("%d 0x%04X"), -20121, 0xBEEF);
А если ещё и через терминалку общение всё равно идёт
Код
int console_putc(char ch, FILE * stream)
{
(void) stream;
uart_putchar(ch);
return 0;
}
int console_getc(FILE * stream)
{
(void) stream;
return uart_getchar();
}
FILE console_file = FDEV_SETUP_STREAM(console_putc, console_getc, _FDEV_SETUP_RW);
#define fconsole (&console_file)
void report_ex_time(const prog_char *header, const prog_char *comment, uint32_t cpu_ticks)
{
uint32_t ex_time = (cpu_ticks * CPU_TICK_SCALE + 128) / 256; // CPU ticks to us
if (comment)
fprintf_P(fconsole, PSTR("%-38S = %6luus (%S)\n"), header, ex_time, comment);
else
fprintf_P(fconsole, PSTR("%-38S = %6luus\n"), header, ex_time);
}
То и сам fprintf уже не тянет карман, а удобства хватает.
В конце концов у какой-нибудь зачуханной меги32 ресурсов - почитай как у "Электроники-60" в неплохой комплектации, а за мегу128 я и не говорю.