【问题标题】:Why use double parentheses in init methods, or is 1 == (1)?为什么在 init 方法中使用双括号,或者是 1 == (1)?
【发布时间】:2013-03-13 07:55:42
【问题描述】:

括号在评估某些含义时有什么作用? 当检查某些内容并且他们使用时,我在代码中遇到过这个问题

if ( (some condition that returns 1) )
{
code
}

所以我的问题是,这是否为真?我认为它总是错误的,因为 (1) 不返回任何东西?

编辑:澄清,问题是为什么在 if 中加上双括号?我知道 1 是真的。

【问题讨论】:

  • 为了可读性可能更多。
  • 在很多init方法中你看到...if ( (self = [super init]) ) {}我一直不明白两组括号的含义。
  • (1) 不是函数。它不会像1 那样“返回”任何东西。
  • @Fogmeister 正是,该代码让我问了这个问题
  • @Juhana 好的,所以 (((((1))))) == 1 ?

标签: objective-c c


【解决方案1】:

当赋值用于其真值时,使用附加括号。它们允许编译器区分

if ((var = expr))

表示有意结合了赋值和真值测试,并且

if (var = expr)

作为if (var == expr) 的无意拼写错误。

从 C 和 C++ 继承下来的约定是让编译器在 if (var = expr) 上发出警告,因为 if (var == expr) 可能拼写错误。他们不会在if ((var = expr)) 上发出警告,因为额外的一组括号向编译器发出了赋值的信号。正如 rob mayoff 解释的那样,clang 有一个特殊情况,即不会对 self 的某些分配发出警告,但对于许多编码人员来说,这种习惯仍然存在。

正如其他人所说,无论有没有额外的括号,生成的代码都是完全相同的。

【讨论】:

  • 正是我想要的,谢谢,我听说编译器在这种情况下会发出警告,忘记了。
  • 如果您说if (self = [super init]),您将不会在默认构建设置下收到警告,因为 clang 明确识别这种情况并默认抑制警告。见Sema::DiagnoseAssignmentAsCondition in the clang source code。有些人在clang有特殊情况之前就养成了这个习惯(我猜),但是在初始化期间重新分配self时不再需要了。
  • @robmayoff 我已经修改了答案以包含此信息,谢谢。
【解决方案2】:

如果你写,

if (self = [super init]) { // Warning
    // ...
}

编译器会给你一个警告,因为它认为你可能将= 错误输入为==。如果添加第二组括号,警告就会消失。

if ((self = [super init])) { // No warning
    // ...
}

所以额外的括号是为了减少拼写错误的可能性。括号不会改变表达式的值。

【讨论】:

  • 与任何警告一样,此警告绝不是任何编译器都必须给出的。从函数式编译器的角度来看,添加额外的括号确实没有任何意义。我想说,任何在出现附加括号时删除警告的编译器都有缺陷或损坏。
  • @Lundin:感谢您对这个话题的夸夸其谈。让更多人就 GCC 和 Clang 是如何“崩溃”发表意见总是有帮助的,而无需解释原因。
  • 我刚刚解释了原因。你不明白我评论的哪一部分?还是您真的希望编译器根据程序员在特定表达式中编写的子表达式的数量来更改其内部警告级别?
  • @Lundin:这听起来像是实施此警告的糟糕方式。作为我自己的编译器编写者,我将对每个谓词进行检查,而不是递归到子表达式中:您将获得所需的行为而无需修改内部状态。编译器发出的每个警告都需要在误报和误报之间取得微妙的平衡,并受益于在本地禁用警告的小技巧,例如 (void) x; 如何抑制未使用的变量警告。或者您可以关闭警告,而不是在这里抱怨 GCC/Clang 是如何“有缺陷/损坏”的。它没有生产力。
  • “这听起来像是一种糟糕的方式来实现这个警告。”的确!然后我们同意。至于哪个编译器损坏与否,我没有指定一个,但请参考 OP 使用的任何编译器(一些 Objective C 编译器)。
【解决方案3】:

通常 0 等于 false,NOT 0 等于 true。

这个链接解释了objective-c中的bool:http://www.mindsizzlers.com/2010/04/objective-c-and-the-properties-of-bool/

【讨论】:

  • 谢谢,但问题主要是关于双括号的。
  • 对不起,我的错。括号用于指示执行操作的顺序,因此多个括号不应对评估的最终条件产生影响,即 (((((1))))) == 1
【解决方案4】:

boolint的真假值

  • 布尔值false 等价于int0
  • 布尔值true 等价于非零的int 值(例如1103000 等)

例如,考虑下面的 C 代码示例:

bool bValue;
int nValue;

bValue = true;
nValue = 1;

if (bValue == nValue) {
    printf("bValue and nValue are the same!\n");
}

// output: bValue and nValue are the same!

用多个括号括起来:

以下两个 sn-ps 返回完全相同相同的结果。

if ((((((((((((((((((((1)))))))))))))))))))) {
   printf("Hello World!\n");
}

返回与以下相同的结果:

if (1) {
   printf("Hello World!\n");
}

if 语句中的表达式

在您给定的if 语句中,您必须有一个表达式可以解析为真值或假值。表达式示例请参考this页面。

【讨论】:

  • 我知道,我的意思是(1)是什么意思?
  • 在这种情况下,括号是多余的。
  • 那么,为什么我会看到这么多带有双括号的init方法?
  • @Fogmeister 双括号用于提高可读性。我们在 init 方法中使用双括号来区分 assignments 和简单的 expressions。例如,if ((a = 5)) 的阅读效果比 if (a = 5) 好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-16
  • 2022-09-26
相关资源
最近更新 更多