为啥返回变量的值会改变?
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 > 0)... n=func();
没有理想的方法来处理这样的循环,你会被一种或另一种不好的做法卡住。
@Olaf 我会不建议交换操作数的顺序(“尤达条件”)。这是 80 年代的一些晦涩实践,在 1990 年 Turbo C 出现革命性警告“可能不正确的赋值”之前。从那时起,每个半体面的编译器都会警告不要在条件内进行赋值,因此没有必要混淆代码。 while(0 < (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)
因为=
的优先级低于>
,所以n
得到比较的结果,这将是0
或1
。您需要明确地对作业进行分组:
(n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0
就像它在 Rio_readlineb_w
函数中的完成方式一样。
赋值的优先级低于大多数其他运算符,因此在较大的表达式中使用赋值表达式时要小心。例如,
a = b && c;
将b && c
的结果分配给a
。如果要将b
的结果分配给a
并将其与c
进行比较,则需要使用括号来表示:
(a = b) && c
【讨论】:
以上是关于为啥返回变量的值会改变?的主要内容,如果未能解决你的问题,请参考以下文章
ajax获取java后台的返回值,long的值为啥会四舍五入解决办法