0

这里我指的是来自“codechef.com”的一个问题。下面的代码用于从用户那里读取初始计数。这将返回一个整数值。

这类似于做一个scanf("%d", &n);. 但是大多数人都是使用这种方法从用户那里获取信息。

我不明白这段代码中的一行,我不明白字符输入在哪里转换为整数。

int readuint()
{
int n = 0;
char c = fgetc(stdin);
do {
n = n * 10 + (c - '0');
} while ((c = fgetc(stdin)) != '\n');
return n;
}

有问题的项目是这条线-n = n * 10 + (c - '0');这条线在做什么?

完整代码访问: http: //www.codechef.com/viewsolution/1221364

4

1 回答 1

4

如果输入是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 charto int:是不是因为我们分配给一个整数容器——即int n

正如Elchonon Edelson所说,字符常量'0'和 ' 1' 是 C 中的整数常量(它们在 C++ 中是常量),并且和char的值通常分别是 48 和 49(但 C 标准不保证! )。所以,当然给出。'0''1'49 - 481

于 2013-06-27T00:13:51.873 回答