2014-02-25 53 views
2

我想知道是否有可能有一个变量后,返回其值?复合语句返回后更改值?

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

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

推理评估声明(someContext->flag = false)的结果将是true,但它似乎没有。

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

是否有任何其他方式来实现预期的功能,而不诉诸临时存储标志值,清除标志,然后返回临时副本?谢谢。

回答

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; 
} 

需要注意的是它没有分支,有时俏皮。但是,再次,聪明并不总是最好的选择。

另外请注意,我认为这是一个要求,此功能不只是命名为“获取”的东西,因为它不需要const指针,这将是我脑海中的即时警告标志。由于它具有超奇怪(对于吸气剂)的副作用,因此应以某种方式反映在名称中。

+0

我喜欢这个不需要临时变量,并具有相同数量的分支 – Toby

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; 
0

可以使用递减后的运营商:

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

这只会有希望的结果,如果你的标志true值有n个数值为1

2

当你做(someContext->flag = false)它将someContext->flag设置为false,然后返回它。

你可以这样做:

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

这样,您将回到您刚才设置的someContext->flag的oposite假的(所以你返回true),但回报

编辑后someContext->flag会留下假

最不可读的是:

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

我喜欢这种方法,简短又甜美:) 但是缺少一些可读性,所以我可能不得不放弃一些回答 – Toby

+1

你刚刚习惯了它,但我承认。它甚至可能是最糟糕的! (见编辑) – EoiFirst