为啥返回变量的值会改变?

Posted

技术标签:

【中文标题】为啥返回变量的值会改变?【英文标题】: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,名称,但是我不知道:-)。然而。有两个优点:第一个我认为不太相关,第二个不在讨论范围内:不常见的光学信号需要谨慎。第二:我的客户的一些工程师想要这样(而且它仍然比替代方案更具可读性)。我会考虑第一种情况;我不确定每个现代编译器是否都会发出警告。你确定主要的嵌入式编译器吗?)。 【参考方案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

【讨论】:

以上是关于为啥返回变量的值会改变?的主要内容,如果未能解决你的问题,请参考以下文章

为啥python脚本返回的值会被shell修改?

为啥我的数组值会发生变化? [复制]

ajax获取java后台的返回值,long的值为啥会四舍五入解决办法

使用 Perl/Moose,修饰符返回的值会发生啥变化?

python调用mysql中的自定义变量,为啥返回的值都是None

4.6 异常处理