当我的角色是'*'或'/'时,此循环不应该停止吗?

时间:2019-07-17 09:07:44

标签: c

Heloo,我一直在寻找K&R C编程手册中1-23的解决方案,但我并不完全理解incomment函数,该函数应删除所有输入,直到注释结束为止,因为我认为||运算符应该在遇到注释中的*或/后立即停止,但是该功能仍应按应有的方式工作,有人可以解释它的实际作用吗?

void incomment()
{
    int c,d;

    c = getchar();
    d = getchar();

    while(c!='*' || d !='/')
    {
        c =d;
        d = getchar();
    }
}

2 个答案:

答案 0 :(得分:3)

  

我认为它应在评论中遇到*或/后立即停止

否,它不会在第一个*或第一个/

处停止

假设c 不是 *。然后看一下逻辑表达式:

while(c!='*' || d !='/')
      ^^^^^^
       TRUE as we assumed that c is not a *

当逻辑表达式的第一部分为TRUE且运算符为||时,整个表达式将为TRUE,而与逻辑表达式的第二部分无关。

因此,我们由此了解到:当c 不等于*时,循环将继续。

因此,现在假设d不是不是 /

while(c!='*' || d !='/')
                ^^^^^^
                TRUE as we assumed that d is not a /

同样,由于逻辑OR表达式的一部分(即第二部分)为TRUE,整个表达式将为TRUE,并且循环将继续进行。

现在我们只错过c*d/的情况

while(c!='*' || d !='/')
      ^^^^^^    ^^^^^^
       FALSE     FALSE as we assumed that d is a /
         |
         as we assumed that c is a *

因此,在这种情况下,循环将停止,因为FALSE || FALSE会产生FALSE

我们可以将其写为表格:

     c     |     d     | Logical expression
-------------------------------------------
   != '*'  | any value |     TRUE
-------------------------------------------
 any value |   != '/'  |     TRUE
-------------------------------------------
   == '*'  |   == '/'  |     FALSE

换句话说-仅当c的值为* 并且 d的值为/ <时,循环才会停止/ p>

循环的主体向我们显示c始终获得d在上一个循环中具有的值:

{
    c =d;            // c is assigned the value that d got in the previous loop
    d = getchar();   // d is assigned the next character of the input
}

因此cd共同构成了输入的2个字符的滑动窗口。

作为示例,请考虑读取测试字符串:“ a *是天生的* /”

text | c   | d   | comment
----------------------
 'a' | 'a' |     | initialization
 ' ' | 'a' | ' ' | initialization
 '*' | ' ' | '*' | loop
 ' ' | '*' | ' ' | loop
 'i' | ' ' | 'i' | loop
 's' | 'i' | 's' | loop
 ' ' | 's' | ' ' | loop
 'b' | ' ' | 'b' | loop
 'o' | 'b' | 'o' | loop
 'r' | 'o' | 'r' | loop
 'n' | 'r' | 'n' | loop
 '*' | 'n' | '*' | loop
 '/' | '*' | '/' | loop (last loop because now c is * AND d is /

换句话说-仅当文本字符串包含序列*/时,循环才会停止,该序列确实是注释结束序列。

答案 1 :(得分:1)

  

此功能应删除所有输入,直到其到达注释末尾为止

对比

  

我认为它应该在遇到

中的*或/后立即停止

如果评论确实终止,或者只是随机*或/,则后者需要稍后进行检查。

如前所述,如果遇到注释结尾,它将停止。 如果注释符合* / c == '*' && d == '/',则注释结束。 另一方面,这意味着循环将继续读取,直到!(c == '*' && d == '/')等效于c != '*' || d != '/'