我想知道是否有可能在返回变量值后对其进行更改?
有问题的函数是一个私有布尔标志变量的简单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
时,才会得到所需的结果。