K&R 2第5.10节的澄清

Thu*_*nch 5 c kernighan-and-ritchie

如果输入是模式,则模式识别程序必须打印包含模式的所有行.如果输入是find -x pattern,则程序必须打印除包含pattern的行以外的所有行.

// .....
switch(c)
{
case 'x':
    except=1;
    break;
// ......
}

// ......
while(getline(line,MAXLINE)>0)
    {
    line_num++;
    if( (strstr(line,*argv)!=NULL) != except)
        {
        if(number)
            printf("%ld:",linenum);
        printf("%s",line);
        found++;
        }
    }
// ......
Run Code Online (Sandbox Code Playgroud)

在上面的代码来自K&R,除了可以是1或0. if(strstr...)块函数如何有效地处理-x?

Vla*_*cow 3

逻辑很简单。如果模式是,"-x"我们应该打印所有不包含该模式的行。

对于这个模式except等于1.

因此包含该模式的行满足条件

strstr(line,*argv)!=NULL
Run Code Online (Sandbox Code Playgroud)

也就是说,如果一行包含该模式,则此条件将始终等于 1。

因此,如果except等于 1 并且条件strstr(line,*argv)!=NULL等于 1,我们应该跳过该模式。

否则,如果条件strstr(line,*argv)!=NULL不等于 1,即未找到模式,则执行 if 语句

if( (strstr(line,*argv)!=NULL) != except)
Run Code Online (Sandbox Code Playgroud)

产生 true 并且执行其复合语句。

另一方面,ifexcept等于0then 为了使 if 语句中的条件计算为 true,我们需要条件strstr(line,*argv)!=NULL等于 1。

其实你可以重写if语句

if( (strstr(line,*argv)!=NULL) != except)
Run Code Online (Sandbox Code Playgroud)

以下方式

if( ( ( strstr(line,*argv) != NULL ) == 1 && except == 0 ) ||
    ( ( strstr(line,*argv) != NULL ) == 0 && except == 1 ) )
Run Code Online (Sandbox Code Playgroud)

简而言之,if 语句可以工作,如果

1 and 0
Run Code Online (Sandbox Code Playgroud)

或者

0 and 1
Run Code Online (Sandbox Code Playgroud)

如果其中之一

1 and 1
Run Code Online (Sandbox Code Playgroud)

或者

0 and 0
Run Code Online (Sandbox Code Playgroud)

那么 if 语句将不会被执行。

这里 1 和 0 是 if 语句中两个子表达式的计算结果。