[英]Need help in understanding order of evaluation of expression in C
I have troubles understanding how expression is evaluated in the below code. 我很难理解下面的代码如何评估表达式。 I do not understand how code works here
我不明白代码在这里如何工作
while (isdigit(s[++i] = c = getch()))
;
and why do we need 以及为什么我们需要
s[1] = '\0';
Full code 完整代码
#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;
}
Thank you for any help! 感谢您的任何帮助!
=
is right associative and therefore isdigit(s[++i] = c = getch())
will be grouped as =
正确关联,因此isdigit(s[++i] = c = getch())
将被分组为
isdigit( s[++i] = (c = getch()) )
. isdigit( s[++i] = (c = getch()) )
。 getch
will read and assign a char
to c
and then c
is assigned to s[++i]
. getch
将读取一个char
并将其分配给c
,然后将c
分配给s[++i]
。
2. 2。
s[1] = '\0';
This is a safety concern and a normal coding practice: you always pad the end of a string with '\\0' in C. Since the input argument s[] is supposed to be a char array, thus you need to pad it. 这是一个安全问题,也是一种常规的编码实践:在C语言中,始终用'\\ 0'填充字符串的结尾。由于输入参数s []应该是char数组,因此需要对其进行填充。
Note that 注意
s[1] will be overwritten if s[0] is a digit or '.',
in which case the 2nd or 3rd while loop will be executed. 在这种情况下,将执行第二个或第三个while循环。 As before, you also need to pad the s[i] with '\\0';
和以前一样,您还需要在s [i]上加上'\\ 0';
This whole function has a design flaw in that it is not possible to prevent a buffer overflow. 整个功能都有一个设计缺陷,即无法防止缓冲区溢出。 It needs to know the size of buffer that
s
is pointing to, to avoid that. 它需要知道
s
所指向的缓冲区的大小,以避免这种情况。
Anyway, while (isdigit(s[++i] = c = getch()));
无论如何,
while (isdigit(s[++i] = c = getch()));
has the same meaning as: 具有以下含义:
for (;;)
{
++i;
c = getch();
s[i] = c;
if ( ! isdigit(s[i]) )
break;
}
There is a reason that c
is used instead of just writing s[++i] = getch()
. 使用
c
而不是只写s[++i] = getch()
是有原因的。
Here I am assuming that getch
(not a standard function) refers to some function which has the same return specification as getchar
, ie it returns either unsigned char
value or EOF
. 在这里,我假设
getch
(不是标准函数)是指某个函数,该函数具有与getchar
相同的返回规范,即它返回unsigned char
值或EOF
。
The int c;
int c;
is needed so that EOF
can be detected. 需要,以便可以检测到
EOF
。 If we did not have c
then there is no way of performing the test if ( c != EOF )
at the end of the function. 如果我们没有
c
,则无法在函数末尾执行if ( c != EOF )
测试。 Doing s[i] == EOF
would not work because it might mistake a valid character for EOF
(or EOF
might be out of range of char
). 进行
s[i] == EOF
无效,因为它可能会误认为EOF
的有效字符(或者EOF
可能超出char
的范围)。
However the code still has a bug. 但是,代码仍然存在错误。 The
isdigit
function expects the same sort of int
value; isdigit
函数需要相同类型的int
值; ie in my unpacked version, the final test should be: 即在我的解压缩版本中,最终测试应为:
if ( !isdigit(c) )
I'd guess that the code author knew about the issue with EOF
but either didn't know about isdigit
, or assumed his code would only be run on an implementation of it that accepted negative chars. 我猜想代码编写者知道
EOF
的问题,但要么不了解isdigit
,要么假设他的代码只能在接受负字符的实现上运行。
Writing it more compactly, the line could be replaced with: 编写得更紧凑,该行可以替换为:
i = 1;
// ...
while ( isdigit(c = getch()) )
s[i++] = c;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.