K&R 2 第 5.10 节中的说明
Clarification in Section 5.10 of K&R 2
如果输入是查找模式,模式识别程序必须打印包含该模式的所有行。如果输入是 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 的代码中,except 可以是 1 或 0。if(strstr...)
块函数如何有效地处理 -x?
我不熟悉该代码,但是此语句将评估为布尔值(0
或 1
),因为 strstr()
将 return 指向单词的指针正在搜索或 NULL
如果未找到:
strstr(line, *argv) != NULL
所以我猜 except
设置为 0
或 1
以影响 "was not found" 或 "was found" 条件。
如果-x
没有通过那么except
就是0
:
if ((strstr(line, *argv) != NULL) != 0)
这意味着如果找到该词,请输入 if
子句。
如果-x
通过则except
是1
:
if ((strstr(line, *argv) != NULL) != 1)
这意味着如果找到该词,请不要输入 if
子句。
这是令人困惑的代码,所以我建议将其分解为:
const char *word = strstr(line,*argv);
int wasfound = word != NULL;
if (wasfound != except)
{
}
然后使用调试器单步执行。学习使用调试器也很重要。
逻辑很简单。如果模式是 "-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 语句中的条件计算结果为真,我们需要条件 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 语句中两个子表达式的求值结果。
!=
运算符与异或运算的真值相同所以可以分解
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
反转在字符串中找到模式时发生的效果。
如果输入是查找模式,模式识别程序必须打印包含该模式的所有行。如果输入是 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 的代码中,except 可以是 1 或 0。if(strstr...)
块函数如何有效地处理 -x?
我不熟悉该代码,但是此语句将评估为布尔值(0
或 1
),因为 strstr()
将 return 指向单词的指针正在搜索或 NULL
如果未找到:
strstr(line, *argv) != NULL
所以我猜 except
设置为 0
或 1
以影响 "was not found" 或 "was found" 条件。
如果-x
没有通过那么except
就是0
:
if ((strstr(line, *argv) != NULL) != 0)
这意味着如果找到该词,请输入 if
子句。
如果-x
通过则except
是1
:
if ((strstr(line, *argv) != NULL) != 1)
这意味着如果找到该词,请不要输入 if
子句。
这是令人困惑的代码,所以我建议将其分解为:
const char *word = strstr(line,*argv);
int wasfound = word != NULL;
if (wasfound != except)
{
}
然后使用调试器单步执行。学习使用调试器也很重要。
逻辑很简单。如果模式是 "-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 语句中的条件计算结果为真,我们需要条件 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 语句中两个子表达式的求值结果。
!=
运算符与异或运算的真值相同所以可以分解
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
反转在字符串中找到模式时发生的效果。