C如何处理带有零的整数字面值,atoi怎么样?

当你创build一个前导零的整数时,c如何处理? 对于不同版本的C是不同的?

在我的情况下,他们似乎被放弃(但也许这是什么printf呢?):

#include <stdio.h> int main() { int a = 005; printf("%i\n", a); return 0; } 

我知道我可以使用printf填充0,但我只是想知道这是如何工作的。

前导零表示数字以八进制表示,或以八进制表示; 因此,010 = 8。添加额外的前导零不起作用; 就像你在math中所期望的一样,x + 0 * 8 ^ n = x; 通过使其代表性更长,价值没有改变。

你经常看到的一个地方是在UNIX文件模式下; 0755实际上是指7 * 8 ^ 2 + 5 * 8 + 5 = 493; 或使用诸如0022 = 2 * 8 + 2 = 10的掩码。

atoi(nptr)被定义为等价于strtol(nptr, (char **) NULL, 10) ,除了它不检测错误 – atoi()总是使用十进制(因此忽略前导零)。 strtol(nptr, anything, 0)做到以下几点:

string可以以任意数量的空格开始(由isspace(3)确定),后跟一个可选的'+''-'符号。 如果基数为零或16,则string可以包括"0x"前缀,并且数字将以基数16读取; 否则,除非下一个字符为'0' ,否则将零基数取为10(十进制),在这种情况下取​​为8(八进制)。

所以它使用与C编译器相同的规则。

小心!

在这个声明中, 005是一个八进制常数。

 int a = 005; 

在这种情况下,这并不重要,因为一个数字的八进制常量与等效的十进制常量具有相同的值,但是在C: 015 != 15

无论整数文字是以八进制,十进制还是hex表示,一旦编译器parsing,它就被视为一个值。 如何通过printf输出一个整数只取决于它的types,它的值和格式说明符(以及活动的语言环境)。

具有前导零的数字意味着在所有版本的C中都是八进制编码。因此, 011 == 9 == 0x9

八进制是一个基于8(而不是十进制或hex16)的编号系统。 所以011 == 1*8 + 1, 013 == 1*8 + 3

前导零表示一个数字是八进制的事实是经常被遗忘的。 我已经多次看到这会导致混淆,比如有人试图用八位字节的一个很好的常规格式input一个IP地址:

 192.168.010.073 

parsing器将最后2个八位字节解释为八进制数字。

唯一比C不幸的使用前导零来产生一个八进制数字的方法是,Javascript处理前导零有时会产生一个八进制数字(如果其余的数字是正确的,那么这个数字是八进制数,否则小于八位十进制数)。 在Javascript中, (017 == 15)(018 == 18)

我宁愿有一个错误; 实际上,我宁愿放弃八进制文字支持。 至less可以使用更多的在你的脸上的前缀

 0t10 (ocTal 8) 0k17 (oKtal 15) 

但是我的提议已经晚了35年了。

你应该试试:

 int a = 5; printf("%03i\n", a); 

0表示“填充零”,3表示所需的输出长度。

编辑:对不起,我读过你的问题太快 – 现在我看到你问了完全不同的东西。 不过,我会留下这个,因为这可能对别人有帮助。

整数没有“前导零”,5是5,如果你愿意,你可以写前面0的string表示,因为你有printf修饰符。

在你的特定情况下,printf会把这个零点丢弃。 除编译器将整数视为八进制数字的初始零外,所有前导零都被编译器除去。 对于005,八进制和十进制表示是相同的,不应该打扰你,但仍然是要求麻烦,除非你特别指八进制表示。

前导零必须纯粹使用整数的string表示。 要使用前导零打印,请使用“%03d”。 这将确保字段长度为3。

通常,“%<x> d”将打印一个整数x个字符宽的字符,并且将填充前导空格。 “%0 x”d将会做同样的事情,但会填充前导零。