17

我理解双感叹号的作用(或者我认为我理解),但我不确定它是如何在随机对象上定义的。例如在下面的代码片段中:

Assignment *a;
if (!getAssignment(query, a))
   return false;
hasSolution = !!a;

if (!a)
   return true;

我怎么知道双感叹号会产生什么值?换句话说,它总是转换为 true 吗?错误的 ?或者你可以为它定义一个行为,比如执行一个方法来确定结果(对象如何知道在这种情况下如何行动)?由于所有这些感叹号的事情,我对这段代码有点困惑。任何解释都值得赞赏。

希望我很清楚,谢谢。

4

7 回答 7

22

a是一个指针。在 C++ 中,nullptr被定义为无效指针。!pointernullptr指针变为true,将非nullptr指针变为false. !boolean变成和。true_ _ 它会一直有效。falsefalsetrue

!(!a)是一种有用的思考方式。

于 2012-07-07T12:03:31.817 回答
11

不要将其视为“双感叹号”,将其视为两个独立的运算符,一个运行在另一个的结果上。

对于所有原始类型,它将“工作”。 !a等价于a == 0, so!!a等价于!(a == 0), 而后者又等价于a != 0.

对于用户定义的类型,除非它们重载,否则它不会编译operator !。但显然,在这种情况下,行为几乎可以是任何东西。

于 2012-07-07T12:05:35.887 回答
5

!!不是 C++ 中的单个标记,而是简单地解析为应用!运算符两次。

由于a是指针而不是类类型的对象,!因此不能重载。它被定义为true如果a是空指针则返回,false否则返回。

第二个应用!简单地否定第一个的结果!

表达式!!a等价于a != 0

于 2012-07-07T12:10:58.880 回答
3

代码非常复杂。实际上,您想测试getAssigment方法是否成功以及分配的指针是否为非空。

代码测试,尽管以一种复杂的方式,利用弱类型,而不是试图接受显式性和 C++ 的强类型。因此,它不是惯用的 C++,而且比必要的更难理解。

特别是,不要!!a在 C++ 中使用。在 JavaScript 等弱类型语言中,这是一个既定的习惯用法,用于将值强制转换为布尔类型。但在 C++ 中,这并不常用。

hasSolution由于未定义或使用代码,因此尚不清楚代码的作用。但是,我怀疑代码应该等同于以下内容:

Assignment *a;
return getAssignment(query, a) and a == nullptr;

(在 C++11 之前,您需要编写0而不是nullptr.)

但是,这段代码仍然暴露了一个糟糕的设计:为什么是a通过引用传递的?为什么不是返回值?更糟糕的a是,从来没有使用过,所以没有必要。如果a确实没有必要,则应完全省略。如果有必要,它应该是返回值。也就是说,原型getAssignment应该是这样的:

Assignment* getAssignment(the_type_of_query query);

它应该简单地使用如下:

Assignment* a = getAssignment(query);

此外,我怀疑这段代码实际上将内存所有权分配给了原始指针a。在现代 C++中强烈建议不要这样做。要么不使用指针,要么使用智能指针。

于 2012-07-07T13:00:34.290 回答
0
bool result = true; 
result = !!result; // result = true, e.g. !result is false, !!result is !false.
于 2012-07-07T12:02:50.270 回答
0

没有“!!” 运算符,所以实际上该语句等价于:

hasSolution = !(!a);

因此,首先,在表达式“a”上调用 operator!(),然后在结果上调用另一个 operator!()。在我们的代码中,“a”是一个指向赋值的指针。C++ 定义了在指针类型上使用 operator!() 的特殊情况:它返回一个布尔值,如果指针为空则为真,否则为假。简而言之,与表达式相同(a == 0)。对 (!a) 的结果调用 operator!(),它是一个布尔值,只是简单地恢复结果,即如果 (!a) 为假则返回真,如果 (!a) 为真则返回假。

所以总而言之,(!!a) 返回与 (a != 0) 相同的结果。这是因为“a”是一个指针。

于 2012-07-07T12:25:20.593 回答
0

记住双重否定 !!a 的最简单方法是将 a!=0 缩小到 1 并将 a==0 缩小到 0。这是在布尔上下文(即 C++)中是真还是假。

于 2012-07-07T18:58:12.710 回答