'(c = *str) != 0' 是什么意思?

What does `(c = *str) != 0` mean?

本文关键字:是什么 意思 str      更新时间:2023-10-16
int equiv (char, char);
int nmatches(char *str, char comp) {
char c;
int n=0;
while ((c = *str) != 0) {  
if (equiv(c,comp) != 0) n++;
str++;
}
return (n);    
}

"(c = *str) != 0"到底是什么意思? 有人可以向我解释一下或帮助我提供正确的术语以自己搜索解释吗?

此表达式包含两部分:

  • c = *str- 这是取消引用指针的简单c赋值,
  • val != 0- 这是与零的比较。

这是有效的,因为赋值是一个表达式,即它有一个值。赋值的值与分配的值相同,在本例中为指针指向的char。所以基本上,你有一个循环,将一个以 null 结尾的字符串跟踪到末尾,将每个单独的char分配给c

请注意,!= 0部分在 C 中是多余的,因为while循环的控制表达式隐式地与零进行比较:

while ((c = *str)) {
...
}

从语法的角度来看,第二对括号是可选的,但它保留在这样的赋值中,以指示赋值是有意的。换句话说,它告诉代码的读者你真的想写一个赋值c = *str,而不是一个比较c == *str,这在循环控制块中更常见。第二对括号也会禁止显示编译器警告。

令人困惑的是,

while ((c = *str) != 0) {

是相当容易阅读的重言式

while (c = *str) {

这也具有将字符分配给c*str的作用,一旦*str,循环就会终止;即当到达字符串的末尾时。

像上面这样的条件中的赋值乍一看可能会令人困惑(参见非常不同的c == *str的行为),但它们是 C 和 C++ 中非常有用的一部分,您需要习惯它们。

>(c = *str)是一个表达式,它本身有一个值。它是一个赋值,赋值的值是赋值。所以(c = *str)的值就是*str的值。

代码基本上检查的是,刚刚分配给c*str的值是否0。如果不是,那么它将使用该值调用函数equiv

分配0后,这是字符串的结尾。该函数必须停止从内存中读取,它确实如此。

它循环访问字符串str中的每个字符,将它们分配给c,然后查看c是否等于 0,这将指示字符串的结束。

尽管实际上代码应该使用''因为这更明显地是一个 NUL 字符。

我们正在遍历 while 循环中的 str 并提取其中的每个字符符号,直到它等于零 - 字符字符串末尾的主要规则。

以下是"for"循环等效项:

for (int i = 0; i < strlen(str); ++i )
std::cout << str[i];

它只是草率编写的代码。目的是将字符串str中的字符复制到c中,然后检查它是否是 null 终止符。

在 C 中检查空终止符的惯用方法是显式检查''

if(c != '')

这就是所谓的自我记录代码,因为用 C 编写空终止符的实际标准方法是使用八进制转义序列


另一个错误是在条件中使用赋值。这在 1980 年代被认为是不好的做法,从那时起,每个编译器都会对此类代码、"可能不正确的赋值"或类似代码发出警告。这是不好的做法,因为赋值包含副作用,具有副作用的表达式应尽可能保持简单。但这也是不好的做法,因为它很容易混淆===


代码可以很容易地重写为更具可读性和安全性的内容:

c = *str;
while (c != '')
{
if(equiv(c, comp) != 0)
{
n++;
}
str++;
c = *str;
}

你不需要char c,因为你已经有了指针char *str,你也可以用!= ''替换!= 0以获得更好的可读性(如果不是兼容性)

while (*str != '')
{  
if (equiv((*str),comp)
!= 0)
{ n++; }
str++;   
}

要理解代码的作用,您可以像这样阅读

while ( <str> pointed-to value is-not <end_of_string> )
{
if (function <equiv> with parameters( <str> pointed-to value, <comp> )
returned non-zero integer value)
then { increment <n> by 1 }
increment pointer <str> by 1 x sizeof(char) so it points to next adjacent char
}