当您创建一个带前导零的整数时,c如何处理它?对于不同版本的C,它有什么不同?
在我的情况下,它们似乎只是被丢弃(但也许这就是printf的作用?):
#include <stdio.h>
int main() {
int a = 005;
printf("%i\n", a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用printf来填充0,但我只是想知道它是如何工作的.
bdo*_*lan 33
前导零表示该数字以八进制表示,或以8为基数表示; 因此,010 = 8.添加额外的前导零没有效果; 正如你在数学中所期望的那样,x + 0*8 ^ n = x; 通过使其表示更长时间来改变价值.
您经常看到的一个地方是UNIX文件模式; 0755实际上意味着7*8 ^ 2 + 5*8 + 5 = 493; 或者使用诸如0022 = 2*8 + 2 = 10之类的umasks.
atoi(nptr)
被定义为等价strtol(nptr, (char **) NULL, 10)
,除了它不检测错误 - 因此,atoi()
总是使用小数(因此忽略前导零).strtol(nptr, anything, 0)
执行以下操作:
字符串可以以任意数量的空白区域(由确定
isspace(3)
)开始,后跟单个可选'+'
或'-'
符号.如果base为0或16,则该字符串可以包括"0x"
前缀,并且该数字将在base 16中读取; 否则,零基数被视为10(十进制),除非下一个字符是'0'
,在这种情况下,它被视为8(八进制).
所以它使用与C编译器相同的规则.
小心!
在这个语句中005
是一个八进制常量.
int a = 005;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,无关紧要,因为单个数字八进制常量与等效的十进制常数具有相同的值但在C中: 015 != 15
整数文字是用八进制,十进制还是十六进制表示,一旦被编译器解析,它就被视为一个值.如何输出整数printf
仅取决于其类型,值和格式说明符(以及活动区域设置).
前导零表示数字是八进制的事实是经常被遗忘的事实.我已经看到它多次引起混淆,例如当有人试图使用一个漂亮的,常规格式的八位字节输入IP地址时:
192.168.010.073
Run Code Online (Sandbox Code Playgroud)
并且解析器将最后2个八位字节解释为八进制数.
唯一比C不幸使用前导零来制作数字八进制更糟糕的是Javascript处理前导零有时会产生一个数字八进制(如果其余数字都可以,则数字为八进制 - 否则小于8 - 十进制).在Javascript中,(017 == 15)
但是(018 == 18)
.
我宁愿有一个错误; 实际上我宁愿完全放弃八字形文字支持.至少可以使用更多的面对面的前缀
0t10 (ocTal 8)
0k17 (oKtal 15)
Run Code Online (Sandbox Code Playgroud)
但是我提议的时间已经晚了35年.
具有前导零的数字表示在所有C版本中的八进制编码011 == 9 == 0x9
.
Octal是一个基于8的编号系统(而不是10为十进制或16为十六进制).所以011 == 1*8 + 1, 013 == 1*8 + 3
,等等