返回后复合语句改变值?

时间:2014-02-25 14:52:07

标签: c return

我想知道在返回值后是否可以更改变量?

有问题的函数是一个私有布尔标志变量的简单get函数。我想读这个标志是破坏性的,所以我想:

bool myGet (context_t * someContext) {
    return (someContext->flag) ? (someContext->flag = false) : false;
}

推断评估语句(someContext->flag = false)的结果是true,但似乎没有。

可能在条件(someContext->flag)?之前评估了

是否有其他方法可以实现预期的功能而无需暂时存储标志值,清除标志然后返回临时副本?感谢。

4 个答案:

答案 0 :(得分:5)

return的所有参数必须在评估return之前进行评估,即在执行离开当前函数之前。

作业的价值是指定的值,所以你经历的是false

我认为你最接近的是后增量,但这当然会严格限制可用值。

以明确的方式做没有错

bool getAndClear(context_t *someContext)
{
  if(someContext->flag)
  {
    someContext->flag = false;
    return true;
  }
  return false;
}

它非常清晰,方式比您可怕的代码更容易理解。很容易想象编译器可以优化它,因为它很简单。

如果我想变得聪明,我可能会使用类似的东西:

bool getAndClear2(context_t *someContext)
{
  const bool flag = someContext->flag;

  someContext->flag ^= flag; /* Clears if set, leaves alone if not set. */

  return flag;
}

请注意,它不是分支,有时是漂亮的。但是,再一次,聪明并不总是最令人敬畏的道路。

另请注意,我认为要求此函数不仅仅是命名为“get”,因为它不需要const指针作为我头脑中的即时警告标志。因为它具有超级奇怪(对于吸气剂)的副作用,所以应该以某种方式反映在名称中。

答案 1 :(得分:2)

  

推测评估语句(someContext->flag = false)的结果是正确的,但似乎没有。

(someContext->flag = false)是一个赋值表达式。它的值是被赋值的表达式的值(即false)。

分配确实经过,虽然它发生在返回之前,而不是之后。如果你想要使用三元运算符,你可以使用逗号运算符,如下所示:

return (someContext->flag) ? (someContext->flag = false, true) : false;

这不是很易读,所以我更喜欢这个没有条件的等效实现:

bool temp = someContext->flag;
someContext->flag = false;
return temp;

答案 2 :(得分:2)

当您执行(someContext->flag = false)时,它会将someContext->flag设置为false,然后将其返回。

你可以这样做:

return (someContext->flag) ? !(someContext->flag = false) : false;

通过这种方式,您将返回您刚刚设置为false的someContext->flag的对位(因此您返回true),但someContext->flag将在返回后保持为假

修改

最难以理解的是:

return !(someContext->flag = !someContext->flag);

答案 3 :(得分:0)

您可以使用后减量运算符:

return (someContext->flag) ? someContext->flag-- : false;

如果您的标记的true值的数值为1,则只会产生预期的结果。