K& R 2的第5.10节澄清

时间:2016-01-29 07:54:32

标签: 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++;
        }
    }
// ......

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

3 个答案:

答案 0 :(得分:3)

我不熟悉代码,但是此语句将评估为布尔值(01),因为strstr()将返回指向要搜索的单词的指针或{{ 1}}如果没有找到:

NULL

所以我猜strstr(line, *argv) != NULL 设置为except0以影响"未找到"或"被发现"条件。

如果未通过1,则-xexcept

0

表示如果找到该单词,请输入if ((strstr(line, *argv) != NULL) != 0) 子句。

如果if通过,则-xexcept

1

表示如果找到该单词,则不要输入if ((strstr(line, *argv) != NULL) != 1) 条款。

令人困惑的代码,所以我建议将其分解为:

if

然后单步调试。学习使用调试器也很重要。

答案 1 :(得分:3)

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

对于此模式,except等于1

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

strstr(line,*argv)!=NULL

如果一行包含模式,则此条件将始终等于1.

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

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

if( (strstr(line,*argv)!=NULL) != except)

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

另一方面,如果except等于0,那么为了实现if语句中的条件将评估为true,我们需要条件strstr(line,*argv)!=NULL等于1

实际上你可以重写if语句

if( (strstr(line,*argv)!=NULL) != except)

以下方式

if( ( ( strstr(line,*argv) != NULL ) == 1 && except == 0 ) ||
    ( ( strstr(line,*argv) != NULL ) == 0 && except == 1 ) )

简而言之,如果

,则if语句可以正常工作
1 and 0

0 and 1

如果

1 and 1

0 and 0

然后不会执行if语句。

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

答案 2 :(得分:0)

!=运算符与XOR运算具有相同的真值。所以你可以分手

if( (strstr(line,*argv)!=NULL) != except)
    {
    if(number)
        printf("%ld:",linenum);
    printf("%s",line);
    found++;
    }
进入(效率低但可能更清晰)

char found_one_match;
if( strstr(line,*argv) != NULL )
{
    found_one_match = 1;
}
else
{
    found_one_match = 0;
}
found_one_match ^= except;
if (found_one_match)
{
    if(number)
        printf("%ld:",linenum);
    printf("%s",line);
}
found += found_one_match;

换句话说,except反转了在字符串中找到模式时发生的情况的影响。