繁体   English   中英

需要帮助来理解C中表达评估的顺序

[英]Need help in understanding order of evaluation of expression in C

我很难理解下面的代码如何评估表达式。 我不明白代码在这里如何工作

while (isdigit(s[++i] = c = getch()))
        ;

以及为什么我们需要

s[1] = '\0';

完整代码

#include <ctype.h>
int getch(void); 
void ungetch(int);
/* getop: get next character or numeric operand */ 

int getop(char s[])
{    
    int i, c;

    while ((s[0] = c = getch()) == ' ' || c == '\t');
    s[1] = '\0';

    if (!isdigit(c) && c != '.')
        return c; /* not a number */ 

    i = 0;

    if (isdigit(c)) /* collect integer part */ 
        while (isdigit(s[++i] = c = getch()));

    if (c == '.') /* collect fraction part */        
        while (isdigit(s[++i] = c = getch()));

    s[i] = '\0';
    if (c != EOF)
        ungetch(c);

    return NUMBER;    
}

感谢您的任何帮助!

=正确关联,因此isdigit(s[++i] = c = getch())将被分组为
isdigit( s[++i] = (c = getch()) ) getch将读取一个char并将其分配给c ,然后将c分配给s[++i]

  1. 这就是所谓的链式分配,请参阅wiki 要了解它,您只需要知道C中的赋值就是有价值的! 因此,就像@hacks所提到的,您可以将其等同于从右到左的多个连续分配的单线。

2。

s[1] = '\0'; 

这是一个安全问题,也是一种常规的编码实践:在C语言中,始终用'\\ 0'填充字符串的结尾。由于输入参数s []应该是char数组,因此需要对其进行填充。

注意

s[1] will be overwritten if s[0] is a digit or '.',

在这种情况下,将执行第二个或第三个while循环。 和以前一样,您还需要在s [i]上加上'\\ 0';

整个功能都有一个设计缺陷,即无法防止缓冲区溢出。 它需要知道s所指向的缓冲区的大小,以避免这种情况。

无论如何, while (isdigit(s[++i] = c = getch())); 具有以下含义:

for (;;)
{
    ++i;
    c = getch();
    s[i] = c;

    if ( ! isdigit(s[i]) )
        break;
} 

使用c而不是只写s[++i] = getch()是有原因的。

在这里,我假设getch (不是标准函数)是指某个函数,该函数具有与getchar相同的返回规范,即它返回unsigned char值或EOF

int c; 需要,以便可以检测到EOF 如果我们没有c ,则无法在函数末尾执行if ( c != EOF )测试。 进行s[i] == EOF无效,因为它可能会误认为EOF的有效字符(或者EOF可能超出char的范围)。

但是,代码仍然存在错误。 isdigit函数需要相同类型的int值; 即在我的解压缩版本中,最终测试应为:

if ( !isdigit(c) )

我猜想代码编写者知道EOF的问题,但要么不了解isdigit ,要么假设他的代码只能在接受负字符的实现上运行。

编写得更紧凑,该行可以替换为:

i = 1;
// ...

while ( isdigit(c = getch()) )
    s[i++] = c;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM