Я бы пошел более радикально, чем то, что люди предлагали до сих пор, но, возможно, это слишком много для вас. (Ключевое слово «встроенное» — это C99; вы можете опустить его без особых последствий, если кодируете на C89.)
/*
** These could be omitted - unless you get still more radical and create
** the format strings at run-time, so you can adapt the %-24s to the
** longest tag you actually have. Plus, with the strings all here, when
** you change the length from 24 to 30, you are less likely to overlook one!
*/
static const char fmt_int[] = "%-24s [%d]\n";
static const char fmt_long[] = "%-24s [%ld]\n";
static const char fmt_str[] = "%-24s [%s]\n"; /* Plausible extra ... */
static inline void print_long(FILE *fp, const char *tag, long value)
{
fprintf(fp, fmt_long, tag, value);
}
static inline void print_int(FILE *fp, const char *tag, int value)
{
fprintf(fp, fmt_int, tag, value);
}
static inline void print_str(FILE *fp, const char *tag, const char *value)
{
fprintf(fp, fmt_str, tag, value);
}
static void dump_data(FILE *fp, const serial_info_t *info)
{
dump_long("Starting serial number", info->start_int_idx);
dump_int( "Current Serial number", info->current_int_idx);
/* ... and similar ... */
}
Затем вызывающий код вызовет dump_data()
один раз (с аргументом stdout
) для вариантов 1, 2, 3 и дважды (один раз с stdout
, один раз с указателем файла для выходного файла) для варианта 4.
Если бы количество параметров стало действительно огромным (в несколько сотен), я бы даже зашел так далеко, что рассмотрел структуру данных, которая кодировала бы информацию о типе и смещении (offsetof
от <stddef.h>
), а также указатели на функции и тому подобное, так что будет просто циклом в dump_data()
, перебирающим структуру, которая кодирует всю необходимую информацию.
Вы также можете упростить жизнь, используя один и тот же базовый целочисленный тип (long
в вашем примере) для всех целочисленных членов структуры данных.
Фред Брукс в «Мифическом человеко-месяце» — книге, которую стоит прочитать, если вы еще этого не сделали, но обязательно прочтите издание, посвященное двадцатой годовщине, — говорит в главе 9:
Покажи мне свои блок-схемы [код] и спрячь свои таблицы [структуры данных], и я продолжу пребывать в замешательстве. Покажите мне свои таблицы, и обычно мне не понадобятся ваши блок-схемы; они будут очевидны.
Табличная версия этого кода может в конечном итоге сэкономить место, а также вызвать разочарование, когда придется изменять сотню связанных функций одним и тем же способом, тогда как простое изменение табличных данных могло исправить все.
person
Jonathan Leffler
schedule
15.01.2009