如果输入是123
,那么在循环的每次迭代中,它都会计算:
n = 0 * 10 + ('1' - '0');
n = 1 * 10 + ('2' - '0');
n = 12 * 10 + ('3' - '0');
assert(n == 123);
数字的字符代码总是连续的,'1' - '0'
1 等也是如此。
它将数字的数字转换为数字。习惯成语;你会在 C 代码中看到很多。
显示的代码在各种方面都很草率:
int readuint()
{
int n = 0;
char c = fgetc(stdin);
do {
n = n * 10 + (c - '0');
} while ((c = fgetc(stdin)) != '\n');
return n;
}
该名称表示它正在读取一个无符号整数 ( uint
),但使用的类型是有符号int
。的类型c
应该是int
因为fgetc()
(and getc()
and getchar()
) 返回 anint
而不是 a char
。没有办法表明它遇到了 EOF。没有防止溢出的保护。输入中没有针对非数字的保护。修复所有这些需要相当多的代码,但代码的基本自我保护意味着它应该更像:
int readint(void)
{
int n = 0;
int c;
while ((c = fgetc(stdin) != EOF && isdigit(c))
n = n * 10 + (c - '0');
if (c != EOF && c != '\n')
ungetc(fp, c);
return n;
}
仍然没有针对溢出的保护,但它具有针对输入中的 EOF 和非数字的基本保护(留下换行符或 EOF 以外的字符,通过将其放回以进行下一次读取操作来重新处理)。
'1'-'0' (char) = (int)1
? 这种转换是如何发生的?From char
to int
:是不是因为我们分配给一个整数容器——即int n
?
正如Elchonon Edelson所说,字符常量'0'
和 ' 1
' 是 C 中的整数常量(它们在 C++ 中是常量),并且和char
的值通常分别是 48 和 49(但 C 标准不保证! )。所以,当然给出。'0'
'1'
49 - 48
1