我想知道在返回值后是否可以更改变量?
有问题的函数是一个私有布尔标志变量的简单get函数。我想读这个标志是破坏性的,所以我想:
bool myGet (context_t * someContext) {
return (someContext->flag) ? (someContext->flag = false) : false;
}
推断评估语句(someContext->flag = false)
的结果是true
,但似乎没有。
可能在条件(someContext->flag)?
之前评估了。
是否有其他方法可以实现预期的功能而无需暂时存储标志值,清除标志然后返回临时副本?感谢。
答案 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
,则只会产生预期的结果。