c-返回值后要更改值的复合语句

  • 本文关键字:复合语句 返回值 c return
  • 更新时间 :
  • 英文 :


我想知道是否有可能在返回变量值后对其进行更改?

有问题的函数是一个私有布尔标志变量的简单get函数。我希望对这面旗帜的解读具有破坏性,所以我想:

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

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

也许它在条件(someContext->flag)?之前被评估

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

在对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指针,这将是我脑海中的一个即时警告标志。由于它有非常奇怪的(对于getter)副作用,这应该以某种方式反映在名称中。

推断语句(someContext->flag = false)的求值结果为真,但似乎不是。

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

赋值确实通过了,尽管它发生在返回之前,而不是之后。如果你想保持幻想并使用三元运算符,你可以使用逗号运算符,比如:

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

不过,这不是很可读,所以我更喜欢这种等效的实现,它没有条件:

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

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

你可以做:

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

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

编辑

最不可读的是:

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

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

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

只有当您的标志的true值为数值1时,才会得到所需的结果。

最新更新