为什么“足够”就足够了?(在char数组中存储int)

4
如何在C语言中将int转换为字符串的一个回答(及其评论)中,提供了以下解决方案。请参考此处
char str[ENOUGH];
sprintf(str, "%d", 42);

在评论中,caf提到可以通过以下方式在编译时确定ENOUGH:

#define ENOUGH ((CHAR_BIT * sizeof(int) - 1) / 3 + 2)

我得到了+ 2,因为您需要能够显示减号和空终止符,但其他部分的逻辑是什么?具体来说,CHAR_BIT是什么?

3个回答

5
如果int类型是32位的,那么表示任何数字(不带符号和空终止符)需要多少字节?
如果int类型是32位的,最大的int值是2147483648(假设使用二进制补码),即10个数字,因此需要10个字节来存储。
要知道特定平台上int中的位数(例如,我们的例子中的32),可以使用CHAR_BIT * sizeof(int) == 32。请记住,CHAR_BIT是C字节中的位数,sizeof返回字节数。
然后,(32-1)/3==10,因此需要10个字节。您可能还想知道作者如何找到值3?好吧,以2为底的10的对数略大于3

谢谢你的解释,我不知道CHAR_BIT决定了int中的位数:O 我以为它只是关于char中位数的说明。 - Gerhard Burger
这个公式对于不寻常的 int 位宽(例如18)会失败。如果用于 char,如 ((CHAR_BIT * sizeof(char) - 1) / 3 + 2),也会失败。建议使用 ((CHAR_BIT * sizeof(whatever_signed_integer_type) + 1) / 3 + 2) - chux - Reinstate Monica

1
我假设ENOUGH是以保守的方式计算的,因为最终的+2考虑了\0空终止符(始终存在,这很好)和“-”减号(有时存在)。对于正值(和零),您最终会多出一个未使用的额外字节。
因此,如果ENOUGH不是计算存储值所需的严格最小字节数,为什么不使用固定值12? (10个字节用于数字,2个字节用于\0和符号)
然而:
CHAR_BIT * sizeof(int)是在您的机器上存储int所需的确切位数。
-1是因为1位用于符号(无论涉及的技术是二进制补码,一进制补码还是简单的符号存储,都会“消耗”1位信息来存储符号)
/ 3是因为每个十进制数字至少需要3位信息。

0

CHAR_BITchar 类型中的位数(很可能是8),sizeof(int) 是2或4,因此 ENOUGH 是7或12,这足以保存一个包括符号和NULL终止符的int。


1
谢谢,但是我只做到这里了 :) - Gerhard Burger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接