C K&;获取int的R代码

C K&;获取int的R代码,c,C,我很难理解在K&R中获取int的代码。 特别是此函数的最后一行: void getint( int *pn ) { int c; while (isspace(c = getch())) ; for (*pn = 0; isdigit(c); c = getch()) *pn = 10 * *pn + (c - '0') ; } 下面是这里发生的事情: 由于pn是指向指针传递的结果的指针,分配或读取*pn意味着访问到目前为止的结果。您

我很难理解在K&R中获取int的代码。 特别是此函数的最后一行:

void getint( int *pn )
{
    int c;
    while (isspace(c = getch()))
        ;

    for (*pn = 0; isdigit(c); c = getch())
        *pn = 10 * *pn + (c - '0') ;
}

下面是这里发生的事情:

  • 由于
    pn
    是指向指针传递的结果的指针,分配或读取
    *pn
    意味着访问到目前为止的结果。您在此函数中所做的任何更改都可以在调用方的上下文中访问,调用方向您传递了指向
    int
    的指针
  • 由于十进制数字的代码彼此相邻,
    c-'0'
    表示代表数字的字符代码的数值。例如,如果
    c
    '5'
    (单引号),则
    c-'0'
    等于
    5
    (无引号)
现在算法的其余部分变得清晰了:在数字的右边附加一个数字意味着取该数字的先前值,乘以10,然后将该数字的值添加到结果中


例如,如果您正在阅读
“12345”
,并且已阅读
“123”
,则
*pn
123
,下一位数字为
4
。将
123
乘以
10
,得到
1230
,然后将
4
相加。现在您有了
1234
,下一个数字是
5
。你再乘以10得到
12340
,再加上
5
,得到
12345
的最终结果。我很确定这是一个代码,通过逐字符读取数字,可以更快地输入整数。所以这类似于

 void input_int(int *pn)
 {
    for ( *pn = 0; isdigit(c); c =getch())
    *pn = 10 * *pn + ( c - '0') ;
 }
用作

 int a;
 input_int(&a);

我们一个字符一个字符地读取数字,同时创建一个整数。

代码1)将数字存储在内存地址
pn
指向,2)使用0初始化结果,3)只要输入数字,就从控制台读取输入,4)将输入的字符转换为数字,5)通过将当前值乘以10并添加最后输入的数字来更新目标数字。@itharob我只关心其中一个代码。我怎样才能正确地格式化这个question@Olafgetch()是一个通过缓冲区获取字符的函数。其内容见第4节。3@MilesGaitan:我非常了解这本书(这就是我为什么不使用它的原因:它只涵盖了一个27年前过时的C版本,它不是标准的,并且包含了一些现在有问题的编码风格)。(旁注:如果您需要在注释中发布代码,请使用标记)。仍然没有理由使用它来代替
getchar
fgetc
。该函数不返回值:这将生成编译器警告。它应该是输入值还是状态?非常感谢。我不知道为什么它会乘以10,但现在它有了意义。@MilesGaitan不客气!当没有溢出时,乘以数字系统的基数相当于左移1。它在十进制中的工作方式与在二进制中的工作方式相同(
为什么您会因为两个
*
运算符而感到困惑?其中一个用作乘法运算符,另一个只是取消指针的引用,我喜欢它
10*(*pn)@ MilesGaitan:如果这解决了你的问题,请考虑通过点击旁边的灰色复选标记来接受答案。这会告诉其他网站访问者,你不再积极地寻求这个问题的帮助,并在堆栈溢出上为你赢得一个全新的徽章。“当然,Michi Ah!这就是当你尝试回答问题时会发生的事情。关于C语言、Swift语言、Java语言、C#语言和一系列其他语言的混合:保持对“方法”、“函数”、“成员变量”、“属性”、“属性”等的心理跟踪成为一个小挑战。是的,函数是getint(int*pn)。函数中还有用于错误处理和跳过空白的代码。