【问题标题】:why does the value of the return variable change?为什么返回变量的值会改变?
【发布时间】:2015-06-23 14:01:44
【问题描述】:

我正在开发一个 linux 代理程序,但我遇到了这个问题。这是我正在努力解决的代码。

while(n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0){
  printf("%d\n", n);
  Rio_writen_w(serverfd, buf, n);
}

这是'Rio_readlineb_w'的包装函数

ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen)
{
  ssize_t rc;
  if((rc = rio_readlineb(rp, usrbuf, maxlen)) < 0 )
  printf("Rio_readlineb error");
  printf("%d\n", rc);
  return rc;
}

变量 'rc' 表示 rio_readlineb 函数读取的字符数。使用包装函数中的 printf,我检查了 rc 是否正是读取的字符数。但是,上面的while语句的变量'n'始终为1。我无法找出问题所在。你觉得返回值有什么变化吗?

【问题讨论】:

  • 避免在条件中使用赋值运算符,因为这样做是众所周知的导致许多错误的原因。很少有需要这样做的情况。
  • @Lundin:我发现它实际上比while ( true ) ... if () break; 更具可读性。但是,比较应该交换,所以赋值在比较运算符的右边,并且赋值应该用括号括起来。
  • @Olaf 或者,您可以在循环之外添加一个额外的调用,这也可以说有点奇怪。 n=func(); while(n &gt; 0){... n=func();} 没有理想的方法来处理这样的循环,你会被一种或另一种不好的做法卡住。
  • @Olaf 我会建议交换操作数的顺序(“尤达条件”)。这是 80 年代的一些晦涩实践,在 1990 年 Turbo C 出现革命性警告“可能不正确的赋值”之前。从那时起,每个半体面的编译器都会警告不要在条件内进行赋值,因此没有必要混淆代码。 while(0 &lt; (n = func()) 可能是重写代码的可读性最低的方式。
  • @Lundin:我同意可读性(而且我知道警告,至少通过 gcc,名称,但是我不知道:-)。然而。有两个优点:第一个我认为不太相关,第二个不在讨论范围内:不常见的光学信号需要谨慎。第二:我的客户的一些工程师想要这样(而且它仍然比替代方案更具可读性)。我会考虑第一种情况;我不确定每个现代编译器是否都会发出警告。你确定主要的嵌入式编译器吗?)。

标签: c return


【解决方案1】:

这是运算符优先级的问题。

while(n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0){

应该是:

while((n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0){

否则,您会将比较结果(0 或 1)分配给 n

【讨论】:

    【解决方案2】:
    while(n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0){
      printf("%d\n", n);
      Rio_writen_w(serverfd, buf, n);
    }
    

    等同于:

    while (n = /* assignment has low priority */
              (Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0)
           ) {
      printf("%d\n", n);
      Rio_writen_w(serverfd, buf, n);
    }
    

    我怀疑你想要:

    while ((n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0) {
      printf("%d\n", n);
      Rio_writen_w(serverfd, buf, n);
    }
    

    【讨论】:

      【解决方案3】:
      n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0
      

      被解析为

      n = (Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0)
      

      因为= 的优先级低于&gt;,所以n 得到比较的结果,这将是01。您需要明确地对作业进行分组:

      (n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0
      

      就像它在 Rio_readlineb_w 函数中的完成方式一样。

      赋值的优先级低于大多数其他运算符,因此在较大的表达式中使用赋值表达式时要小心。例如,

      a = b && c;
      

      b &amp;&amp; c 的结果分配给a。如果要将b 的结果分配给a 并将其与c 进行比较,则需要使用括号来表示:

      (a = b) && c
      

      【讨论】:

        猜你喜欢
        • 2013-04-08
        • 2016-06-20
        • 2011-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多