我会比人们迄今为止建议的更激进,但也许对你来说太过分了。('inline' 关键字是 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 ... */
}
然后调用代码将为选项 1、2、3调用dump_data()
一次(带参数),为选项 4 调用两次(一次为,一次为输出文件的文件指针)。stdout
stdout
如果参数的数量真的很大(达到数百个),我什至会考虑一个数据结构,它编码类型和偏移信息(offsetof
from <stddef.h>
)以及指向函数等的指针,这样就会有只是一个循环dump_data()
遍历编码所有必要信息的结构。
long
您还可以通过对数据结构的所有整数成员使用相同的基本整数类型(在您的示例中)来简化生活。
Fred Brooks 在“神话人物月”中——如果你还没有读过这本书,非常值得一读,但请确保你阅读了 20 周年纪念版——在第 9 章中说:
给我看你的流程图[代码]并隐藏你的表格[数据结构],我将继续被迷惑。给我看你的表格,我通常不需要你的流程图;他们会很明显。
此代码的表格驱动版本最终可能会节省空间,并且在必须以相同方式更改一百个相关函数时感到沮丧,而表格数据中的简单更改可能会解决整个问题。