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

在关于如何在C中将int转换为字符串 的答案之一 (及其注释)中给出了以下解决方案

char str[ENOUGH]; sprintf(str, "%d", 42); 

在评论中, ENOUGH提到ENOUGH可以在编译时确定:

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

我得到+ 2因为你需要能够显示减号和空终止符但是其他部分背后的逻辑是什么? 特别是CHAR_BIT

如果int类型是32位,那么你需要多少字节来表示任何数字(没有符号和空终止符)?

如果int类型是32位,则最大int值为2147483648 (假设为2的补码),即10位数,因此存储需要10个字节。

要知道特定平台中int的位数(例如,在我们的示例中为32 ),我们可以使用CHAR_BIT * sizeof (int) == 32 。 记住CHAR_BIT是C字节中的位数, sizeof产生一个以字节为单位的大小。

然后(32 - 1) / 3 == 10所以需要10个字节。 您可能还想知道作者如何找到值3? 那么10基数23多一点。

我假设ENOUGH是以保守的方式计算的,因为最终的+2考虑了\ 0 null终止符(总是存在,那很好)和“ – ”减号(有时存在)。 对于正值(和零),最终会得到一个未使用的额外字节。

因此,如果未计算ENOUGH作为存储值所需的严格最小字节数,为什么不使用固定值12? (数字为10个字节,\ 0和符号为2个字节)

然而:

CHAR_BIT * sizeof(int)是在计算机中存储int的确切位数。

-1是因为1位用于符号(你“消耗”1位信息来存储符号,不管涉及的技术是什么,让它成为二进制补码,一个补码或天真符号存储)

/ 3是因为每1个十进制数字至少需要3位信息

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