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

时间:2017-03-29 10:41:27

标签: c++ c pointers syntax

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”究竟是什么意思? 有人可以向我解释一下,或者帮我给自己一个正确的条款来搜索解释吗?

7 个答案:

答案 0 :(得分:5)

这个表达式有两个部分:

  • c = *str - 这是解除引用指针的c的简单分配,
  • val != 0 - 这是与零的比较。

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

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

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

从语法角度来看,第二对括号是可选的,但它保存在类似的赋值中,以指示赋值是有意的。换句话说,它告诉读者您的代码,您真正打算编写一个赋值c = *str,而不是一个比较c == *str,这是一个更常见的内部循环控制块。第二对括号也会抑制编译器警告。

答案 1 :(得分:2)

混淆,

<ListView x:Name="test" ItemsSource="{Binding UserProfileData}"> <ListView.Resources> <Style TargetType="GridViewColumnHeader"> <Setter Property="Command" Value="{Binding YourCommandProperty}" /> <Setter Property="CommandParameter" Value="{Binding Content, RelativeSource={RelativeSource Self}}" /> </Style> </ListView.Resources> <ListView.View> <GridView> <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="User ID"/> <GridViewColumn DisplayMemberBinding="{Binding LastUsed}" Header="Last Loaded"/> <GridViewColumn DisplayMemberBinding="{Binding IsLoaded}" Header="Logged In"/> </GridView> </ListView.View> </ListView>

是一个相当容易阅读的重言式

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

这也可以将while (c = *str) {处的字符分配给*str,并且c *str后循环将终止;即当到达字符串的末尾时。

如上所述的条件中的赋值乍一看可能会令人困惑,(参见非常不同的\0的行为),但它们是C和C ++中非常有用的部分,需要使用他们。

答案 2 :(得分:1)

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

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

分配equiv后,这就是字符串的结尾。该函数必须停止从内存中读取它。

答案 3 :(得分:1)

循环遍历字符串str中的每个字符,将它们分配给c,然后查看c是否等于0,这表示字符串的结尾。

虽然代码应该使用'\0',因为这显然是一个NUL字符。

答案 4 :(得分:0)

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

这是&#39;对于&#39;循环等价物:

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

答案 5 :(得分:0)

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

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

if(c != '\0')

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

另一个错误是在条件内使用赋值。这在20世纪80年代被认为是不好的做法,从那时起,每个编译器都会对这些代码发出警告,并且可能会错误地分配&#34;或类似的。这是不好的做法,因为赋值包含副作用,副作用表达式应尽可能简单。但这也是不好的做法,因为很容易混淆===

代码很容易被重写为更可读和安全的东西:

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

答案 6 :(得分:0)

由于您已经拥有指针char c,因此您不需要char *str,您也可以将!= 0替换为!= '\0'以获得更好的可读性(如果不兼容)

while (*str != '\0')
{  
    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
}