在我的一个项目中,我将当前版本定义为十进制值,看起来像这样:
#define MINOR_VERSION 13
为了能够在被要求时输出版本,我需要将十六进制表示形式转换为字符串。目前我正在使用sprintf(),它基本上是这样的:
char buffer[3];
sprintf(buffer, "%2x", MINOR_VERSION);
// output buffer
这有一些缺点,其中之一是代码大小增加,因为需要包含sprintf()。此外,值在运行时计算,这无论如何都是浪费的努力。这两个问题对我来说都很重要,因为我在这里使用微控制器。
也许我错过了完全明显的,但我无法想出一个漂亮而干净的宏来为我做转换。原则上我需要一种方法在编译期间将13
转换为其十六进制表示(2位数,没有通常在前面的0x)0d
。
你会建议什么?
答案 0 :(得分:3)
翻转问题,并将版本定义为十六进制。当您需要将其用作字符串时,请使用here中的答案将其转换为字符串。然后你可以做这样的事情:
#include <stdio.h>
#define VERSION 0xd
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
int main() {
printf("hello " TOSTRING(VERSION) "\n");
printf("%d\n", VERSION);
}
答案 1 :(得分:1)
我假设您将手动递增MINOR_VERSION
。如果是这样,为什么要经历一个宏将宏转换为字符串的麻烦。只需在定义中以二进制和字符串形式提供此数字:
#define MINOR_VERSION_BIN (13)
#define MINOR_VERSION_STR ("D")
我知道您可能会发现这种风险很大,例如,您可能会增加一个而不是另一个,但是,预处理器的功能非常有限。它更适合替代而非转换。
答案 2 :(得分:1)
您可以手动创建字符串:
#define HEX_DIGIT(digit) "0123456789ABCDEF"[(digit)]
#define MAKE_HEX(value) HEX_DIGIT((value) < 16? (value): ((value)/16)%16), \
HEX_DIGIT((value) < 16? 16: (value)%16), \
0
#define MINOR_VERSION_BIN 13
char const version[] = { MAKE_HEX(MINOR_VERSION_BIN) };
答案 3 :(得分:1)
信任编译器。如果你绝对坚持在编译时解决它,请使用常量表达式。
char MINOR_VERSION_STR[3] {
'0'+(MINOR_VERSION >>4)&0xF,
'0'+(MINOR_VERSION)&0xF,
0 };
这将达到次要版本63 - 尽管可以肯定是领先零。我提出,如果你超过64个次要版本,那么是时候进行另一个主要版本了。或者你可以通过添加nybbles向上扩展,如果你真的想要
如果前导0困扰你,你可以使用条件表达式 - 再次,优化器应该能够在编译时解析 -
char MINOR_VERSION_STR[3] {
MINOR>VERSION > 15 ? '0'+(MINOR_VERSION >>4)&0xF : '0'+(MINOR_VERSION)&0xF,
MINOR>VERSION > 15 ? '0'+(MINOR_VERSION)&0xF : 0,
0 };
不需要任何宏,但如果你认为你将在其他地方使用它,你当然可以把它变成一个。
或者,不是使用sprintf,而是为此目的编写一个小的专用函数。正如她所展示的那样,她可以非常小巧而且非常快速地痴迷。
将C视为高级汇编程序。这些库非常棒,但是当库不能满足您的需求时,请自行调整这些内容。
答案 4 :(得分:0)
将 master MINOR_VERSION以文本形式定义为欲望(十六进制)格式的字符串。
让MINOR_VERSION的int
版本来自该版本。
#define MINOR_VERSION_S " D"
#define MINOR_VERSION strtol(MINOR_VERSION_S, 0, 16)
注意:OP sprintf(buffer, "%2x", MINOR_VERSION);
的结果是" D"
。