[英]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]
。
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.