C如何处理带前导零的整数文字,以及“atoi”如何处理?

gwo2fgha  于 2023-10-16  发布在  其他
关注(0)|答案(9)|浏览(209)

当你创建一个带前导零的整数时,C如何处理它?不同版本的C有什么不同吗?
在我的例子中,它们似乎只是被丢弃了(但也许这就是printf所做的?):

#include <stdio.h>

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

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

bkhjykvo

bkhjykvo1#

前导零表示该数字以八进制或基数8表示;因此,010 = 8。添加额外的前导零没有效果;正如你在数学中所期望的那样,x + 08^n = x;把它的表示变长并不会改变值。
在UNIX文件模式中,您经常会看到这种情况; 0755实际上意味着7
8^2+58+5 = 493;或者具有诸如0022 = 28+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编译器相同的规则。

mwecs4sa

mwecs4sa2#

事实上,一个前导零表示一个数字是八进制的,这是经常被遗忘的。我见过它引起混乱几次,例如当有人试图输入IP地址使用一个很好的,规则的八位字节格式:

192.168.010.073

并且解析器将最后2个八位字节解释为八进制数。
唯一比C不幸地使用前导零来使数字八进制更糟糕的是JavaScript对前导零的处理,以 * 有时 * 使数字八进制(如果其余的数字是OK的,则数字是八进制-否则小于8 -十进制)。在JavaScript中,(017 == 15)(018 == 18)
我宁愿有一个错误;实际上,我宁愿完全放弃对八进制的文字支持。至少用一个更直接的前缀,比如

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

但我的求婚晚了35年。

imzjd6km

imzjd6km3#

小心点!
在这个语句中,005是一个八进制常数。

int a = 005;

在这种情况下,这并不重要,因为一位八进制常数与等效的十进制常数具有相同的值,但在C中:015 != 15
无论一个整数是用八进制、十进制还是十六进制表示的,一旦它被编译器解析,它就被当作一个值。如何通过printf输出一个整数只取决于它的类型,它的值和格式说明符(和活动的区域设置)。

h22fl7wq

h22fl7wq4#

一个带前导零的数字意味着在所有C语言版本中的八进制编码。所以011 == 9 == 0x9
八进制是基于8的编号系统(而不是十进制的10或十六进制的16)。所以011 == 1*8 + 1, 013 == 1*8 + 3等等。

5tmbdcev

5tmbdcev5#

你应该尝试:

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

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

**编辑:**对不起,我读你的问题太快了-现在我看到你问的是完全不同的问题。不过,我会保持原样,因为它可能对其他人有帮助。

iibxawm4

iibxawm46#

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);
}

有关更多信息,请访问tutorialspoint

beq87vna

beq87vna7#

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

rqqzpn5f

rqqzpn5f8#

在您的特定情况下,printf会删除零。编译器将去掉所有前导零,除了初始零,初始零会导致编译器将整数视为八进制。对于005,八进制和十进制表示是相同的,不应该打扰你,但仍然,它是自找麻烦,除非你特别意味着八进制表示。
前导零只与整数的字符串表示有关。若要使用前导零打印,请使用“%03d”。这将确保字段长度为3。
一般来说,“% d”将打印一个x个字符宽的整数,并使用前导空格填充。“%0 d”将执行相同的操作,但将填充前导零。

pu3pd22g

pu3pd22g9#

后台

以“0”开头的数字是以8为基数的,因此称为八进制数,使用数字0-7。正如以“0x”开头的数字是以16为基数的十六进制数字,使用数字0-9和A-F(不区分大小写,a-f)。
由于每个八进制数字代表3位,所以027(9位)可能用于代表8位,即一个字节。它的十进制值= 0.8² + 2.8 + 7.8° = 23。
027 == 23 == 0x17
最后但并非最不重要的是028会给给予一个编译错误:不是一个有效的数字。
如今十六进制数是无处不在的,因为他们适合一个字节正好2十六进制数字。
然而,在旧的Unix时代,硬件也有其他8位的字。还要注意的是,在Unix/Linux中,usergroupothers 的文件权限形成了一个r/w/x的三元组,所以老版本的0777(所有权限)仍然在使用。

相关问题