11

当您创建一个带有前导零的整数时,c 如何处理它?不同版本的C有不同吗?

就我而言,它们似乎只是被丢弃了(但也许这就是 printf 的作用?):

#include <stdio.h>

int main() {
    int a = 005;
    printf("%i\n", a);
    return 0;
}

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

4

8 回答 8

37

前导零表示该数字以八进制或以 8 为基数表示;因此,010 = 8。添加额外的前导零无效;正如您在数学中所期望的那样,x + 0*8^n = x; 延长其表示时间不会改变值。

您经常看到的一个地方是 UNIX 文件模式。0755 实际上意味着 7*8^2+5*8+5 = 493;或使用 umasks,例如 0022 = 2*8+2 = 10。

atoi(nptr)定义为等效于strtol(nptr, (char **) NULL, 10),除了它不检测错误 - 因此,atoi()始终使用十进制(因此忽略前导零)。strtol(nptr, anything, 0)执行以下操作:

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

因此它使用与 C 编译器相同的规则。

于 2009-11-02T13:34:18.690 回答
8

当心!

在这个语句005中是一个八进制常数。

int a = 005;

在这种情况下,这无关紧要,因为一位八进制常量与等效的十进制常量具有相同的值,但在 C 中:015 != 15

无论整数文字以八进制、十进制还是十六进制表示,一旦它被编译器解析,它就会被视为一个值。整数的输出方式printf仅取决于其类型、值和格式说明符(以及活动区域设置)。

于 2009-11-02T13:35:17.877 回答
8

前导零表示数字是八进制这一事实经常被遗忘。我已经多次看到它引起混淆,例如当有人尝试使用八位字节的良好常规格式输入 IP 地址时:

192.168.010.073

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

唯一比 C 不幸地使用前导零来生成八进制数字更糟糕的是 Javascript 对前导零的处理有时会生成八进制数字(如果其余数字都可以,则该数字是八进制 - 小于 8 - 否则为十进制)。在 Javascript 中,(017 == 15)但是(018 == 18).

我宁愿有一个错误;实际上我宁愿完全放弃八进制文字支持。至少使用更直接的前缀,比如也许

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

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

于 2009-11-02T15:35:58.060 回答
5

带有前导零的数字表示所有 C 版本中的八进制编码。所以011 == 9 == 0x9

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

于 2009-11-02T13:35:49.677 回答
3

你应该试试:

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

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

编辑:对不起,我读你的问题太快了——现在我看到你问了一些完全不同的东西。但是,我将保持原样,因为它可能对其他人有帮助。

于 2009-11-02T13:45:41.053 回答
2

带前导0的数字表示该数字是八进制数。它被称为整数文字。也可以0b用来表示二进制数十六进制数0x0X。你不需要为decimal写任何东西。请参阅下面的代码。

#include<stdio.h>

int main()
{
    int binary = 0b10;
    int octal=010;
    int decimal = 10;
    int hexa = 0x10;
    printf("%d %d %d %d\n", octal, decimal, hexa, binary);
}

欲了解更多信息,请访问教程点

于 2019-02-01T15:03:00.633 回答
1

整数没有“前导零”a 5 是 5,如果你愿意,你可以用前导 0 编写它的字符串表示,因为你有 printf 修饰符。

于 2009-11-02T13:33:59.813 回答
1

在您的特定情况下,printf 正在删除零。 编译器会删除所有前导零,但初始零除外,这会导致编译器将整数视为八进制。对于 005,八进制和十进制表示是相同的,不应该打扰你,但它仍然是在自找麻烦,除非你特别指的是八进制表示。

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

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

于 2009-11-02T13:39:14.733 回答