我在读c++老师的课堂笔记,他是这样写的:

使用缩进// OK 永远不要依赖运算符优先级-总是使用括号// OK 总是使用{}块-即使是单行//不可以,为什么?? Const对象在比较的左边// OK 对>= 0的变量使用unsigned,这是个不错的技巧 删除后将指针设置为NULL -双重删除保护//不错

第三种方法我不清楚:放一行进去能得到什么 A{…} ?

例如,下面这段奇怪的代码:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
    if (i % 2 == 0)
    {
        j++;
    }
}

将其替换为:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
    if (i % 2 == 0)
        j++;

使用第一个版本的好处是什么?


当前回答

因为当你有两个没有{}的语句时,很容易漏掉一个问题。让我们假设代码是这样的。

int error = 0;
enum hash_type hash = SHA256;
struct hash_value *hash_result = hash_allocate();

if ((err = prepare_hash(hash, &hash_result))) != 0)
    goto fail;
if ((err = hash_update(&hash_result, &client_random)) != 0)
    goto fail;
if ((err = hash_update(&hash_result, &server_random)) != 0)
    goto fail;
if ((err = hash_update(&hash_result, &exchange_params)) != 0)
    goto fail;
    goto fail;
if ((err = hash_finish(hash)) != 0)
    goto fail;

error = do_important_stuff_with(hash);

fail:
hash_free(hash);
return error;

看起来不错。它的问题很容易被忽略,特别是当包含代码的函数非常大的时候。问题是,失败是无条件的。您可以很容易地想象这是多么令人沮丧(让您问为什么上次hash_update总是失败,毕竟在hash_update函数中一切看起来都很好)。

然而,这并不意味着我支持在所有地方都添加{}(在我看来,到处都看到{}很烦人)。虽然这可能会导致问题,但在我自己的项目中却从来没有,因为我个人的编码风格禁止没有{}的条件,当它们不在同一行时(是的,我同意我的编码风格是非常规的,但我喜欢它,并且我在为其他项目贡献时使用项目的代码风格)。这使得下面的代码很好。

if (something) goto fail;

但下一个不是。

if (something)
    goto fail;

其他回答

有许多可能的方法来编写控制语句;它们的某些组合可能共存而不损害易读性,但其他组合将引起麻烦。的风格

if (condition)
  statement;

可以与其他一些编写控制语句的方法很好地共存,但与其他方法就不那么好了。如果多行受控语句被写成:

if (condition)
{
  statement;
  statement;
}

那么,从视觉上看,哪些if语句控制单行,哪些语句控制多行就很明显了。然而,多行If语句被写成:

if (condition) {
  statement;
  statement;
}

那么,如果构造不添加必要的大括号,那么试图扩展单个语句的可能性就会高得多。

如果代码库大量使用这种形式,那么下一行的单个语句if语句也可能有问题

if (condition) statement;

我个人的偏好是将语句放在自己的行上通常可以提高易读性,除非有许多if语句具有类似的控制块,例如。

if (x1 > xmax) x1 = xmax;
if (x1 < xmin) x1 = xmin;
if (x2 > xmax) x2 = xmax;
if (x2 < xmin) x2 = xmin;
etc.

在这种情况下,我通常会在这些if语句的前面和后面加上一个空行,以便在视觉上将它们与其他代码分开。在相同的缩进处使用一系列以if开头的语句将提供一个清晰的视觉指示,表明有不寻常的地方。

它通过清楚地定义循环和条件块的范围,使您的代码更具可读性。它还可以避免你意外出错。

在“总是使用牙套”的营地呆了10年之后,我最近开始不怎么使用牙套了。 主要是受到Bob叔叔关于如何编写干净代码的争论的启发,我现在相信不使用大括号编写代码更具有可读性。

if(guardClause)
      throw new SomeException(..)

Bob大叔认为,在if/for语句中编写多行代码是潜在的可读性问题。

e.g.

if(someCondition)
{
   doTechnicalThingX();
   doTechnicalThingY();
   doTechnicalThingZ();
}

应该被重构为

if(someCondition)
    doFunctionalThingA();

对我来说,不把大括号放在那里是有帮助的,因为我得到提醒,我在if块中写了太多代码。

正如其他人所提到的,我相信代码风格是团队决策。

我对这位讲师的能力表示怀疑。考虑到他 点:

OK Would anyone really write (or want to read) (b*b) - ((4*a)*c)? Some precedences are obvious (or should be), and the extra parentheses just add to confusion. (On the other hand, you _should_ use the parentheses in less obvious cases, even if you know that they're not needed.) Sort of. There are two wide spread conventions for formatting conditionals and loops: if ( cond ) { code; } and: if ( cond ) { code; } In the first, I'd agree with him. The opening { is not that visible, so it's best to assume it's always there. In the second, however, I (and most of the people I've worked with) have no problem with omitting the braces for a single statement. (Provided, of course, that the indentation is systematic and that you use this style consistently. (And a lot of very good programmers, writing very readable code, omit the braces even when formatting the first way.) NO. Things like if ( NULL == ptr ) are ugly enough to hinder readability. Write the comparisons intuitively. (Which in many cases results in the constant on the right.) His 4 is bad advice; anything which makes the code unnatural makes it less readable. NO. Anything but int is reserved for special cases. To experienced C and C++ programmers, the use of unsigned signals bit operators. C++ doesn't have a real cardinal type (or any other effective subrange type); unsigned doesn't work for numeric values, because of the promotion rules. Numerical values on which no arithmetic operations would make sense, like serial numbers, could presumably be unsigned. I'd argue against it, however, because it sends the wrong message: bitwise operations don't make sense either. The basic rule is that integral types are int, _unless_ there is a significant reason for using another type. NO. Doing this systematically is misleading, and doesn't actually protect against anything. In strict OO code, delete this; is often the most frequent case (and you can't set this to NULL), and otherwise, most delete are in destructors, so you can't access the pointer later anyway. And setting it to NULL doesn't do anything about any other pointers floating around. Setting the pointer systematically to NULL gives a false sense of security, and doesn't really buy you anything.

查看任何典型参考文献中的代码。Stroustrup违反 除了第一条,你给出的每一条规则。

我建议你换个讲师。一个真正知道什么的人 他说的是。

如果不使用{和},很容易意外地用注释更改控制流。例如:

if (condition)
  do_something();
else
  do_something_else();

must_always_do_this();

如果你用一行注释注释掉do_something_else(),你会得到这样的结果:

if (condition)
  do_something();
else
  //do_something_else();

must_always_do_this();

它会编译,但must_always_do_this()并不总是被调用。

我们在代码库中遇到了这个问题,有人在发布之前很快地禁用了一些功能。幸运的是,我们在代码审查中发现了它。